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,495 @@
|
|
|
1
|
+
# 🗂️ TinyFS OPFS Backend
|
|
2
|
+
|
|
3
|
+
> An Origin Private File System backend for [`TinyFSCore`](./TinyFS.md), running in the browser.
|
|
4
|
+
|
|
5
|
+
This backend maps the `TinyFSCore` contract onto the
|
|
6
|
+
[Origin Private File System](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system)
|
|
7
|
+
(OPFS). It gives you a real, persistent, sandboxed file system inside the browser,
|
|
8
|
+
with the same API you already use in Node.js.
|
|
9
|
+
|
|
10
|
+
It is designed for **browser extensions, PWAs, offline-first editors and Web Workers** that
|
|
11
|
+
need more than `localStorage` and less than a server.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 📑 Table of Contents
|
|
16
|
+
|
|
17
|
+
1. [Why This Exists](#-why-this-exists)
|
|
18
|
+
2. [Features](#-features)
|
|
19
|
+
3. [Requirements](#-requirements)
|
|
20
|
+
4. [Project Layout](#-project-layout)
|
|
21
|
+
5. [Quick Start](#-quick-start)
|
|
22
|
+
6. [Core Concepts](#-core-concepts)
|
|
23
|
+
- [The Root Handle](#1--the-root-handle)
|
|
24
|
+
- [Path Resolution](#2--path-resolution)
|
|
25
|
+
- [Native vs. Emulated Operations](#3--native-vs-emulated-operations)
|
|
26
|
+
7. [API Reference](#-api-reference)
|
|
27
|
+
- [Constructor](#constructor)
|
|
28
|
+
- [Static Members](#static-members)
|
|
29
|
+
- [Protected Hooks](#protected-hooks)
|
|
30
|
+
8. [Compatibility Matrix](#-compatibility-matrix)
|
|
31
|
+
9. [Daily Workflow Recipes](#-daily-workflow-recipes)
|
|
32
|
+
10. [Error Codes](#-error-codes)
|
|
33
|
+
11. [Known Divergences and Gotchas](#-known-divergences-and-gotchas)
|
|
34
|
+
12. [Cheatsheet](#-cheatsheet)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 🤔 Why This Exists
|
|
39
|
+
|
|
40
|
+
The browser has three storage primitives, and none of them is a file system:
|
|
41
|
+
|
|
42
|
+
| Primitive | Size limit | Sync API | Directory tree |
|
|
43
|
+
| --- | --- | --- | --- |
|
|
44
|
+
| `localStorage` | ~5 MB | ✅ | ❌ |
|
|
45
|
+
| IndexedDB | Quota-based | ❌ | ❌ |
|
|
46
|
+
| **OPFS** | Quota-based | ❌ | ✅ |
|
|
47
|
+
|
|
48
|
+
OPFS is the only one that gives you a real hierarchy. But its API is verbose:
|
|
49
|
+
every operation needs a `FileSystemDirectoryHandle`, every path has to be walked
|
|
50
|
+
manually, and errors are `DOMException` instances with names like `NotFoundError`.
|
|
51
|
+
|
|
52
|
+
This backend hides all of that behind the `TinyFSCore` interface.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## ✨ Features
|
|
57
|
+
|
|
58
|
+
| Feature | Status |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| 🌐 Runs in the main thread and in Workers | ✅ |
|
|
61
|
+
| 📁 Nested directory trees | ✅ |
|
|
62
|
+
| 🔁 Recursive copy and move | ✅ |
|
|
63
|
+
| 📦 Zero runtime dependencies | ✅ |
|
|
64
|
+
| 🔒 Symbolic links | ❌ OPFS has none |
|
|
65
|
+
| 🔐 POSIX permissions | 🧠 Emulated in memory |
|
|
66
|
+
| 🕐 Timestamps | 🧠 Emulated in memory |
|
|
67
|
+
| ⚛️ Atomic rename | ❌ Copy + delete |
|
|
68
|
+
| 🌊 Streaming reads and writes | ❌ Buffered in memory |
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 📋 Requirements
|
|
73
|
+
|
|
74
|
+
- A **secure context** (`https://` or `localhost`).
|
|
75
|
+
- A browser with OPFS support: Chrome 86+, Firefox 111+, Safari 15.2+.
|
|
76
|
+
|
|
77
|
+
> ⚠️ OPFS is **not available** in a Node.js process without a polyfill. The constructor
|
|
78
|
+
> succeeds, but the first operation throws `ENOSYS`.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 🚀 Quick Start
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
import TinyOPFSFileSystem from 'tiny-essentials/libs/fs/plugins/OPFS';
|
|
86
|
+
|
|
87
|
+
const fs = new TinyOPFSFileSystem();
|
|
88
|
+
|
|
89
|
+
// Write a file. Parent directories must exist.
|
|
90
|
+
await fs.mkdir('/projects', { recursive: true });
|
|
91
|
+
await fs.writeFile('/projects/notes.txt', 'hello from OPFS', { encoding: 'utf8' });
|
|
92
|
+
|
|
93
|
+
// Read it back.
|
|
94
|
+
const text = await fs.readFile('/projects/notes.txt', { encoding: 'utf8' });
|
|
95
|
+
console.log(text); // "hello from OPFS"
|
|
96
|
+
|
|
97
|
+
// List the directory.
|
|
98
|
+
console.log(await fs.readdir('/projects')); // ["notes.txt"]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 🧠 Core Concepts
|
|
104
|
+
|
|
105
|
+
### 1. 🌱 The Root Handle
|
|
106
|
+
|
|
107
|
+
Every operation starts from a `FileSystemDirectoryHandle`. By default, the backend calls
|
|
108
|
+
`navigator.storage.getDirectory()` on first use and **caches the result** in a private
|
|
109
|
+
field.
|
|
110
|
+
|
|
111
|
+
```javascript
|
|
112
|
+
const fs = new TinyOPFSFileSystem();
|
|
113
|
+
// Nothing has touched the disk yet.
|
|
114
|
+
|
|
115
|
+
await fs.readFile('/a.txt');
|
|
116
|
+
// 1. #resolveRoot() runs.
|
|
117
|
+
// 2. navigator.storage.getDirectory() is called once.
|
|
118
|
+
// 3. The handle is cached in #root.
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
You can inject your own root — useful for tests and for scoping a backend to a
|
|
122
|
+
sub-directory:
|
|
123
|
+
|
|
124
|
+
```javascript
|
|
125
|
+
const root = await navigator.storage.getDirectory();
|
|
126
|
+
const scoped = await root.getDirectoryHandle('my-app', { create: true });
|
|
127
|
+
|
|
128
|
+
const fs = new TinyOPFSFileSystem({ root: scoped });
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
> 💡 Injecting a root is the recommended way to isolate tests. Each test gets a fresh
|
|
132
|
+
> sub-directory and cleans up after itself.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
### 2. 🧭 Path Resolution
|
|
137
|
+
|
|
138
|
+
Paths are normalised by `toSegments()` and then walked one segment at a time. There is no
|
|
139
|
+
path cache, so a deep path costs one `getDirectoryHandle` call per segment.
|
|
140
|
+
|
|
141
|
+
```text
|
|
142
|
+
"/a/b/c.txt"
|
|
143
|
+
│
|
|
144
|
+
├─ getDirectoryHandle("a")
|
|
145
|
+
├─ getDirectoryHandle("b")
|
|
146
|
+
└─ getFileHandle("c.txt")
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The special path `"/"` resolves to zero segments, which is why `_stat("/")` short-circuits
|
|
150
|
+
and returns a synthetic descriptor.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
### 3. 🔀 Native vs. Emulated Operations
|
|
155
|
+
|
|
156
|
+
This is the most important concept in this document.
|
|
157
|
+
|
|
158
|
+
| Layer | Backed by | Survives a reload? |
|
|
159
|
+
| --- | --- | --- |
|
|
160
|
+
| **File contents** | OPFS | ✅ Yes |
|
|
161
|
+
| **Directory structure** | OPFS | ✅ Yes |
|
|
162
|
+
| **Permissions (`mode`)** | `Map` in `TinyFSCore` | ❌ No |
|
|
163
|
+
| **Ownership (`uid`/`gid`)** | `Map` in `TinyFSCore` | ❌ No |
|
|
164
|
+
| **Timestamps** | `Map` in `TinyFSCore` | ❌ No |
|
|
165
|
+
|
|
166
|
+
The class docstring states this directly:
|
|
167
|
+
|
|
168
|
+
> OPFS has no symbolic links, no permission bits and no way to set timestamps. Those
|
|
169
|
+
> operations are emulated by the base class and stored in memory, so they are lost when
|
|
170
|
+
> the tab is closed.
|
|
171
|
+
|
|
172
|
+
**Practical consequence:** if your application relies on `chmod` to gate access, that gate
|
|
173
|
+
disappears on reload. Persist any security-relevant flag inside the file itself.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## 📚 API Reference
|
|
178
|
+
|
|
179
|
+
### Constructor
|
|
180
|
+
|
|
181
|
+
```javascript
|
|
182
|
+
new TinyOPFSFileSystem(options?)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
| Option | Type | Default | Description |
|
|
186
|
+
| --- | --- | --- | --- |
|
|
187
|
+
| `options.root` | `FileSystemDirectoryHandle` | `null` | Custom root. Resolved lazily when omitted. |
|
|
188
|
+
| `options.cwd` | `string` | `ROOT_PATH` | Forwarded to `TinyFSCore`. |
|
|
189
|
+
| `options.umask` | `number` | `DEFAULT_UMASK` | Forwarded to `TinyFSCore`. |
|
|
190
|
+
| `options.identity` | `FSIdentity` | `{ uid: 0, gid: 0, groups: [] }` | Forwarded to `TinyFSCore`. |
|
|
191
|
+
|
|
192
|
+
```javascript
|
|
193
|
+
const fs = new TinyOPFSFileSystem({
|
|
194
|
+
root: await navigator.storage.getDirectory(),
|
|
195
|
+
umask: 0o022,
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
### Static Members
|
|
202
|
+
|
|
203
|
+
#### `TinyOPFSFileSystem.capabilities`
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
TinyOPFSFileSystem.capabilities;
|
|
207
|
+
// {
|
|
208
|
+
// permissions: false,
|
|
209
|
+
// ownership: false,
|
|
210
|
+
// symlinks: false,
|
|
211
|
+
// timestamps: false,
|
|
212
|
+
// atomicRename: false,
|
|
213
|
+
// seekableHandles: false
|
|
214
|
+
// }
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
> ⚠️ Every flag is `false`, including `atomicRename`. The `_rename` implementation is a
|
|
218
|
+
> recursive copy followed by a delete, so a crash mid-way leaves a partial tree.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
### Protected Hooks
|
|
223
|
+
|
|
224
|
+
These are the methods this backend implements. You should not call them directly — use the
|
|
225
|
+
public `TinyFSCore` methods instead.
|
|
226
|
+
|
|
227
|
+
#### `_resolveRoot()`
|
|
228
|
+
|
|
229
|
+
Resolves and caches the root directory handle.
|
|
230
|
+
|
|
231
|
+
| Returns | Description |
|
|
232
|
+
| --- | --- |
|
|
233
|
+
| `Promise<FileSystemDirectoryHandle>` | The OPFS root directory. |
|
|
234
|
+
|
|
235
|
+
**Throws:** `ENOSYS` when `navigator.storage.getDirectory` is not a function.
|
|
236
|
+
|
|
237
|
+
**Override this** when your backend stores its tree inside a nested location, such as a
|
|
238
|
+
storage bucket:
|
|
239
|
+
|
|
240
|
+
```javascript
|
|
241
|
+
class BucketFileSystem extends TinyOPFSFileSystem {
|
|
242
|
+
async _resolveRoot() {
|
|
243
|
+
const root = await super._resolveRoot();
|
|
244
|
+
return root.getDirectoryHandle('bucket', { create: true });
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
#### `_readFile(targetPath)`
|
|
252
|
+
|
|
253
|
+
Reads a file into a `Uint8Array`.
|
|
254
|
+
|
|
255
|
+
| Parameter | Type | Description |
|
|
256
|
+
| --- | --- | --- |
|
|
257
|
+
| `targetPath` | `string` | Absolute path of the file. |
|
|
258
|
+
|
|
259
|
+
**Returns:** `Promise<Uint8Array>`
|
|
260
|
+
|
|
261
|
+
**Throws:** `EISDIR` when the path is a directory. The fallback code is applied to every
|
|
262
|
+
non-`DOMException` failure, so a genuine I/O error is also reported as `EISDIR`.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
#### `_writeFile(targetPath, bytes, options)`
|
|
267
|
+
|
|
268
|
+
Writes bytes to a file, creating it when missing.
|
|
269
|
+
|
|
270
|
+
| Parameter | Type | Description |
|
|
271
|
+
| --- | --- | --- |
|
|
272
|
+
| `targetPath` | `string` | Absolute path of the file. |
|
|
273
|
+
| `bytes` | `Uint8Array` | Payload to persist. |
|
|
274
|
+
| `options.append` | `boolean` | When `true`, writes at the current end of file. |
|
|
275
|
+
|
|
276
|
+
**Returns:** `Promise<void>`
|
|
277
|
+
|
|
278
|
+
> ⚠️ The parent directory must already exist. `#resolveParent` uses `create: false`, so a
|
|
279
|
+
> missing parent throws `ENOENT`.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
#### `_readdir(targetPath)`
|
|
284
|
+
|
|
285
|
+
Lists a directory.
|
|
286
|
+
|
|
287
|
+
**Returns:** `Promise<FSDirectoryEntry[]>` — sorted by `name` using `localeCompare`.
|
|
288
|
+
|
|
289
|
+
> ⚠️ The sort is locale-dependent. Do not rely on it for a stable wire format.
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
#### `_mkdir(targetPath, options)`
|
|
294
|
+
|
|
295
|
+
Creates a directory.
|
|
296
|
+
|
|
297
|
+
| `options.recursive` | Behaviour |
|
|
298
|
+
| --- | --- |
|
|
299
|
+
| `true` | Creates missing parents. Silently succeeds when the directory exists. |
|
|
300
|
+
| `false` | Throws `EEXIST` when the name is taken. |
|
|
301
|
+
|
|
302
|
+
> ⚠️ The non-recursive path performs a **check-then-create**. It is not atomic.
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
#### `_rm(targetPath, options)`
|
|
307
|
+
|
|
308
|
+
Removes a file or directory.
|
|
309
|
+
|
|
310
|
+
| `options.recursive` | `options.force` | Behaviour |
|
|
311
|
+
| --- | --- | --- |
|
|
312
|
+
| `false` | `false` | Throws `ENOTEMPTY` when the directory is not empty. |
|
|
313
|
+
| `true` | `false` | Removes the tree. |
|
|
314
|
+
| `*` | `true` | Missing paths are ignored. |
|
|
315
|
+
|
|
316
|
+
> ⚠️ `force: true` does **not** suppress a missing **parent** directory. `#resolveParent`
|
|
317
|
+
> runs before the existence check, so `rm('/missing/child', { force: true })` still throws
|
|
318
|
+
> `ENOENT`.
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
#### `_stat(targetPath)`
|
|
323
|
+
|
|
324
|
+
Returns a descriptor for a file or directory.
|
|
325
|
+
|
|
326
|
+
**Returns:** `Promise<FSStatDescriptor | undefined>`
|
|
327
|
+
|
|
328
|
+
| Kind | `size` | `mtimeMs` |
|
|
329
|
+
| --- | --- | --- |
|
|
330
|
+
| File | `File.size` | `File.lastModified` |
|
|
331
|
+
| Directory | `0` | `Date.now()` |
|
|
332
|
+
| Root (`/`) | `0` | `Date.now()` |
|
|
333
|
+
|
|
334
|
+
> ⚠️ Directory `mtimeMs` is **never stable**. It returns the current time on every call.
|
|
335
|
+
> Do not use it for cache invalidation.
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
#### `_rename(oldPath, newPath)`
|
|
340
|
+
|
|
341
|
+
Moves a file or directory.
|
|
342
|
+
|
|
343
|
+
| Source kind | Implementation |
|
|
344
|
+
| --- | --- |
|
|
345
|
+
| File | `_readFile` → `_writeFile` → `_rm` |
|
|
346
|
+
| Directory | `#copyTree` → `_rm` |
|
|
347
|
+
|
|
348
|
+
**Returns:** `Promise<void>`
|
|
349
|
+
|
|
350
|
+
> ⚠️ This is **not atomic**. See [Known Divergences](#-known-divergences-and-gotchas).
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
#### `_copyFile(sourcePath, destinationPath)`
|
|
355
|
+
|
|
356
|
+
Copies a file by reading it fully into memory.
|
|
357
|
+
|
|
358
|
+
**Returns:** `Promise<void>`
|
|
359
|
+
|
|
360
|
+
> ⚠️ The base class passes a third `mode` argument. This override ignores it.
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## 📊 Compatibility Matrix
|
|
365
|
+
|
|
366
|
+
| `node:fs/promises` method | Status | Notes |
|
|
367
|
+
| --- | --- | --- |
|
|
368
|
+
| `readFile` | ✅ Native | |
|
|
369
|
+
| `writeFile` | ✅ Native | |
|
|
370
|
+
| `appendFile` | ✅ Native | Uses `keepExistingData: true` |
|
|
371
|
+
| `readdir` | ✅ Native | Sorted by name |
|
|
372
|
+
| `mkdir` | ✅ Native | |
|
|
373
|
+
| `rm` / `rmdir` | ✅ Native | |
|
|
374
|
+
| `unlink` | ✅ Native | |
|
|
375
|
+
| `copyFile` | ✅ Native | Buffered in memory |
|
|
376
|
+
| `stat` / `lstat` | ✅ Native | Directory mtime is not stable |
|
|
377
|
+
| `rename` | ⚠️ Emulated | Copy + delete, not atomic |
|
|
378
|
+
| `truncate` | ⚠️ Emulated | Read + write |
|
|
379
|
+
| `access` | ⚠️ Emulated | Uses the in-memory identity |
|
|
380
|
+
| `realpath` | ⚠️ Emulated | String normalisation only |
|
|
381
|
+
| `open` | ⚠️ Emulated | Returns a `FileHandle` |
|
|
382
|
+
| `chmod` / `chown` | 🧠 In-memory | Lost on reload |
|
|
383
|
+
| `utimes` | 🧠 In-memory | Lost on reload |
|
|
384
|
+
| `symlink` / `readlink` | ❌ Unsupported | OPFS has no symlinks |
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## 🚨 Error Codes
|
|
389
|
+
|
|
390
|
+
All errors are created through `createFileSystemError` or mapped by `toFileSystemError`.
|
|
391
|
+
|
|
392
|
+
| Code | Thrown by | Meaning |
|
|
393
|
+
| --- | --- | --- |
|
|
394
|
+
| `ENOENT` | `readFile`, `stat`, `rm`, `rename` | No such file or directory. |
|
|
395
|
+
| `EISDIR` | `readFile` | The path is a directory. |
|
|
396
|
+
| `EEXIST` | `mkdir` | The directory already exists. |
|
|
397
|
+
| `ENOTEMPTY` | `rm` | The directory is not empty. |
|
|
398
|
+
| `EINVAL` | `rm`, `rename` | The root has no parent. |
|
|
399
|
+
| `ENOSYS` | `_resolveRoot` | OPFS is not available. |
|
|
400
|
+
|
|
401
|
+
```javascript
|
|
402
|
+
try {
|
|
403
|
+
await fs.readFile('/missing.txt');
|
|
404
|
+
} catch (error) {
|
|
405
|
+
console.error(error.code); // "ENOENT"
|
|
406
|
+
console.error(error.syscall); // "readFile"
|
|
407
|
+
console.error(error.path); // "/missing.txt"
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
## ⚠️ Known Divergences and Gotchas
|
|
414
|
+
|
|
415
|
+
Read this section before you file a bug. These are the behaviours that differ from
|
|
416
|
+
`node:fs/promises` or from the base class contract.
|
|
417
|
+
|
|
418
|
+
### 🔴 Data integrity
|
|
419
|
+
|
|
420
|
+
| # | Location | Behaviour |
|
|
421
|
+
| --- | --- | --- |
|
|
422
|
+
| 1 | `_rename` | **Not atomic.** Copies the tree, then deletes the source. A crash leaves both copies. |
|
|
423
|
+
| 2 | `_rename` | **Merges into an existing destination.** `getDirectoryHandle(newPath, { create: true })` does not replace the target. |
|
|
424
|
+
| 3 | `_rename` | **Renaming a directory into its own descendant** copies the tree, then deletes the copy. Silent data loss. |
|
|
425
|
+
| 4 | `_rm` | `force: true` does **not** suppress a missing parent. `#resolveParent` runs first and throws `ENOENT`. |
|
|
426
|
+
| 5 | `_writeFile` | Does **not** create parent directories. `#resolveParent` uses `create: false`. |
|
|
427
|
+
|
|
428
|
+
### 🟡 Metadata
|
|
429
|
+
|
|
430
|
+
| # | Location | Behaviour |
|
|
431
|
+
| --- | --- | --- |
|
|
432
|
+
| 6 | `_stat` | Directory `mtimeMs` is `Date.now()`. Never stable across calls. |
|
|
433
|
+
| 7 | `_stat` | The root descriptor uses `name: "/"` instead of a base name. |
|
|
434
|
+
| 8 | `_stat` | Every directory reports `size: 0`. |
|
|
435
|
+
| 9 | `chmod` / `chown` / `utimes` | Emulated in memory. Lost on reload. |
|
|
436
|
+
|
|
437
|
+
### 🟠 Performance
|
|
438
|
+
|
|
439
|
+
| # | Location | Behaviour |
|
|
440
|
+
| --- | --- | --- |
|
|
441
|
+
| 10 | `_readFile` / `_writeFile` | Buffer the whole file in memory. No streaming. |
|
|
442
|
+
| 11 | `_rename` | Reads and rewrites every byte of a directory tree. |
|
|
443
|
+
| 12 | `_stat` | Calls `getFile()` for files, which reads the file header. |
|
|
444
|
+
| 13 | `_rename` (file) | Calls `getFile()` twice: once in `_stat`, once in `_readFile`. |
|
|
445
|
+
| 14 | `_readdir` | Sorts with `localeCompare`, which is locale-dependent. |
|
|
446
|
+
|
|
447
|
+
### 🔵 API surface
|
|
448
|
+
|
|
449
|
+
| # | Location | Behaviour |
|
|
450
|
+
| --- | --- | --- |
|
|
451
|
+
| 15 | `_copyFile` | Ignores the `mode` argument the base class passes. |
|
|
452
|
+
| 16 | `_readFile` | Maps every non-`DOMException` failure to `EISDIR`. |
|
|
453
|
+
| 17 | `capabilities` | Every flag is `false`, including `atomicRename`. |
|
|
454
|
+
| 18 | `_resolveRoot` | Caches the handle. Replacing the OPFS root at runtime has no effect. |
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## 🧾 Cheatsheet
|
|
459
|
+
|
|
460
|
+
```javascript
|
|
461
|
+
import TinyOPFSFileSystem from 'tiny-essentials/libs/fs/plugins/OPFS';
|
|
462
|
+
|
|
463
|
+
// ─── Setup ────────────────────────────────────────────────────────────
|
|
464
|
+
const fs = new TinyOPFSFileSystem();
|
|
465
|
+
const scoped = new TinyOPFSFileSystem({ root: await navigator.storage.getDirectory() });
|
|
466
|
+
|
|
467
|
+
// ─── Files ────────────────────────────────────────────────────────────
|
|
468
|
+
await fs.mkdir('/app', { recursive: true });
|
|
469
|
+
await fs.writeFile('/app/a.txt', 'data', { encoding: 'utf8' });
|
|
470
|
+
await fs.appendFile('/app/a.txt', 'more');
|
|
471
|
+
const text = await fs.readFile('/app/a.txt', { encoding: 'utf8' });
|
|
472
|
+
const buffer = await fs.readFile('/app/a.txt'); // Uint8Array
|
|
473
|
+
await fs.copyFile('/app/a.txt', '/app/b.txt');
|
|
474
|
+
await fs.unlink('/app/a.txt');
|
|
475
|
+
|
|
476
|
+
// ─── Directories ──────────────────────────────────────────────────────
|
|
477
|
+
const names = await fs.readdir('/app');
|
|
478
|
+
const dirents = await fs.readdir('/app', { withFileTypes: true });
|
|
479
|
+
await fs.rm('/app', { recursive: true, force: true });
|
|
480
|
+
|
|
481
|
+
// ─── Metadata (in-memory only) ────────────────────────────────────────
|
|
482
|
+
const stats = await fs.stat('/app/a.txt');
|
|
483
|
+
await fs.chmod('/app/a.txt', 0o600);
|
|
484
|
+
await fs.chown('/app/a.txt', 1000, 1000);
|
|
485
|
+
await fs.utimes('/app/a.txt', Date.now(), Date.now());
|
|
486
|
+
|
|
487
|
+
// ─── Paths ────────────────────────────────────────────────────────────
|
|
488
|
+
await fs.rename('/app/a.txt', '/app/b.txt');
|
|
489
|
+
const absolute = await fs.realpath('/app/../app/a.txt');
|
|
490
|
+
const found = await fs.exists('/app/a.txt');
|
|
491
|
+
|
|
492
|
+
// ─── Storage ──────────────────────────────────────────────────────────
|
|
493
|
+
await navigator.storage.persist();
|
|
494
|
+
const { usage, quota } = await navigator.storage.estimate();
|
|
495
|
+
```
|