tiny-essentials 1.28.19 → 1.29.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/changelog/1/28/19.md +24 -0
- package/changelog/1/29/0.md +58 -0
- package/dist/v1/ColorSafeStringify.min.js +1 -1
- package/dist/v1/TinyAdvancedRaffle.min.js +1 -1
- package/dist/v1/TinyAfterScrollWatcher.min.js +1 -1
- package/dist/v1/TinyAnalogClock.min.js +1 -1
- package/dist/v1/TinyArrayComparator.min.js +1 -1
- package/dist/v1/TinyArrayPaginator.min.js +1 -1
- package/dist/v1/TinyBasicsEs.min.js +1 -1
- package/dist/v1/TinyBrowserMonitor.min.js +1 -0
- package/dist/v1/TinyClassManager.min.js +1 -1
- package/dist/v1/TinyClipboard.min.js +1 -1
- package/dist/v1/TinyCloner.min.js +1 -0
- package/dist/v1/TinyColorConverter.min.js +1 -1
- package/dist/v1/TinyColorValidator.min.js +1 -1
- package/dist/v1/TinyCookieConsent.min.js +1 -1
- package/dist/v1/TinyDayNightCycle.min.js +1 -1
- package/dist/v1/TinyDebugger.min.js +1 -1
- package/dist/v1/TinyDomReadyManager.min.js +1 -1
- package/dist/v1/TinyDragDropDetector.min.js +1 -1
- package/dist/v1/TinyDragger.min.js +1 -1
- package/dist/v1/TinyElementObserver.min.js +1 -1
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyGamepad.min.js +1 -1
- package/dist/v1/TinyHtml.min.js +1 -1
- package/dist/v1/TinyHtmlTagRegexBuilder.min.js +1 -0
- package/dist/v1/TinyHttpResponseRegistry.min.js +1 -0
- package/dist/v1/TinyI18.min.js +1 -1
- package/dist/v1/TinyIframeEvents.min.js +1 -1
- package/dist/v1/TinyInventory.min.js +1 -1
- package/dist/v1/TinyInventoryTrader.min.js +1 -1
- package/dist/v1/TinyLevelUp.min.js +1 -1
- package/dist/v1/TinyLoadingScreen.min.js +1 -1
- package/dist/v1/TinyLocalStorage.min.js +1 -1
- package/dist/v1/TinyMaInSys.min.js +1 -1
- package/dist/v1/TinyMapCache.min.js +1 -0
- package/dist/v1/TinyMediaPlayer.min.js +1 -1
- package/dist/v1/TinyNeedBar.min.js +1 -1
- package/dist/v1/TinyNewWinEvents.min.js +1 -1
- package/dist/v1/TinyNotificationAdapter.min.js +1 -0
- package/dist/v1/TinyNotifications.min.js +1 -1
- package/dist/v1/TinyNotifyCenter.min.js +1 -1
- package/dist/v1/TinyOPFSFileSystem.min.js +1 -0
- package/dist/v1/TinyPasswordValidator.min.js +1 -0
- package/dist/v1/TinyPluginPackage.min.js +1 -0
- package/dist/v1/TinyPromiseQueue.min.js +1 -1
- package/dist/v1/TinyPushManager.min.js +1 -0
- package/dist/v1/TinyPushPayload.min.js +1 -0
- package/dist/v1/TinyPushRouter.min.js +1 -0
- package/dist/v1/TinyRadioFm.min.js +1 -1
- package/dist/v1/TinyRateLimiter.min.js +1 -1
- package/dist/v1/TinyRegexEs.min.js +1 -0
- package/dist/v1/TinyRouter.min.js +1 -0
- package/dist/v1/TinyServiceWorker.min.js +1 -0
- package/dist/v1/TinyServiceWorkerEngine.min.js +1 -0
- package/dist/v1/TinySetMapPackage.min.js +1 -0
- package/dist/v1/TinySimpleDice.min.js +1 -1
- package/dist/v1/TinySmartScroller.min.js +1 -1
- package/dist/v1/TinyStorageBucketFileSystem.min.js +1 -0
- package/dist/v1/TinyTextDiffer.min.js +1 -1
- package/dist/v1/TinyTextRangeEditor.min.js +1 -1
- package/dist/v1/TinyTextarea.min.js +1 -1
- package/dist/v1/TinyThrottledApi.min.js +1 -0
- package/dist/v1/TinyTimeout.min.js +1 -1
- package/dist/v1/TinyToastNotify.min.js +1 -1
- package/dist/v1/TinyUploadClicker.min.js +1 -1
- package/dist/v1/TinyUriParser.min.js +1 -0
- package/dist/v1/TinyVersion.min.js +1 -0
- package/dist/v1/TinyWebWorker.min.js +1 -0
- package/dist/v1/TinyWebWorkerEngine.min.js +1 -0
- package/dist/v1/UltraRandomMsgGen.min.js +1 -1
- package/dist/v1/basics/array.cjs +2 -2
- package/dist/v1/basics/array.d.mts +2 -0
- package/dist/v1/basics/array.d.mts.map +1 -1
- package/dist/v1/basics/array.mjs +2 -1
- package/dist/v1/basics/browserDetector.cjs +37 -12
- package/dist/v1/basics/browserDetector.d.mts +8 -0
- package/dist/v1/basics/browserDetector.d.mts.map +1 -1
- package/dist/v1/basics/browserDetector.mjs +32 -13
- package/dist/v1/basics/crypto.cjs +23 -0
- package/dist/v1/basics/crypto.d.mts +10 -0
- package/dist/v1/basics/crypto.d.mts.map +1 -0
- package/dist/v1/basics/crypto.mjs +18 -0
- package/dist/v1/basics/html.cjs +0 -3
- package/dist/v1/basics/html.d.mts.map +1 -1
- package/dist/v1/basics/html.mjs +0 -2
- package/dist/v1/basics/index.cjs +8 -1
- package/dist/v1/basics/index.d.mts +6 -5
- package/dist/v1/basics/index.d.mts.map +1 -1
- package/dist/v1/basics/index.mjs +6 -5
- package/dist/v1/basics/objChecker.cjs +88 -0
- package/dist/v1/basics/objChecker.d.mts +26 -0
- package/dist/v1/basics/objChecker.d.mts.map +1 -1
- package/dist/v1/basics/objChecker.mjs +74 -0
- package/dist/v1/basics/objFilter.cjs +234 -93
- package/dist/v1/basics/objFilter.d.mts +96 -22
- package/dist/v1/basics/objFilter.d.mts.map +1 -1
- package/dist/v1/basics/objFilter.mjs +216 -92
- package/dist/v1/basics/promiseUtils.cjs +48 -12
- package/dist/v1/basics/promiseUtils.d.mts +45 -12
- package/dist/v1/basics/promiseUtils.d.mts.map +1 -1
- package/dist/v1/basics/promiseUtils.mjs +47 -12
- package/dist/v1/basics/text.cjs +0 -12
- package/dist/v1/basics/text.d.mts +0 -10
- package/dist/v1/basics/text.d.mts.map +1 -1
- package/dist/v1/basics/text.mjs +0 -10
- package/dist/v1/index.cjs +88 -3
- package/dist/v1/index.d.mts +31 -6
- package/dist/v1/index.d.mts.map +1 -1
- package/dist/v1/index.mjs +32 -7
- package/dist/v1/jsdoc/EventEmitter.cjs +4 -0
- package/dist/v1/jsdoc/EventEmitter.d.mts +33 -0
- package/dist/v1/jsdoc/EventEmitter.d.mts.map +1 -0
- package/dist/v1/jsdoc/EventEmitter.mjs +18 -0
- package/dist/v1/libs/array/TinyArrayComparator.cjs +240 -25
- package/dist/v1/libs/array/TinyArrayComparator.d.mts +130 -22
- package/dist/v1/libs/array/TinyArrayComparator.d.mts.map +1 -1
- package/dist/v1/libs/array/TinyArrayComparator.mjs +210 -24
- package/dist/v1/libs/fs/constants.cjs +74 -0
- package/dist/v1/libs/fs/constants.d.mts +22 -0
- package/dist/v1/libs/fs/constants.d.mts.map +1 -0
- package/dist/v1/libs/fs/constants.mjs +53 -0
- package/dist/v1/libs/fs/encoding.cjs +118 -0
- package/dist/v1/libs/fs/encoding.d.mts +50 -0
- package/dist/v1/libs/fs/encoding.d.mts.map +1 -0
- package/dist/v1/libs/fs/encoding.mjs +102 -0
- package/dist/v1/libs/fs/error.cjs +188 -0
- package/dist/v1/libs/fs/error.d.mts +105 -0
- package/dist/v1/libs/fs/error.d.mts.map +1 -0
- package/dist/v1/libs/fs/error.mjs +158 -0
- package/dist/v1/libs/fs/handle.cjs +121 -0
- package/dist/v1/libs/fs/handle.d.mts +56 -0
- package/dist/v1/libs/fs/handle.d.mts.map +1 -0
- package/dist/v1/libs/fs/handle.mjs +100 -0
- package/dist/v1/libs/fs/index.cjs +700 -0
- package/dist/v1/libs/fs/index.d.mts +377 -0
- package/dist/v1/libs/fs/index.d.mts.map +1 -0
- package/dist/v1/libs/fs/index.mjs +630 -0
- package/dist/v1/libs/fs/path.cjs +234 -0
- package/dist/v1/libs/fs/path.d.mts +176 -0
- package/dist/v1/libs/fs/path.d.mts.map +1 -0
- package/dist/v1/libs/fs/path.mjs +197 -0
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.cjs +202 -0
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.d.mts +121 -0
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.d.mts.map +1 -0
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.mjs +172 -0
- package/dist/v1/libs/fs/plugins/OPFS/index.cjs +334 -0
- package/dist/v1/libs/fs/plugins/OPFS/index.d.mts +98 -0
- package/dist/v1/libs/fs/plugins/OPFS/index.d.mts.map +1 -0
- package/dist/v1/libs/fs/plugins/OPFS/index.mjs +300 -0
- package/dist/v1/libs/fs/stats.cjs +245 -0
- package/dist/v1/libs/fs/stats.d.mts +226 -0
- package/dist/v1/libs/fs/stats.d.mts.map +1 -0
- package/dist/v1/libs/fs/stats.mjs +197 -0
- package/dist/v1/libs/html/events/TinyIframeEvents.cjs +10 -1
- package/dist/v1/libs/html/events/TinyIframeEvents.d.mts +9 -2
- package/dist/v1/libs/html/events/TinyIframeEvents.d.mts.map +1 -1
- package/dist/v1/libs/html/events/TinyIframeEvents.mjs +8 -1
- package/dist/v1/libs/html/events/TinyNewWinEvents.cjs +14 -3
- package/dist/v1/libs/html/events/TinyNewWinEvents.d.mts +21 -5
- package/dist/v1/libs/html/events/TinyNewWinEvents.d.mts.map +1 -1
- package/dist/v1/libs/html/events/TinyNewWinEvents.mjs +12 -3
- package/dist/v1/libs/html/scroll/TinySmartScroller.cjs +13 -1
- package/dist/v1/libs/html/scroll/TinySmartScroller.d.mts +29 -2
- package/dist/v1/libs/html/scroll/TinySmartScroller.d.mts.map +1 -1
- package/dist/v1/libs/html/scroll/TinySmartScroller.mjs +11 -1
- package/dist/v1/libs/math/TinyAdvancedRaffle.cjs +13 -1
- package/dist/v1/libs/math/TinyAdvancedRaffle.d.mts +32 -2
- package/dist/v1/libs/math/TinyAdvancedRaffle.d.mts.map +1 -1
- package/dist/v1/libs/math/TinyAdvancedRaffle.mjs +11 -1
- package/dist/v1/libs/math/TinyTimeout.cjs +0 -14
- package/dist/v1/libs/math/TinyTimeout.d.mts +0 -11
- package/dist/v1/libs/math/TinyTimeout.d.mts.map +1 -1
- package/dist/v1/libs/math/TinyTimeout.mjs +0 -13
- package/dist/v1/libs/media/TinyMediaPlayer/index.cjs +25 -1
- package/dist/v1/libs/media/TinyMediaPlayer/index.d.mts +35 -2
- package/dist/v1/libs/media/TinyMediaPlayer/index.d.mts.map +1 -1
- package/dist/v1/libs/media/TinyMediaPlayer/index.mjs +23 -1
- package/dist/v1/libs/media/TinyMediaPlayer.cjs +2 -2
- package/dist/v1/libs/media/TinyMediaPlayer.d.mts +2 -2
- package/dist/v1/libs/media/TinyMediaPlayer.d.mts.map +1 -1
- package/dist/v1/libs/media/TinyMediaPlayer.mjs +2 -2
- package/dist/v1/libs/media/TinyRadioFm.cjs +19 -1
- package/dist/v1/libs/media/TinyRadioFm.d.mts +78 -2
- package/dist/v1/libs/media/TinyRadioFm.d.mts.map +1 -1
- package/dist/v1/libs/media/TinyRadioFm.mjs +17 -1
- package/dist/v1/libs/plugin/TinyPlugin.cjs +1630 -0
- package/dist/v1/libs/plugin/TinyPlugin.d.mts +753 -0
- package/dist/v1/libs/plugin/TinyPlugin.d.mts.map +1 -0
- package/dist/v1/libs/plugin/TinyPlugin.mjs +1376 -0
- package/dist/v1/libs/plugin/TinyVersion.cjs +204 -0
- package/dist/v1/libs/plugin/TinyVersion.d.mts +70 -0
- package/dist/v1/libs/plugin/TinyVersion.d.mts.map +1 -0
- package/dist/v1/libs/plugin/TinyVersion.mjs +179 -0
- package/dist/v1/libs/router/TinyRouter.cjs +661 -0
- package/dist/v1/libs/router/TinyRouter.d.mts +320 -0
- package/dist/v1/libs/router/TinyRouter.d.mts.map +1 -0
- package/dist/v1/libs/router/TinyRouter.mjs +572 -0
- package/dist/v1/libs/storage/TinyLocalStorage.cjs +20 -1
- package/dist/v1/libs/storage/TinyLocalStorage.d.mts +64 -2
- package/dist/v1/libs/storage/TinyLocalStorage.d.mts.map +1 -1
- package/dist/v1/libs/storage/TinyLocalStorage.mjs +18 -1
- package/dist/v1/libs/storage/TinyMapCache.cjs +373 -0
- package/dist/v1/libs/storage/TinyMapCache.d.mts +274 -0
- package/dist/v1/libs/storage/TinyMapCache.d.mts.map +1 -0
- package/dist/v1/libs/storage/TinyMapCache.mjs +333 -0
- package/dist/v1/libs/storage/TinySetMapDatabase.cjs +1167 -0
- package/dist/v1/libs/storage/TinySetMapDatabase.d.mts +603 -0
- package/dist/v1/libs/storage/TinySetMapDatabase.d.mts.map +1 -0
- package/dist/v1/libs/storage/TinySetMapDatabase.mjs +1059 -0
- package/dist/v1/libs/sw/browser/TinyNotificationAdapter.cjs +126 -0
- package/dist/v1/libs/sw/browser/TinyNotificationAdapter.d.mts +132 -0
- package/dist/v1/libs/sw/browser/TinyNotificationAdapter.d.mts.map +1 -0
- package/dist/v1/libs/sw/browser/TinyNotificationAdapter.mjs +109 -0
- package/dist/v1/libs/sw/browser/TinyPushManager.cjs +310 -0
- package/dist/v1/libs/sw/browser/TinyPushManager.d.mts +168 -0
- package/dist/v1/libs/sw/browser/TinyPushManager.d.mts.map +1 -0
- package/dist/v1/libs/sw/browser/TinyPushManager.mjs +264 -0
- package/dist/v1/libs/sw/browser/TinyServiceWorker.cjs +1060 -0
- package/dist/v1/libs/sw/browser/TinyServiceWorker.d.mts +348 -0
- package/dist/v1/libs/sw/browser/TinyServiceWorker.d.mts.map +1 -0
- package/dist/v1/libs/sw/browser/TinyServiceWorker.mjs +933 -0
- package/dist/v1/libs/sw/browser/plugins/TabManager.cjs +315 -0
- package/dist/v1/libs/sw/browser/plugins/TabManager.d.mts +178 -0
- package/dist/v1/libs/sw/browser/plugins/TabManager.d.mts.map +1 -0
- package/dist/v1/libs/sw/browser/plugins/TabManager.mjs +274 -0
- package/dist/v1/libs/sw/browser/utils.cjs +28 -0
- package/dist/v1/libs/sw/browser/utils.d.mts +8 -0
- package/dist/v1/libs/sw/browser/utils.d.mts.map +1 -0
- package/dist/v1/libs/sw/browser/utils.mjs +21 -0
- package/dist/v1/libs/sw/service/TinyPushRouter.cjs +222 -0
- package/dist/v1/libs/sw/service/TinyPushRouter.d.mts +138 -0
- package/dist/v1/libs/sw/service/TinyPushRouter.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/TinyPushRouter.mjs +201 -0
- package/dist/v1/libs/sw/service/TinyServiceWorkerEngine.cjs +3016 -0
- package/dist/v1/libs/sw/service/TinyServiceWorkerEngine.d.mts +993 -0
- package/dist/v1/libs/sw/service/TinyServiceWorkerEngine.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/TinyServiceWorkerEngine.mjs +2558 -0
- package/dist/v1/libs/sw/service/plugins/GlobBypassPlugin.cjs +88 -0
- package/dist/v1/libs/sw/service/plugins/GlobBypassPlugin.d.mts +32 -0
- package/dist/v1/libs/sw/service/plugins/GlobBypassPlugin.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/plugins/GlobBypassPlugin.mjs +69 -0
- package/dist/v1/libs/sw/service/plugins/GlobCachePlugin.cjs +112 -0
- package/dist/v1/libs/sw/service/plugins/GlobCachePlugin.d.mts +31 -0
- package/dist/v1/libs/sw/service/plugins/GlobCachePlugin.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/plugins/GlobCachePlugin.mjs +91 -0
- package/dist/v1/libs/sw/service/plugins/Ping.cjs +32 -0
- package/dist/v1/libs/sw/service/plugins/Ping.d.mts +9 -0
- package/dist/v1/libs/sw/service/plugins/Ping.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/plugins/Ping.mjs +25 -0
- package/dist/v1/libs/sw/service/plugins/TabManager.cjs +457 -0
- package/dist/v1/libs/sw/service/plugins/TabManager.d.mts +91 -0
- package/dist/v1/libs/sw/service/plugins/TabManager.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/plugins/TabManager.mjs +372 -0
- package/dist/v1/libs/sw/service/plugins/ViteFileDetector.cjs +180 -0
- package/dist/v1/libs/sw/service/plugins/ViteFileDetector.d.mts +28 -0
- package/dist/v1/libs/sw/service/plugins/ViteFileDetector.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/plugins/ViteFileDetector.mjs +148 -0
- package/dist/v1/libs/sw/service/shared/TinyPushPayload.cjs +199 -0
- package/dist/v1/libs/sw/service/shared/TinyPushPayload.d.mts +80 -0
- package/dist/v1/libs/sw/service/shared/TinyPushPayload.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/shared/TinyPushPayload.mjs +174 -0
- package/dist/v1/libs/sw/utils.cjs +57 -0
- package/dist/v1/libs/sw/utils.d.mts +173 -0
- package/dist/v1/libs/sw/utils.d.mts.map +1 -0
- package/dist/v1/libs/sw/utils.mjs +50 -0
- package/dist/v1/libs/text/TinyI18/Browser-NON-DOM.cjs +57 -0
- package/dist/v1/libs/text/TinyI18/Browser-NON-DOM.d.mts +39 -0
- package/dist/v1/libs/text/TinyI18/Browser-NON-DOM.d.mts.map +1 -0
- package/dist/v1/libs/text/TinyI18/Browser-NON-DOM.mjs +48 -0
- package/dist/v1/libs/text/TinyI18/Browser.cjs +64 -0
- package/dist/v1/libs/text/TinyI18/Browser.d.mts +47 -0
- package/dist/v1/libs/text/TinyI18/Browser.d.mts.map +1 -0
- package/dist/v1/libs/text/TinyI18/Browser.mjs +57 -0
- package/dist/v1/libs/text/TinyI18/Node.cjs +49 -0
- package/dist/v1/libs/text/TinyI18/Node.d.mts +38 -0
- package/dist/v1/libs/text/TinyI18/Node.d.mts.map +1 -0
- package/dist/v1/libs/text/TinyI18/Node.mjs +43 -0
- package/dist/v1/libs/text/TinyI18/browser-utils.cjs +17 -0
- package/dist/v1/libs/text/TinyI18/browser-utils.d.mts +8 -0
- package/dist/v1/libs/text/TinyI18/browser-utils.d.mts.map +1 -0
- package/dist/v1/libs/text/TinyI18/browser-utils.mjs +13 -0
- package/dist/v1/libs/text/{TinyI18.cjs → TinyI18/index.cjs} +205 -104
- package/dist/v1/libs/text/{TinyI18.d.mts → TinyI18/index.d.mts} +141 -92
- package/dist/v1/libs/text/TinyI18/index.d.mts.map +1 -0
- package/dist/v1/libs/text/{TinyI18.mjs → TinyI18/index.mjs} +195 -101
- package/dist/v1/libs/tools/TinyBrowserMonitor.cjs +1088 -0
- package/dist/v1/libs/tools/TinyBrowserMonitor.d.mts +621 -0
- package/dist/v1/libs/tools/TinyBrowserMonitor.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyBrowserMonitor.mjs +940 -0
- package/dist/v1/libs/tools/TinyDebugger.cjs +180 -19
- package/dist/v1/libs/tools/TinyDebugger.d.mts +220 -24
- package/dist/v1/libs/tools/TinyDebugger.d.mts.map +1 -1
- package/dist/v1/libs/tools/TinyDebugger.mjs +161 -19
- package/dist/v1/libs/tools/TinyHtmlTagRegexBuilder.cjs +256 -0
- package/dist/v1/libs/tools/TinyHtmlTagRegexBuilder.d.mts +125 -0
- package/dist/v1/libs/tools/TinyHtmlTagRegexBuilder.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHtmlTagRegexBuilder.mjs +223 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser-NON-DOM.cjs +23 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser-NON-DOM.d.mts +17 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser-NON-DOM.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser-NON-DOM.mjs +19 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser.cjs +23 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser.d.mts +17 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser.mjs +19 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/EmptyRequestCodes.cjs +390 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/EmptyRequestCodes.d.mts +9 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/EmptyRequestCodes.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/EmptyRequestCodes.mjs +387 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/JsDoc.cjs +2 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/JsDoc.d.mts +27 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/JsDoc.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/JsDoc.mjs +12 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/LICENSE +53 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/index.cjs +405 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/index.d.mts +34 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/index.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/index.mjs +342 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Node.cjs +23 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Node.d.mts +17 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Node.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Node.mjs +19 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/RequestCodes.cjs +327 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/RequestCodes.d.mts +9 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/RequestCodes.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/RequestCodes.mjs +324 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/index.cjs +268 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/index.d.mts +107 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/index.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/index.mjs +238 -0
- package/dist/v1/libs/tools/TinyPasswordValidator.cjs +491 -0
- package/dist/v1/libs/tools/TinyPasswordValidator.d.mts +246 -0
- package/dist/v1/libs/tools/TinyPasswordValidator.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyPasswordValidator.mjs +434 -0
- package/dist/v1/libs/tools/TinyPkgExportValidator.cjs +48 -0
- package/dist/v1/libs/tools/TinyPkgExportValidator.d.mts +14 -0
- package/dist/v1/libs/tools/TinyPkgExportValidator.d.mts.map +1 -1
- package/dist/v1/libs/tools/TinyPkgExportValidator.mjs +44 -0
- package/dist/v1/libs/tools/TinySiteMap.cjs +1029 -0
- package/dist/v1/libs/tools/TinySiteMap.d.mts +429 -0
- package/dist/v1/libs/tools/TinySiteMap.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinySiteMap.mjs +910 -0
- package/dist/v1/libs/tools/TinySiteMapStream.cjs +121 -0
- package/dist/v1/libs/tools/TinySiteMapStream.d.mts +51 -0
- package/dist/v1/libs/tools/TinySiteMapStream.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinySiteMapStream.mjs +85 -0
- package/dist/v1/libs/tools/TinyURLSecurityVerifier.cjs +444 -0
- package/dist/v1/libs/tools/TinyURLSecurityVerifier.d.mts +217 -0
- package/dist/v1/libs/tools/TinyURLSecurityVerifier.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyURLSecurityVerifier.mjs +394 -0
- package/dist/v1/libs/tools/TinyUriParser/BlueSky.cjs +613 -0
- package/dist/v1/libs/tools/TinyUriParser/BlueSky.d.mts +152 -0
- package/dist/v1/libs/tools/TinyUriParser/BlueSky.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyUriParser/BlueSky.mjs +527 -0
- package/dist/v1/libs/tools/TinyUriParser/Discord.cjs +1119 -0
- package/dist/v1/libs/tools/TinyUriParser/Discord.d.mts +306 -0
- package/dist/v1/libs/tools/TinyUriParser/Discord.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyUriParser/Discord.mjs +968 -0
- package/dist/v1/libs/tools/TinyUriParser/MatrixProtocol.cjs +469 -0
- package/dist/v1/libs/tools/TinyUriParser/MatrixProtocol.d.mts +80 -0
- package/dist/v1/libs/tools/TinyUriParser/MatrixProtocol.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyUriParser/MatrixProtocol.mjs +379 -0
- package/dist/v1/libs/tools/TinyUriParser.cjs +217 -0
- package/dist/v1/libs/tools/TinyUriParser.d.mts +109 -0
- package/dist/v1/libs/tools/TinyUriParser.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyUriParser.mjs +183 -0
- package/dist/v1/libs/utils/TinyCloner.cjs +466 -0
- package/dist/v1/libs/utils/TinyCloner.d.mts +221 -0
- package/dist/v1/libs/utils/TinyCloner.d.mts.map +1 -0
- package/dist/v1/libs/utils/TinyCloner.mjs +416 -0
- package/dist/v1/libs/utils/TinyPromiseQueue.cjs +1 -1
- package/dist/v1/libs/utils/TinyPromiseQueue.d.mts +2 -2
- package/dist/v1/libs/utils/TinyPromiseQueue.d.mts.map +1 -1
- package/dist/v1/libs/utils/TinyPromiseQueue.mjs +1 -1
- package/dist/v1/libs/utils/TinyThrottledApi.cjs +333 -0
- package/dist/v1/libs/utils/TinyThrottledApi.d.mts +163 -0
- package/dist/v1/libs/utils/TinyThrottledApi.d.mts.map +1 -0
- package/dist/v1/libs/utils/TinyThrottledApi.mjs +294 -0
- package/dist/v1/libs/worker/browser/TinyWebWorker.cjs +342 -0
- package/dist/v1/libs/worker/browser/TinyWebWorker.d.mts +97 -0
- package/dist/v1/libs/worker/browser/TinyWebWorker.d.mts.map +1 -0
- package/dist/v1/libs/worker/browser/TinyWebWorker.mjs +305 -0
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.cjs +346 -0
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.d.mts +127 -0
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.d.mts.map +1 -0
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.mjs +304 -0
- package/dist/v1/regexp/Email.cjs +185 -0
- package/dist/v1/regexp/Email.d.mts +73 -0
- package/dist/v1/regexp/Email.d.mts.map +1 -0
- package/dist/v1/regexp/Email.mjs +153 -0
- package/dist/v1/regexp/Glob.cjs +293 -0
- package/dist/v1/regexp/Glob.d.mts +45 -0
- package/dist/v1/regexp/Glob.d.mts.map +1 -0
- package/dist/v1/regexp/Glob.mjs +260 -0
- package/dist/v1/regexp/Ipv4.cjs +57 -0
- package/dist/v1/regexp/Ipv4.d.mts +29 -0
- package/dist/v1/regexp/Ipv4.d.mts.map +1 -0
- package/dist/v1/regexp/Ipv4.mjs +45 -0
- package/dist/v1/regexp/Ipv6.cjs +67 -0
- package/dist/v1/regexp/Ipv6.d.mts +29 -0
- package/dist/v1/regexp/Ipv6.d.mts.map +1 -0
- package/dist/v1/regexp/Ipv6.mjs +54 -0
- package/dist/v1/regexp/SegmentExtractor.cjs +145 -0
- package/dist/v1/regexp/SegmentExtractor.d.mts +91 -0
- package/dist/v1/regexp/SegmentExtractor.d.mts.map +1 -0
- package/dist/v1/regexp/SegmentExtractor.mjs +116 -0
- package/dist/v1/regexp/UrlDetector.cjs +125 -0
- package/dist/v1/regexp/UrlDetector.d.mts +67 -0
- package/dist/v1/regexp/UrlDetector.d.mts.map +1 -0
- package/dist/v1/regexp/UrlDetector.mjs +102 -0
- package/dist/v1/regexp/Username/index.cjs +233 -0
- package/dist/v1/regexp/Username/index.d.mts +77 -0
- package/dist/v1/regexp/Username/index.d.mts.map +1 -0
- package/dist/v1/regexp/Username/index.mjs +199 -0
- package/dist/v1/regexp/Username/jsDoc.cjs +2 -0
- package/dist/v1/regexp/Username/jsDoc.d.mts +57 -0
- package/dist/v1/regexp/Username/jsDoc.d.mts.map +1 -0
- package/dist/v1/regexp/Username/jsDoc.mjs +18 -0
- package/dist/v1/regexp/Username/templates/BlueSky.cjs +56 -0
- package/dist/v1/regexp/Username/templates/BlueSky.d.mts +35 -0
- package/dist/v1/regexp/Username/templates/BlueSky.d.mts.map +1 -0
- package/dist/v1/regexp/Username/templates/BlueSky.mjs +52 -0
- package/dist/v1/regexp/Username/templates/Discord.cjs +505 -0
- package/dist/v1/regexp/Username/templates/Discord.d.mts +209 -0
- package/dist/v1/regexp/Username/templates/Discord.d.mts.map +1 -0
- package/dist/v1/regexp/Username/templates/Discord.mjs +458 -0
- package/dist/v1/regexp/Username/templates/MatrixProtocol.cjs +143 -0
- package/dist/v1/regexp/Username/templates/MatrixProtocol.d.mts +70 -0
- package/dist/v1/regexp/Username/templates/MatrixProtocol.d.mts.map +1 -0
- package/dist/v1/regexp/Username/templates/MatrixProtocol.mjs +128 -0
- package/dist/v1/regexp/Username/templates/deprecated/Discord.cjs +24 -0
- package/dist/v1/regexp/Username/templates/deprecated/Discord.d.mts +17 -0
- package/dist/v1/regexp/Username/templates/deprecated/Discord.d.mts.map +1 -0
- package/dist/v1/regexp/Username/templates/deprecated/Discord.mjs +20 -0
- package/dist/v1/regexp/Username/templates/index.cjs +11 -0
- package/dist/v1/regexp/Username/templates/index.d.mts +5 -0
- package/dist/v1/regexp/Username/templates/index.d.mts.map +1 -0
- package/dist/v1/regexp/Username/templates/index.mjs +4 -0
- package/dist/v1/regexp/index.cjs +41 -0
- package/dist/v1/regexp/index.d.mts +9 -0
- package/dist/v1/regexp/index.d.mts.map +1 -0
- package/dist/v1/regexp/index.mjs +8 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Browser.cjs +64 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Browser.d.mts +11 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Browser.d.mts.map +1 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Browser.mjs +51 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/FileInput.cjs +66 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/FileInput.d.mts +11 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/FileInput.d.mts.map +1 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/FileInput.mjs +51 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Node.cjs +39 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Node.d.mts +11 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Node.d.mts.map +1 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Node.mjs +28 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Template.cjs +494 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Template.d.mts +142 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Template.d.mts.map +1 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Template.mjs +445 -0
- package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.cjs +30 -4
- package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.d.mts +5 -2
- package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.d.mts.map +1 -1
- package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.mjs +29 -5
- package/dist/v1/webTemplates/media/MediaValidator/v1/Browser/index.cjs +135 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Browser/index.d.mts +83 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Browser/index.d.mts.map +1 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Browser/index.mjs +120 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Node/index.cjs +127 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Node/index.d.mts +95 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Node/index.d.mts.map +1 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Node/index.mjs +109 -0
- package/dist/v1/webTemplates/multiformats/14.0/IPFSHasher/index.cjs +83 -0
- package/dist/v1/webTemplates/multiformats/14.0/IPFSHasher/index.d.mts +46 -0
- package/dist/v1/webTemplates/multiformats/14.0/IPFSHasher/index.d.mts.map +1 -0
- package/dist/v1/webTemplates/multiformats/14.0/IPFSHasher/index.mjs +71 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.cjs +493 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.d.mts +67 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.d.mts.map +1 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.mjs +399 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/githubUtils.cjs +35 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/githubUtils.d.mts +6 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/githubUtils.d.mts.map +1 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/githubUtils.mjs +29 -0
- package/docs/info/RegExp.md +74 -0
- package/docs/v1/Exports.md +101 -0
- package/docs/v1/README.md +113 -15
- package/docs/v1/basics/asyncReplace.md +2 -0
- package/docs/v1/basics/browserDetector.md +28 -11
- package/docs/v1/basics/crypto.md +85 -0
- package/docs/v1/basics/deprecated/html.md +2 -0
- package/docs/v1/basics/deprecated/objFilter.md +2 -0
- package/docs/v1/basics/html.md +2 -0
- package/docs/v1/basics/objChecker.md +55 -0
- package/docs/v1/basics/objFilter.md +57 -86
- package/docs/v1/basics/promiseUtils.md +12 -3
- package/docs/v1/basics/text.md +0 -1
- package/docs/v1/libs/array/TinyArrayComparator.md +50 -39
- package/docs/v1/libs/fs/TinyFS.md +752 -0
- package/docs/v1/libs/fs/TinyOPFSFileSystem.md +495 -0
- package/docs/v1/libs/fs/TinyStorageBucketFileSystem.md +407 -0
- package/docs/v1/libs/plugin/TinyPlugin.md +441 -0
- package/docs/v1/libs/plugin/TinyVersion.md +145 -0
- package/docs/v1/libs/router/TinyRouter.md +216 -0
- package/docs/v1/libs/storage/TinyMapCache.md +219 -0
- package/docs/v1/libs/storage/TinySetMapDatabase.md +478 -0
- package/docs/v1/libs/sw/browser/TinyNotificationAdapter.md +280 -0
- package/docs/v1/libs/sw/browser/TinyPushManager.md +782 -0
- package/docs/v1/libs/sw/browser/TinyServiceWorker.md +365 -0
- package/docs/v1/libs/sw/browser/plugins/TabManager.md +133 -0
- package/docs/v1/libs/sw/service/TinyPushRouter.md +314 -0
- package/docs/v1/libs/sw/service/TinyServiceWorkerEngine.md +748 -0
- package/docs/v1/libs/sw/service/plugins/GlobBypassPlugin.md +229 -0
- package/docs/v1/libs/sw/service/plugins/GlobCachePlugin.md +91 -0
- package/docs/v1/libs/sw/service/plugins/Ping.md +36 -0
- package/docs/v1/libs/sw/service/plugins/TabManager.md +64 -0
- package/docs/v1/libs/sw/service/plugins/ViteFileDetector.md +92 -0
- package/docs/v1/libs/sw/service/shared/TinyPushPayload.md +316 -0
- package/docs/v1/libs/text/TinyI18.md +80 -56
- package/docs/v1/libs/tools/TinyBrowserMonitor.md +170 -0
- package/docs/v1/libs/tools/TinyDebugger.md +117 -1
- package/docs/v1/libs/tools/TinyHtmlTagRegexBuilder.md +141 -0
- package/docs/v1/libs/tools/TinyHttpResponseRegistry.md +129 -0
- package/docs/v1/libs/tools/TinyPasswordValidator.md +153 -0
- package/docs/v1/libs/tools/TinyPkgExportValidator.md +45 -1
- package/docs/v1/libs/tools/TinySiteMap.md +134 -0
- package/docs/v1/libs/tools/TinySiteMapStream.md +97 -0
- package/docs/v1/libs/tools/TinyURLSecurityVerifier.md +146 -0
- package/docs/v1/libs/tools/TinyUriParser/Discord.md +374 -0
- package/docs/v1/libs/tools/TinyUriParser/MatrixProtocol.md +54 -0
- package/docs/v1/libs/tools/TinyUriParser.md +128 -0
- package/docs/v1/libs/utils/TinyCloner.md +126 -0
- package/docs/v1/libs/utils/TinyPromiseQueue.md +1 -1
- package/docs/v1/libs/utils/TinyThrottledApi.md +219 -0
- package/docs/v1/libs/worker/browser/TinyWebWorker.md +331 -0
- package/docs/v1/libs/worker/engine/TinyWebWorkerEngine.md +137 -0
- package/docs/v1/regexp/Email.md +127 -0
- package/docs/v1/regexp/Glob.md +155 -0
- package/docs/v1/regexp/IPv4.md +103 -0
- package/docs/v1/regexp/IPv6.md +122 -0
- package/docs/v1/regexp/SegmentExtractor.md +120 -0
- package/docs/v1/regexp/UrlDetector.md +117 -0
- package/docs/v1/regexp/Username/Base.md +131 -0
- package/docs/v1/regexp/Username/Discord.md +267 -0
- package/docs/v1/regexp/Username/MatrixProtocol.md +131 -0
- package/docs/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters.md +569 -0
- package/docs/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.md +19 -7
- package/docs/v1/webTemplates/media/MediaValidator/v1/Browser.md +123 -0
- package/docs/v1/webTemplates/media/MediaValidator/v1/Node.md +136 -0
- package/docs/v1/webTemplates/multiformats/14.0/IPFSHasher.md +310 -0
- package/docs/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.md +131 -0
- package/docs/v1/webTemplates/vite/7.3/plugins/githubUtils.md +50 -0
- package/package.json +303 -13
- package/types/EventEmitter.d.ts +48 -0
- package/dist/v1/libs/text/TinyI18.d.mts.map +0 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { TinySetMapDatabase, TinySetDb } from '../../../storage/TinySetMapDatabase.mjs';
|
|
2
|
+
import TinyServiceWorkerEngine from '../TinyServiceWorkerEngine.mjs';
|
|
3
|
+
const { TinyPluginLayer } = TinyServiceWorkerEngine;
|
|
4
|
+
const db = new TinySetMapDatabase('tiny-sw-vite-file-detector', [
|
|
5
|
+
{
|
|
6
|
+
create: [
|
|
7
|
+
{
|
|
8
|
+
name: 'logged-urls',
|
|
9
|
+
validate: (value) => typeof value === 'string',
|
|
10
|
+
type: 'set',
|
|
11
|
+
},
|
|
12
|
+
],
|
|
13
|
+
},
|
|
14
|
+
]);
|
|
15
|
+
/**
|
|
16
|
+
* Persistent store of URL strings that already emitted a detection log.
|
|
17
|
+
* Survives service worker restarts by mirroring every write into IndexedDB.
|
|
18
|
+
* @type {TinySetDb<string>}
|
|
19
|
+
*/
|
|
20
|
+
const loggedUrls = db.tableSet('logged-urls');
|
|
21
|
+
/**
|
|
22
|
+
* Configuration options for the ViteFileDetectorPlugin to define which paths should be bypassed.
|
|
23
|
+
* @typedef {Object} ViteFileDetectorOptions
|
|
24
|
+
* @property {(string|RegExp)[]} paths - An array of strings or regular expressions used to identify URLs that should be bypassed.
|
|
25
|
+
* @property {string} srcPath - The base path for the source directory to be included in the bypass list.
|
|
26
|
+
* @property {string} manifestPath - The path to the manifest file to be included in the bypass list.
|
|
27
|
+
* @property {number} maxCachedUrls - Maximum amount of detected URLs kept in the persistent cache. When the limit is reached, the oldest entries are evicted before the new one is written. Use `Infinity` to keep every URL forever.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Default configuration to maintain backward compatibility.
|
|
31
|
+
* @type {ViteFileDetectorOptions}
|
|
32
|
+
*/
|
|
33
|
+
const DEFAULT_OPTIONS = {
|
|
34
|
+
paths: ['/@vite', '/@react', '/node_modules'],
|
|
35
|
+
srcPath: '/src',
|
|
36
|
+
manifestPath: '/manifest.json',
|
|
37
|
+
maxCachedUrls: 1000,
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* A plugin for TinyServiceWorkerEngine to detect and bypass Vite-specific files.
|
|
41
|
+
*
|
|
42
|
+
* @type {import('../TinyServiceWorkerEngine.mjs').SwPluginInstaller<InstanceType<typeof TinyPluginLayer>, 'ViteFileDetector', '1.0.0', [Partial<ViteFileDetectorOptions>]|[]>}
|
|
43
|
+
* @throws {TypeError} If the engine is invalid or if the provided options do not match the required schema.
|
|
44
|
+
*/
|
|
45
|
+
const ViteFileDetectorPlugin = (instance, options = {}) => {
|
|
46
|
+
const engine = instance.engine;
|
|
47
|
+
instance.id = 'ViteFileDetector';
|
|
48
|
+
instance.version = '1.0.0';
|
|
49
|
+
instance.description = 'Vite File detector.';
|
|
50
|
+
instance.authors = ['JasminDreasond'];
|
|
51
|
+
instance.contributors = ['JasminDreasond'];
|
|
52
|
+
instance.categories = ['framework-validator'];
|
|
53
|
+
instance.tags = ['vite', 'framework', 'validator'];
|
|
54
|
+
if (!(engine instanceof TinyServiceWorkerEngine)) {
|
|
55
|
+
throw new TypeError('Plugin requires a TinyServiceWorkerEngine instance to function.');
|
|
56
|
+
}
|
|
57
|
+
// 1. Merge and Validate Options
|
|
58
|
+
/** @type {ViteFileDetectorOptions} */
|
|
59
|
+
const config = { ...DEFAULT_OPTIONS, ...options };
|
|
60
|
+
if (!Array.isArray(config.paths)) {
|
|
61
|
+
throw new TypeError('The "paths" property in options must be an array.');
|
|
62
|
+
}
|
|
63
|
+
const paths = [...config.paths, config.srcPath, config.manifestPath];
|
|
64
|
+
// Deep validation of the paths array elements
|
|
65
|
+
paths.forEach((pattern, index) => {
|
|
66
|
+
const isValidString = typeof pattern === 'string';
|
|
67
|
+
const isValidRegExp = pattern instanceof RegExp;
|
|
68
|
+
if (!isValidString && !isValidRegExp) {
|
|
69
|
+
throw new TypeError(`Invalid type at paths[${index}]: Expected string or RegExp, but received ${typeof pattern}.`);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
// 2. Validate the cache limit
|
|
73
|
+
if (typeof config.maxCachedUrls !== 'number') {
|
|
74
|
+
throw new TypeError(`The "maxCachedUrls" option must be a number, but received ${typeof config.maxCachedUrls}.`);
|
|
75
|
+
}
|
|
76
|
+
if (config.maxCachedUrls !== Infinity &&
|
|
77
|
+
(!Number.isInteger(config.maxCachedUrls) || config.maxCachedUrls < 1)) {
|
|
78
|
+
throw new RangeError(`The "maxCachedUrls" option must be a positive integer or Infinity, but received ${config.maxCachedUrls}.`);
|
|
79
|
+
}
|
|
80
|
+
const { maxCachedUrls } = config;
|
|
81
|
+
// 3. Implementation
|
|
82
|
+
// @ts-ignore
|
|
83
|
+
if (import.meta.env.DEV) {
|
|
84
|
+
/**
|
|
85
|
+
* Tail of the detection queue.
|
|
86
|
+
*
|
|
87
|
+
* Every cache mutation is chained here because `TinySetDb` only makes each
|
|
88
|
+
* individual call atomic. Without this queue, two detections that resolve in
|
|
89
|
+
* the same tick would both read the same `size` and both decide to insert,
|
|
90
|
+
* letting the cache grow past `maxCachedUrls`.
|
|
91
|
+
* @type {Promise<void>}
|
|
92
|
+
*/
|
|
93
|
+
let detectionQueue = Promise.resolve();
|
|
94
|
+
/**
|
|
95
|
+
* Runs a detection task after every previously queued task has settled.
|
|
96
|
+
* @param {() => Promise<void>} task - The task that touches the cache.
|
|
97
|
+
* @returns {Promise<void>} Resolves when the task settles.
|
|
98
|
+
*/
|
|
99
|
+
const enqueueDetection = (task) => {
|
|
100
|
+
const result = detectionQueue.then(task);
|
|
101
|
+
detectionQueue = result.catch(() => undefined);
|
|
102
|
+
return result;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Drops the oldest URLs until a single new entry fits inside the limit.
|
|
106
|
+
*
|
|
107
|
+
* The `+ 1` reserves the slot for the value that is about to be inserted,
|
|
108
|
+
* so the cache always ends up with exactly `maxCachedUrls` entries.
|
|
109
|
+
* @returns {Promise<void>} Resolves once the cache is below the limit.
|
|
110
|
+
*/
|
|
111
|
+
const evictOldestUrls = async () => {
|
|
112
|
+
const overflow = loggedUrls.size - maxCachedUrls + 1;
|
|
113
|
+
if (overflow <= 0)
|
|
114
|
+
return;
|
|
115
|
+
const snapshot = await loggedUrls.toArray();
|
|
116
|
+
/** @type {Promise<any>[]} */
|
|
117
|
+
const promises = [];
|
|
118
|
+
for (let index = 0; index < overflow; index += 1) {
|
|
119
|
+
promises.push(loggedUrls.delete(snapshot[index]));
|
|
120
|
+
}
|
|
121
|
+
await Promise.all(promises);
|
|
122
|
+
};
|
|
123
|
+
engine.addFetchGlobalListener('ViteFileDetectorPlugin', ({ url }, response) => {
|
|
124
|
+
const isBypassed = paths.some((pattern) => {
|
|
125
|
+
if (pattern instanceof RegExp)
|
|
126
|
+
return pattern.test(url.pathname);
|
|
127
|
+
return url.pathname.startsWith(pattern);
|
|
128
|
+
});
|
|
129
|
+
if (!isBypassed)
|
|
130
|
+
return;
|
|
131
|
+
response.continueCheck = false;
|
|
132
|
+
response.needValidation = false;
|
|
133
|
+
response.code = 200;
|
|
134
|
+
const cacheKey = url.toString();
|
|
135
|
+
enqueueDetection(async () => {
|
|
136
|
+
if (await loggedUrls.has(cacheKey))
|
|
137
|
+
return;
|
|
138
|
+
await evictOldestUrls();
|
|
139
|
+
await loggedUrls.add(cacheKey);
|
|
140
|
+
instance.log('warn', `File detected: ${cacheKey}`);
|
|
141
|
+
}).catch((error) => {
|
|
142
|
+
instance.log('error', `Failed to cache the detected URL "${cacheKey}": ${error.message}`);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return new TinyPluginLayer();
|
|
147
|
+
};
|
|
148
|
+
export default ViteFileDetectorPlugin;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var utils = require('../../utils.cjs');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file Shared contract for every message that travels through the Web Push channel.
|
|
7
|
+
*
|
|
8
|
+
* The module is isomorphic on purpose: the Service Worker imports it to parse the
|
|
9
|
+
* incoming payload, and the page imports it to build and validate the payload
|
|
10
|
+
* before it reaches the backend.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** @typedef {import('../../utils.mjs').TinyPushNotification} TinyPushNotification */
|
|
14
|
+
/** @typedef {import('../../utils.mjs').TinyPushMessage} TinyPushMessage */
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Holds the fallback values applied when an incoming message omits the
|
|
18
|
+
* corresponding optional notification field.
|
|
19
|
+
*
|
|
20
|
+
* @typedef {Object} TinyPushNotificationDefaults
|
|
21
|
+
* @property {string} [defaultIcon] - Fallback icon.
|
|
22
|
+
* @property {string} [defaultBadge] - Fallback badge.
|
|
23
|
+
* @property {string} [defaultUrl] - Fallback click URL.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const MAX_TTL_SECONDS = 2419200;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Normalizes, validates and converts Web Push payloads.
|
|
30
|
+
*
|
|
31
|
+
* Every method is static and side effect free, so the class is safe to import
|
|
32
|
+
* from both the page and the Service Worker.
|
|
33
|
+
* @beta
|
|
34
|
+
*/
|
|
35
|
+
class TinyPushPayload {
|
|
36
|
+
static #PUSH_TYPE = utils.PUSH_TYPE;
|
|
37
|
+
static get PUSH_TYPE() {
|
|
38
|
+
return TinyPushPayload.#PUSH_TYPE;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** @type {number} The current payload schema version. */
|
|
42
|
+
static VERSION = 1;
|
|
43
|
+
|
|
44
|
+
/** @type {number} The maximum allowed TTL, in seconds. */
|
|
45
|
+
static MAX_TTL = MAX_TTL_SECONDS;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Builds a normalized message from an untrusted value.
|
|
49
|
+
*
|
|
50
|
+
* @param {unknown} raw - The value received from the network.
|
|
51
|
+
* @returns {TinyPushMessage} A frozen, normalized message.
|
|
52
|
+
* @throws {TypeError} If `raw` is not a non-null object.
|
|
53
|
+
*/
|
|
54
|
+
static from(raw) {
|
|
55
|
+
if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
|
|
56
|
+
throw new TypeError('[TinyPushPayload] from: raw must be a non-null object.');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const source = /** @type {Record<string, unknown>} */ (raw);
|
|
60
|
+
const type =
|
|
61
|
+
typeof source.type === 'string' && source.type !== '' ? source.type : utils.PUSH_TYPE.UNKNOWN;
|
|
62
|
+
|
|
63
|
+
/** @type {TinyPushMessage} */
|
|
64
|
+
const message = {
|
|
65
|
+
v: typeof source.v === 'number' ? source.v : TinyPushPayload.VERSION,
|
|
66
|
+
type,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
if (typeof source.id === 'string') message.id = source.id;
|
|
70
|
+
if (typeof source.topic === 'string') message.topic = source.topic;
|
|
71
|
+
if (typeof source.expiresAt === 'number') message.expiresAt = source.expiresAt;
|
|
72
|
+
if (typeof source.ttl === 'number' && Number.isFinite(source.ttl)) {
|
|
73
|
+
message.ttl = Math.min(Math.max(0, Math.trunc(source.ttl)), MAX_TTL_SECONDS);
|
|
74
|
+
}
|
|
75
|
+
if (typeof source.data === 'object' && source.data !== null && !Array.isArray(source.data)) {
|
|
76
|
+
message.data = /** @type {Record<string, unknown>} */ (source.data);
|
|
77
|
+
}
|
|
78
|
+
if (typeof source.notification === 'object' && source.notification !== null) {
|
|
79
|
+
message.notification = TinyPushPayload.#normalizeNotification(source.notification);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return Object.freeze(message);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Reads the payload of a `push` event exactly once.
|
|
87
|
+
*
|
|
88
|
+
* `PushMessageData` is a one-shot stream: calling `json()` and then `text()`
|
|
89
|
+
* throws `TypeError`. This method reads the body once and parses it manually.
|
|
90
|
+
*
|
|
91
|
+
* @param {PushEvent} event - The native push event.
|
|
92
|
+
* @returns {Promise<TinyPushMessage>} The normalized message, never `null`.
|
|
93
|
+
*/
|
|
94
|
+
static async fromEvent(event) {
|
|
95
|
+
if (typeof event !== 'object' || event === null || !('data' in event)) {
|
|
96
|
+
throw new TypeError('[TinyPushPayload] fromEvent: event must be a PushEvent.');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (!event.data) {
|
|
100
|
+
return Object.freeze({ v: TinyPushPayload.VERSION, type: utils.PUSH_TYPE.UNKNOWN });
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let text;
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
text = await event.data.text();
|
|
107
|
+
} catch {
|
|
108
|
+
return Object.freeze({ v: TinyPushPayload.VERSION, type: utils.PUSH_TYPE.UNKNOWN });
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (text === '') {
|
|
112
|
+
return Object.freeze({ v: TinyPushPayload.VERSION, type: utils.PUSH_TYPE.UNKNOWN });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
return TinyPushPayload.from(JSON.parse(text));
|
|
117
|
+
} catch {
|
|
118
|
+
return Object.freeze({
|
|
119
|
+
v: TinyPushPayload.VERSION,
|
|
120
|
+
type: utils.PUSH_TYPE.UNKNOWN,
|
|
121
|
+
notification: { title: 'Notification', body: text },
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Checks whether a message is past its expiration time.
|
|
128
|
+
*
|
|
129
|
+
* @param {TinyPushMessage} message - The message to inspect.
|
|
130
|
+
* @param {number} [now=Date.now()] - Reference time in milliseconds.
|
|
131
|
+
* @returns {boolean} `true` when the message must be discarded.
|
|
132
|
+
* @throws {TypeError} If `message` is not a non-null object or `now` is not a finite number.
|
|
133
|
+
*/
|
|
134
|
+
static isExpired(message, now = Date.now()) {
|
|
135
|
+
if (typeof message !== 'object' || message === null) {
|
|
136
|
+
throw new TypeError('[TinyPushPayload] isExpired: message must be a non-null object.');
|
|
137
|
+
}
|
|
138
|
+
if (typeof now !== 'number' || !Number.isFinite(now)) {
|
|
139
|
+
throw new TypeError('[TinyPushPayload] isExpired: now must be a finite number.');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return typeof message.expiresAt === 'number' && message.expiresAt <= now;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Converts a message into the `[title, options]` pair expected by `showNotification`.
|
|
147
|
+
*
|
|
148
|
+
* @param {TinyPushMessage} message - The normalized message.
|
|
149
|
+
* @param {TinyPushNotificationDefaults} [defaults] - Fallback values.
|
|
150
|
+
* @returns {{ title: string, options: NotificationOptions & { data: Record<string, unknown> } }} The arguments.
|
|
151
|
+
* @throws {TypeError} If `message` is not a non-null object.
|
|
152
|
+
*/
|
|
153
|
+
static toNotification(message, defaults = {}) {
|
|
154
|
+
if (typeof message !== 'object' || message === null) {
|
|
155
|
+
throw new TypeError('[TinyPushPayload] toNotification: message must be a non-null object.');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const n = message.notification ?? { title: 'Notification' };
|
|
159
|
+
const { title, body, url, actions, data, ...rest } = n;
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
title: title ?? 'Notification',
|
|
163
|
+
options: {
|
|
164
|
+
...rest,
|
|
165
|
+
body: body ?? '',
|
|
166
|
+
icon: n.icon ?? defaults.defaultIcon,
|
|
167
|
+
badge: n.badge ?? defaults.defaultBadge,
|
|
168
|
+
// @ts-ignore
|
|
169
|
+
actions,
|
|
170
|
+
data: {
|
|
171
|
+
...data,
|
|
172
|
+
url: url ?? defaults.defaultUrl ?? '/',
|
|
173
|
+
actions: Object.fromEntries((actions ?? []).map((a) => [a.action, a.url ?? url ?? '/'])),
|
|
174
|
+
pushId: message.id,
|
|
175
|
+
pushType: message.type,
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Validates and normalizes a notification descriptor.
|
|
183
|
+
*
|
|
184
|
+
* @param {object} raw - The value to normalize.
|
|
185
|
+
* @returns {TinyPushNotification} The normalized descriptor.
|
|
186
|
+
* @throws {TypeError} If `title` is missing or not a string.
|
|
187
|
+
*/
|
|
188
|
+
static #normalizeNotification(raw) {
|
|
189
|
+
const source = /** @type {Record<string, unknown>} */ (raw);
|
|
190
|
+
|
|
191
|
+
if (typeof source.title !== 'string' || source.title.trim() === '') {
|
|
192
|
+
throw new TypeError('[TinyPushPayload] notification.title must be a non-empty string.');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return /** @type {TinyPushNotification} */ ({ ...source });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
module.exports = TinyPushPayload;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export type TinyPushNotification = import('../../utils.mjs').TinyPushNotification;
|
|
2
|
+
export type TinyPushMessage = import('../../utils.mjs').TinyPushMessage;
|
|
3
|
+
export type TinyPushNotificationDefaults = {
|
|
4
|
+
/**
|
|
5
|
+
* - Fallback icon.
|
|
6
|
+
*/
|
|
7
|
+
defaultIcon?: string;
|
|
8
|
+
/**
|
|
9
|
+
* - Fallback badge.
|
|
10
|
+
*/
|
|
11
|
+
defaultBadge?: string;
|
|
12
|
+
/**
|
|
13
|
+
* - Fallback click URL.
|
|
14
|
+
*/
|
|
15
|
+
defaultUrl?: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Normalizes, validates and converts Web Push payloads.
|
|
19
|
+
*
|
|
20
|
+
* Every method is static and side effect free, so the class is safe to import
|
|
21
|
+
* from both the page and the Service Worker.
|
|
22
|
+
* @beta
|
|
23
|
+
*/
|
|
24
|
+
declare class TinyPushPayload {
|
|
25
|
+
#private;
|
|
26
|
+
static get PUSH_TYPE(): Readonly<{
|
|
27
|
+
NOTIFICATION: "notification";
|
|
28
|
+
DATA: "data";
|
|
29
|
+
SYNC: "sync";
|
|
30
|
+
COMMAND: "command";
|
|
31
|
+
UNKNOWN: "unknown";
|
|
32
|
+
}>;
|
|
33
|
+
/** @type {number} The current payload schema version. */
|
|
34
|
+
static VERSION: number;
|
|
35
|
+
/** @type {number} The maximum allowed TTL, in seconds. */
|
|
36
|
+
static MAX_TTL: number;
|
|
37
|
+
/**
|
|
38
|
+
* Builds a normalized message from an untrusted value.
|
|
39
|
+
*
|
|
40
|
+
* @param {unknown} raw - The value received from the network.
|
|
41
|
+
* @returns {TinyPushMessage} A frozen, normalized message.
|
|
42
|
+
* @throws {TypeError} If `raw` is not a non-null object.
|
|
43
|
+
*/
|
|
44
|
+
static from(raw: unknown): TinyPushMessage;
|
|
45
|
+
/**
|
|
46
|
+
* Reads the payload of a `push` event exactly once.
|
|
47
|
+
*
|
|
48
|
+
* `PushMessageData` is a one-shot stream: calling `json()` and then `text()`
|
|
49
|
+
* throws `TypeError`. This method reads the body once and parses it manually.
|
|
50
|
+
*
|
|
51
|
+
* @param {PushEvent} event - The native push event.
|
|
52
|
+
* @returns {Promise<TinyPushMessage>} The normalized message, never `null`.
|
|
53
|
+
*/
|
|
54
|
+
static fromEvent(event: PushEvent): Promise<TinyPushMessage>;
|
|
55
|
+
/**
|
|
56
|
+
* Checks whether a message is past its expiration time.
|
|
57
|
+
*
|
|
58
|
+
* @param {TinyPushMessage} message - The message to inspect.
|
|
59
|
+
* @param {number} [now=Date.now()] - Reference time in milliseconds.
|
|
60
|
+
* @returns {boolean} `true` when the message must be discarded.
|
|
61
|
+
* @throws {TypeError} If `message` is not a non-null object or `now` is not a finite number.
|
|
62
|
+
*/
|
|
63
|
+
static isExpired(message: TinyPushMessage, now?: number): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Converts a message into the `[title, options]` pair expected by `showNotification`.
|
|
66
|
+
*
|
|
67
|
+
* @param {TinyPushMessage} message - The normalized message.
|
|
68
|
+
* @param {TinyPushNotificationDefaults} [defaults] - Fallback values.
|
|
69
|
+
* @returns {{ title: string, options: NotificationOptions & { data: Record<string, unknown> } }} The arguments.
|
|
70
|
+
* @throws {TypeError} If `message` is not a non-null object.
|
|
71
|
+
*/
|
|
72
|
+
static toNotification(message: TinyPushMessage, defaults?: TinyPushNotificationDefaults): {
|
|
73
|
+
title: string;
|
|
74
|
+
options: NotificationOptions & {
|
|
75
|
+
data: Record<string, unknown>;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export default TinyPushPayload;
|
|
80
|
+
//# sourceMappingURL=TinyPushPayload.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TinyPushPayload.d.mts","sourceRoot":"","sources":["../../../../../../../src/v1/libs/sw/service/shared/TinyPushPayload.mjs"],"names":[],"mappings":"AAUI,YAA0D,oBAAoB,GAApE,OAAO,iBAAiB,EAAE,oBAAoB,CAAsB;AAC9E,YAAqD,eAAe,GAA1D,OAAO,iBAAiB,EAAE,eAAe,CAAiB;AAMrE,YAAkB,4BAA4B,GAC9C;;;;IAAoB,WAAW,AAA/B,CACA,EADW,MAAM,CACjB;;;;IAAoB,YAAY,AAAhC,CACA,EADW,MAAM,CACjB;;;;IAAoB,UAAU,AAA9B,CACF,EADa,MAAM,CACnB;CAAA,CAAA;AAID;;;;;;GAMG;AACH,cAAM,eAAe;;IAEnB,MAAM,KAAK,SAAS;;;;;;OAEnB;IAED,yDAAyD;IACzD,MAAM,CAAC,OAAO,EADH,MAAM,CACE;IAEnB,0DAA0D;IAC1D,MAAM,CAAC,OAAO,EADH,MAAM,CACgB;IAEjC;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,CAAC,GAAG,EAJJ,OAII,GAHF,eAAe,CAgC3B;IAED;;;;;;;;OAQG;IACH,OAAa,SAAS,CAAC,KAAK,EAHjB,SAGiB,GAFf,OAAO,CAAC,eAAe,CAAC,CAgCpC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,SAAS,CAAC,OAAO,EALb,eAKa,EAAE,GAAG,AAJ1B,CACA,EADQ,MAI+B,GAH7B,OAAO,CAYnB;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EALlB,eAKkB,EAAE,QAAQ,AAJpC,CACA,EADQ,4BAIiC,GAH/B;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,mBAAmB,GAAG;YAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAAE,CAAA;KAAE,CA6B/F;CAkBF;eAEc,eAAe"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { PUSH_TYPE } from '../../utils.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* @file Shared contract for every message that travels through the Web Push channel.
|
|
4
|
+
*
|
|
5
|
+
* The module is isomorphic on purpose: the Service Worker imports it to parse the
|
|
6
|
+
* incoming payload, and the page imports it to build and validate the payload
|
|
7
|
+
* before it reaches the backend.
|
|
8
|
+
*/
|
|
9
|
+
/** @typedef {import('../../utils.mjs').TinyPushNotification} TinyPushNotification */
|
|
10
|
+
/** @typedef {import('../../utils.mjs').TinyPushMessage} TinyPushMessage */
|
|
11
|
+
/**
|
|
12
|
+
* Holds the fallback values applied when an incoming message omits the
|
|
13
|
+
* corresponding optional notification field.
|
|
14
|
+
*
|
|
15
|
+
* @typedef {Object} TinyPushNotificationDefaults
|
|
16
|
+
* @property {string} [defaultIcon] - Fallback icon.
|
|
17
|
+
* @property {string} [defaultBadge] - Fallback badge.
|
|
18
|
+
* @property {string} [defaultUrl] - Fallback click URL.
|
|
19
|
+
*/
|
|
20
|
+
const MAX_TTL_SECONDS = 2419200;
|
|
21
|
+
/**
|
|
22
|
+
* Normalizes, validates and converts Web Push payloads.
|
|
23
|
+
*
|
|
24
|
+
* Every method is static and side effect free, so the class is safe to import
|
|
25
|
+
* from both the page and the Service Worker.
|
|
26
|
+
* @beta
|
|
27
|
+
*/
|
|
28
|
+
class TinyPushPayload {
|
|
29
|
+
static #PUSH_TYPE = PUSH_TYPE;
|
|
30
|
+
static get PUSH_TYPE() {
|
|
31
|
+
return TinyPushPayload.#PUSH_TYPE;
|
|
32
|
+
}
|
|
33
|
+
/** @type {number} The current payload schema version. */
|
|
34
|
+
static VERSION = 1;
|
|
35
|
+
/** @type {number} The maximum allowed TTL, in seconds. */
|
|
36
|
+
static MAX_TTL = MAX_TTL_SECONDS;
|
|
37
|
+
/**
|
|
38
|
+
* Builds a normalized message from an untrusted value.
|
|
39
|
+
*
|
|
40
|
+
* @param {unknown} raw - The value received from the network.
|
|
41
|
+
* @returns {TinyPushMessage} A frozen, normalized message.
|
|
42
|
+
* @throws {TypeError} If `raw` is not a non-null object.
|
|
43
|
+
*/
|
|
44
|
+
static from(raw) {
|
|
45
|
+
if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
|
|
46
|
+
throw new TypeError('[TinyPushPayload] from: raw must be a non-null object.');
|
|
47
|
+
}
|
|
48
|
+
const source = /** @type {Record<string, unknown>} */ (raw);
|
|
49
|
+
const type = typeof source.type === 'string' && source.type !== '' ? source.type : PUSH_TYPE.UNKNOWN;
|
|
50
|
+
/** @type {TinyPushMessage} */
|
|
51
|
+
const message = {
|
|
52
|
+
v: typeof source.v === 'number' ? source.v : TinyPushPayload.VERSION,
|
|
53
|
+
type,
|
|
54
|
+
};
|
|
55
|
+
if (typeof source.id === 'string')
|
|
56
|
+
message.id = source.id;
|
|
57
|
+
if (typeof source.topic === 'string')
|
|
58
|
+
message.topic = source.topic;
|
|
59
|
+
if (typeof source.expiresAt === 'number')
|
|
60
|
+
message.expiresAt = source.expiresAt;
|
|
61
|
+
if (typeof source.ttl === 'number' && Number.isFinite(source.ttl)) {
|
|
62
|
+
message.ttl = Math.min(Math.max(0, Math.trunc(source.ttl)), MAX_TTL_SECONDS);
|
|
63
|
+
}
|
|
64
|
+
if (typeof source.data === 'object' && source.data !== null && !Array.isArray(source.data)) {
|
|
65
|
+
message.data = /** @type {Record<string, unknown>} */ (source.data);
|
|
66
|
+
}
|
|
67
|
+
if (typeof source.notification === 'object' && source.notification !== null) {
|
|
68
|
+
message.notification = TinyPushPayload.#normalizeNotification(source.notification);
|
|
69
|
+
}
|
|
70
|
+
return Object.freeze(message);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Reads the payload of a `push` event exactly once.
|
|
74
|
+
*
|
|
75
|
+
* `PushMessageData` is a one-shot stream: calling `json()` and then `text()`
|
|
76
|
+
* throws `TypeError`. This method reads the body once and parses it manually.
|
|
77
|
+
*
|
|
78
|
+
* @param {PushEvent} event - The native push event.
|
|
79
|
+
* @returns {Promise<TinyPushMessage>} The normalized message, never `null`.
|
|
80
|
+
*/
|
|
81
|
+
static async fromEvent(event) {
|
|
82
|
+
if (typeof event !== 'object' || event === null || !('data' in event)) {
|
|
83
|
+
throw new TypeError('[TinyPushPayload] fromEvent: event must be a PushEvent.');
|
|
84
|
+
}
|
|
85
|
+
if (!event.data) {
|
|
86
|
+
return Object.freeze({ v: TinyPushPayload.VERSION, type: PUSH_TYPE.UNKNOWN });
|
|
87
|
+
}
|
|
88
|
+
let text;
|
|
89
|
+
try {
|
|
90
|
+
text = await event.data.text();
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return Object.freeze({ v: TinyPushPayload.VERSION, type: PUSH_TYPE.UNKNOWN });
|
|
94
|
+
}
|
|
95
|
+
if (text === '') {
|
|
96
|
+
return Object.freeze({ v: TinyPushPayload.VERSION, type: PUSH_TYPE.UNKNOWN });
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
return TinyPushPayload.from(JSON.parse(text));
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return Object.freeze({
|
|
103
|
+
v: TinyPushPayload.VERSION,
|
|
104
|
+
type: PUSH_TYPE.UNKNOWN,
|
|
105
|
+
notification: { title: 'Notification', body: text },
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Checks whether a message is past its expiration time.
|
|
111
|
+
*
|
|
112
|
+
* @param {TinyPushMessage} message - The message to inspect.
|
|
113
|
+
* @param {number} [now=Date.now()] - Reference time in milliseconds.
|
|
114
|
+
* @returns {boolean} `true` when the message must be discarded.
|
|
115
|
+
* @throws {TypeError} If `message` is not a non-null object or `now` is not a finite number.
|
|
116
|
+
*/
|
|
117
|
+
static isExpired(message, now = Date.now()) {
|
|
118
|
+
if (typeof message !== 'object' || message === null) {
|
|
119
|
+
throw new TypeError('[TinyPushPayload] isExpired: message must be a non-null object.');
|
|
120
|
+
}
|
|
121
|
+
if (typeof now !== 'number' || !Number.isFinite(now)) {
|
|
122
|
+
throw new TypeError('[TinyPushPayload] isExpired: now must be a finite number.');
|
|
123
|
+
}
|
|
124
|
+
return typeof message.expiresAt === 'number' && message.expiresAt <= now;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Converts a message into the `[title, options]` pair expected by `showNotification`.
|
|
128
|
+
*
|
|
129
|
+
* @param {TinyPushMessage} message - The normalized message.
|
|
130
|
+
* @param {TinyPushNotificationDefaults} [defaults] - Fallback values.
|
|
131
|
+
* @returns {{ title: string, options: NotificationOptions & { data: Record<string, unknown> } }} The arguments.
|
|
132
|
+
* @throws {TypeError} If `message` is not a non-null object.
|
|
133
|
+
*/
|
|
134
|
+
static toNotification(message, defaults = {}) {
|
|
135
|
+
if (typeof message !== 'object' || message === null) {
|
|
136
|
+
throw new TypeError('[TinyPushPayload] toNotification: message must be a non-null object.');
|
|
137
|
+
}
|
|
138
|
+
const n = message.notification ?? { title: 'Notification' };
|
|
139
|
+
const { title, body, url, actions, data, ...rest } = n;
|
|
140
|
+
return {
|
|
141
|
+
title: title ?? 'Notification',
|
|
142
|
+
options: {
|
|
143
|
+
...rest,
|
|
144
|
+
body: body ?? '',
|
|
145
|
+
icon: n.icon ?? defaults.defaultIcon,
|
|
146
|
+
badge: n.badge ?? defaults.defaultBadge,
|
|
147
|
+
// @ts-ignore
|
|
148
|
+
actions,
|
|
149
|
+
data: {
|
|
150
|
+
...data,
|
|
151
|
+
url: url ?? defaults.defaultUrl ?? '/',
|
|
152
|
+
actions: Object.fromEntries((actions ?? []).map((a) => [a.action, a.url ?? url ?? '/'])),
|
|
153
|
+
pushId: message.id,
|
|
154
|
+
pushType: message.type,
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Validates and normalizes a notification descriptor.
|
|
161
|
+
*
|
|
162
|
+
* @param {object} raw - The value to normalize.
|
|
163
|
+
* @returns {TinyPushNotification} The normalized descriptor.
|
|
164
|
+
* @throws {TypeError} If `title` is missing or not a string.
|
|
165
|
+
*/
|
|
166
|
+
static #normalizeNotification(raw) {
|
|
167
|
+
const source = /** @type {Record<string, unknown>} */ (raw);
|
|
168
|
+
if (typeof source.title !== 'string' || source.title.trim() === '') {
|
|
169
|
+
throw new TypeError('[TinyPushPayload] notification.title must be a non-empty string.');
|
|
170
|
+
}
|
|
171
|
+
return /** @type {TinyPushNotification} */ ({ ...source });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
export default TinyPushPayload;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {Object} TinyPushAction
|
|
5
|
+
* @property {string} action - Identifier echoed back on `notificationclick`.
|
|
6
|
+
* @property {string} title - Human readable label.
|
|
7
|
+
* @property {string} [icon] - Absolute URL of the action icon.
|
|
8
|
+
* @property {string} [url] - URL opened when the action is clicked.
|
|
9
|
+
* @property {boolean} [dismiss] - When `true`, the action only closes the notification.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {Object} TinyPushNotification
|
|
14
|
+
* @property {string} title - Notification title.
|
|
15
|
+
* @property {string} [body] - Notification body.
|
|
16
|
+
* @property {string} [icon] - Absolute URL of the icon.
|
|
17
|
+
* @property {string} [badge] - Absolute URL of the badge.
|
|
18
|
+
* @property {string} [image] - Absolute URL of the hero image.
|
|
19
|
+
* @property {string} [tag] - Collapse key. Notifications with the same tag replace each other.
|
|
20
|
+
* @property {string} [lang] - BCP 47 language tag.
|
|
21
|
+
* @property {string} [dir] - Text direction: `ltr` or `rtl`.
|
|
22
|
+
* @property {string} [url] - URL opened when the notification body is clicked.
|
|
23
|
+
* @property {boolean} [renotify] - Whether to vibrate on replacement.
|
|
24
|
+
* @property {boolean} [requireInteraction] - Whether the notification stays until dismissed.
|
|
25
|
+
* @property {boolean} [silent] - Whether to suppress vibration and sound.
|
|
26
|
+
* @property {number} [timestamp] - Creation time in milliseconds since the epoch.
|
|
27
|
+
* @property {number[]} [vibrate] - Vibration pattern in milliseconds.
|
|
28
|
+
* @property {TinyPushAction[]} [actions] - Action buttons.
|
|
29
|
+
* @property {Record<string, unknown>} [data] - Opaque data echoed back on click.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @typedef {Object} TinyPushMessage
|
|
34
|
+
* @property {number} v - Contract version.
|
|
35
|
+
* @property {string} type - Routing key, see {@link PUSH_TYPE}.
|
|
36
|
+
* @property {string} [id] - Idempotency identifier.
|
|
37
|
+
* @property {number} [ttl] - Time to live in seconds.
|
|
38
|
+
* @property {string} [topic] - Collapse key at the transport level.
|
|
39
|
+
* @property {number} [expiresAt] - Absolute expiration time in milliseconds since the epoch.
|
|
40
|
+
* @property {TinyPushNotification} [notification] - Notification descriptor.
|
|
41
|
+
* @property {Record<string, unknown>} [data] - Arbitrary payload for custom handlers.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Discriminator used by the router to pick a handler.
|
|
46
|
+
* @readonly
|
|
47
|
+
* @enum {string}
|
|
48
|
+
*/
|
|
49
|
+
const PUSH_TYPE = Object.freeze({
|
|
50
|
+
NOTIFICATION: 'notification',
|
|
51
|
+
DATA: 'data',
|
|
52
|
+
SYNC: 'sync',
|
|
53
|
+
COMMAND: 'command',
|
|
54
|
+
UNKNOWN: 'unknown',
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
exports.PUSH_TYPE = PUSH_TYPE;
|