tiny-essentials 1.28.18 โ 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/css/TinyCookieConsent.min.css +1 -0
- package/dist/v1/css/TinyCookieConsent.min.css.map +1 -0
- package/dist/v1/css/TinyDraggerExample.min.css +1 -0
- package/dist/v1/css/TinyDraggerExample.min.css.map +1 -0
- package/dist/v1/css/TinyLoadingScreen.min.css +1 -0
- package/dist/v1/css/TinyLoadingScreen.min.css.map +1 -0
- package/dist/v1/css/TinyNotify.min.css +1 -0
- package/dist/v1/css/TinyNotify.min.css.map +1 -0
- package/dist/v1/css/aiMarker.min.css +1 -0
- package/dist/v1/css/aiMarker.min.css.map +1 -0
- 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 +725 -0
- package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.d.mts +293 -0
- package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.d.mts.map +1 -0
- package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.mjs +614 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/input/Placeholder-Colors-Fix.scss +64 -0
- package/dist/v1/webTemplates/bootstrap/5.3/scss/spacing/Spacing-Plus.scss +31 -0
- 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 +111 -0
- package/docs/v1/README.md +117 -13
- 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 +174 -0
- 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 +313 -18
- package/types/EventEmitter.d.ts +48 -0
- package/dist/v1/libs/text/TinyI18.d.mts.map +0 -1
|
@@ -0,0 +1,752 @@
|
|
|
1
|
+
# ๐๏ธ TinyFS Core
|
|
2
|
+
|
|
3
|
+
> A tiny, dependency-free, `node:fs/promises`-compatible file system core written in pure ESM JavaScript.
|
|
4
|
+
|
|
5
|
+
TinyFS Core is an **abstract base class**. It gives you a complete, promise-based file system
|
|
6
|
+
API surface โ `readFile`, `writeFile`, `readdir`, `stat`, `chmod`, `rename`, and friends โ while
|
|
7
|
+
delegating the actual byte storage to a backend you write.
|
|
8
|
+
|
|
9
|
+
The base class is **not a stub**. It ships with a working in-memory side table for permissions,
|
|
10
|
+
ownership and timestamps, so a backend only has to answer one question: *"where do the bytes
|
|
11
|
+
live?"*
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## ๐ Table of Contents
|
|
16
|
+
|
|
17
|
+
1. [Features](#-features)
|
|
18
|
+
2. [Requirements](#-requirements)
|
|
19
|
+
3. [Project Layout](#-project-layout)
|
|
20
|
+
4. [Quick Start](#-quick-start)
|
|
21
|
+
5. [Core Concepts](#-core-concepts)
|
|
22
|
+
- [The Metadata Side Table](#1--the-metadata-side-table)
|
|
23
|
+
- [Protected Hooks](#2--protected-hooks)
|
|
24
|
+
- [Capabilities](#3--capabilities)
|
|
25
|
+
- [Identity and Permissions](#4--identity-and-permissions)
|
|
26
|
+
6. [API Reference](#-api-reference)
|
|
27
|
+
- [Constructor](#constructor)
|
|
28
|
+
- [Instance Getters](#instance-getters)
|
|
29
|
+
- [Static Members](#static-members)
|
|
30
|
+
- [File Operations](#-file-operations)
|
|
31
|
+
- [Directory Operations](#-directory-operations)
|
|
32
|
+
- [Metadata Operations](#-metadata-operations)
|
|
33
|
+
- [Path Operations](#-path-operations)
|
|
34
|
+
- [Handles](#-handles)
|
|
35
|
+
7. [Building a Backend](#-building-a-backend)
|
|
36
|
+
8. [Error Codes](#-error-codes)
|
|
37
|
+
9. [Known Divergences and Gotchas](#-known-divergences-and-gotchas)
|
|
38
|
+
10. [Cheatsheet](#-cheatsheet)
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## โจ Features
|
|
43
|
+
|
|
44
|
+
| Feature | Status |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| ๐งฉ Zero runtime dependencies | โ
|
|
|
47
|
+
| ๐ฆ Pure ESM (`import` / `export`) | โ
|
|
|
48
|
+
| ๐ Private class fields with getters | โ
|
|
|
49
|
+
| ๐งช Trivially mockable | โ
|
|
|
50
|
+
| ๐ช Windows-style path handling | โ POSIX only |
|
|
51
|
+
| ๐ Symbolic links | โ Base class only |
|
|
52
|
+
| ๐งต Concurrent write safety | โ Backend's responsibility |
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## ๐ Requirements
|
|
57
|
+
|
|
58
|
+
- **Node.js** `>= 18.0.0` (native ESM, private class fields, `Object.freeze` on statics).
|
|
59
|
+
- A module resolver that understands the `.mjs` extension.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## ๐ Project Layout
|
|
64
|
+
|
|
65
|
+
The core module imports from six sibling modules. Your tree should look like this:
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
src/
|
|
69
|
+
โโโ index.mjs # TinyFSCore โ the abstract class
|
|
70
|
+
โโโ constants.mjs # DEFAULT_FILE_MODE, DEFAULT_DIRECTORY_MODE, DEFAULT_UMASK, ROOT_PATH, constants
|
|
71
|
+
โโโ error.mjs # assertPath, assertInteger, assertMode, assertOptionsObject,
|
|
72
|
+
โ # assertEncoding, createFileSystemError
|
|
73
|
+
โโโ encoding.mjs # decodeBytes, toUint8Array
|
|
74
|
+
โโโ stats.mjs # Stats, Dirent
|
|
75
|
+
โโโ handle.mjs # FileHandle
|
|
76
|
+
โโโ path.mjs # toSegments
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## ๐ Quick Start
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
import MemoryFileSystem from './memory-fs.mjs';
|
|
85
|
+
|
|
86
|
+
const fs = new MemoryFileSystem({ cwd: '/app' });
|
|
87
|
+
|
|
88
|
+
// Write and read text.
|
|
89
|
+
await fs.writeFile('/app/notes.txt', 'hello world', { encoding: 'utf8' });
|
|
90
|
+
const text = await fs.readFile('/app/notes.txt', { encoding: 'utf8' });
|
|
91
|
+
|
|
92
|
+
console.log(text); // "hello world"
|
|
93
|
+
|
|
94
|
+
// Inspect metadata.
|
|
95
|
+
const stats = await fs.stat('/app/notes.txt');
|
|
96
|
+
console.log(stats.size);
|
|
97
|
+
console.log(stats.mode.toString(8));
|
|
98
|
+
|
|
99
|
+
// Clean up.
|
|
100
|
+
await fs.rm('/app/notes.txt');
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
> ๐ก The example above requires a backend. Jump to
|
|
104
|
+
> [Building a Backend](#-building-a-backend) for a complete, copy-pasteable implementation.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## ๐ง Core Concepts
|
|
109
|
+
|
|
110
|
+
### 1. ๐๏ธ The Metadata Side Table
|
|
111
|
+
|
|
112
|
+
Every `TinyFSCore` instance owns a private `Map`:
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
#metadata = new Map(); // Map<string, FSMetadata>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This map stores `mode`, `uid`, `gid`, `atimeMs`, `mtimeMs` and `birthtimeMs` for each path.
|
|
119
|
+
**Your backend never touches it directly.** The public methods read and write it for you.
|
|
120
|
+
|
|
121
|
+
The shape of each record is:
|
|
122
|
+
|
|
123
|
+
```javascript
|
|
124
|
+
/**
|
|
125
|
+
* @typedef {Object} FSMetadata
|
|
126
|
+
* @property {number | null} mode
|
|
127
|
+
* @property {number | null} uid
|
|
128
|
+
* @property {number | null} gid
|
|
129
|
+
* @property {number | null} atimeMs
|
|
130
|
+
* @property {number | null} mtimeMs
|
|
131
|
+
* @property {number | null} birthtimeMs
|
|
132
|
+
*/
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
A `null` field means *"not set"*. When `stat()` encounters a `null`, it substitutes a sensible
|
|
136
|
+
default based on the entry kind.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
### 2 ๐ Protected Hooks
|
|
141
|
+
|
|
142
|
+
Methods prefixed with a single underscore are **hooks**. They are the contract between the core
|
|
143
|
+
and your backend. Every hook receives **raw, already-validated values** โ no encoding, no
|
|
144
|
+
defaults, no metadata merging.
|
|
145
|
+
|
|
146
|
+
| Hook | Purpose |
|
|
147
|
+
| --- | --- |
|
|
148
|
+
| `_readFile(path)` | Return the raw bytes of a file. |
|
|
149
|
+
| `_writeFile(path, bytes, options)` | Persist bytes. Honour `options.append`. |
|
|
150
|
+
| `_readdir(path)` | Return `FSDirectoryEntry[]`. |
|
|
151
|
+
| `_mkdir(path, options)` | Create a directory. Honour `options.recursive`. |
|
|
152
|
+
| `_rm(path, options)` | Remove an entry. Honour `recursive` and `force`. |
|
|
153
|
+
| `_stat(path)` | Return an `FSStatDescriptor`, or `undefined` when missing. |
|
|
154
|
+
| `_rename(oldPath, newPath)` | Move an entry. |
|
|
155
|
+
| `_copyFile(source, destination, mode)` | Copy a file. |
|
|
156
|
+
| `_readMetadata(path)` | Read the side table. **Rarely overridden.** |
|
|
157
|
+
| `_writeMetadata(path, metadata)` | Write the side table. **Rarely overridden.** |
|
|
158
|
+
|
|
159
|
+
Every hook throws `ENOSYS` by default, so an unimplemented operation fails loudly instead of
|
|
160
|
+
silently corrupting data.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
### 3. ๐๏ธ Capabilities
|
|
165
|
+
|
|
166
|
+
`capabilities` is a **static getter** that advertises what a backend supports. It is frozen, so
|
|
167
|
+
consumers can safely cache it.
|
|
168
|
+
|
|
169
|
+
```javascript
|
|
170
|
+
import TinyFSCore from 'tiny-essentials/libs/fs/TinyFSCore';
|
|
171
|
+
|
|
172
|
+
console.log(TinyFSCore.capabilities);
|
|
173
|
+
// {
|
|
174
|
+
// permissions: false,
|
|
175
|
+
// ownership: false,
|
|
176
|
+
// symlinks: false,
|
|
177
|
+
// timestamps: false,
|
|
178
|
+
// atomicRename: false,
|
|
179
|
+
// seekableHandles: false
|
|
180
|
+
// }
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
> โ ๏ธ Because it is `static`, read it from the **class**, not the instance:
|
|
184
|
+
> `MyBackend.capabilities`. Inside an instance method, use `this.constructor.capabilities`.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
### 4. ๐ Identity and Permissions
|
|
189
|
+
|
|
190
|
+
The constructor accepts an `FSIdentity`. The `access()` method uses it to decide which permission
|
|
191
|
+
triad applies:
|
|
192
|
+
|
|
193
|
+
| Condition | Triad | Bit shift |
|
|
194
|
+
| --- | --- | --- |
|
|
195
|
+
| `uid === identity.uid` | Owner | `>> 6` |
|
|
196
|
+
| `gid === identity.gid` or in `identity.groups` | Group | `>> 3` |
|
|
197
|
+
| Otherwise | Other | `>> 0` |
|
|
198
|
+
|
|
199
|
+
```javascript
|
|
200
|
+
const fs = new MemoryFileSystem({
|
|
201
|
+
identity: { uid: 1000, gid: 1000, groups: [27, 100] },
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## ๐ API Reference
|
|
208
|
+
|
|
209
|
+
### Constructor
|
|
210
|
+
|
|
211
|
+
```javascript
|
|
212
|
+
new TinyFSCore(options?)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
| Option | Type | Default | Description |
|
|
216
|
+
| --- | --- | --- | --- |
|
|
217
|
+
| `options.cwd` | `string` | `ROOT_PATH` | Working directory used to resolve relative paths. |
|
|
218
|
+
| `options.umask` | `number` | `DEFAULT_UMASK` | Mask applied to `mode` on creation. |
|
|
219
|
+
| `options.identity` | `FSIdentity` | `{ uid: 0, gid: 0, groups: [] }` | Effective identity used by `access()`. |
|
|
220
|
+
|
|
221
|
+
```javascript
|
|
222
|
+
const fs = new MemoryFileSystem({
|
|
223
|
+
cwd: '/srv/app',
|
|
224
|
+
umask: 0o022,
|
|
225
|
+
identity: { uid: 1000, gid: 1000, groups: [] },
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
### Instance Getters
|
|
232
|
+
|
|
233
|
+
```javascript
|
|
234
|
+
fs.cwd; // string โ the configured working directory
|
|
235
|
+
fs.umask; // number โ the configured umask
|
|
236
|
+
fs.identity; // FSIdentity โ the effective identity
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
### Static Members
|
|
242
|
+
|
|
243
|
+
```javascript
|
|
244
|
+
TinyFSCore.capabilities; // Readonly<FSCapabilities>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
### ๐ File Operations
|
|
250
|
+
|
|
251
|
+
#### `readFile(path, options?)`
|
|
252
|
+
|
|
253
|
+
Reads the entire contents of a file.
|
|
254
|
+
|
|
255
|
+
| Parameter | Type | Description |
|
|
256
|
+
| --- | --- | --- |
|
|
257
|
+
| `path` | `string` | Absolute path of the file. |
|
|
258
|
+
| `options.encoding` | `string \| null` | When omitted or `null`, resolves to a `Uint8Array`. |
|
|
259
|
+
|
|
260
|
+
**Returns:** `Promise<string | Uint8Array>`
|
|
261
|
+
|
|
262
|
+
```javascript
|
|
263
|
+
const buffer = await fs.readFile('/data/blob.bin'); // Uint8Array
|
|
264
|
+
const text = await fs.readFile('/data/notes.txt', { encoding: 'utf8' });
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
#### `writeFile(path, data, options?)`
|
|
270
|
+
|
|
271
|
+
Writes data to a file, replacing it when it already exists.
|
|
272
|
+
|
|
273
|
+
| Parameter | Type | Description |
|
|
274
|
+
| --- | --- | --- |
|
|
275
|
+
| `path` | `string` | Absolute path of the file. |
|
|
276
|
+
| `data` | `string \| Uint8Array \| ArrayBuffer` | Payload to persist. |
|
|
277
|
+
| `options.encoding` | `string \| null` | Used to serialise string input. |
|
|
278
|
+
| `options.append` | `boolean` | When `true`, appends instead of replacing. |
|
|
279
|
+
| `options.mode` | `number` | Permission bits applied **when the file is created**. |
|
|
280
|
+
|
|
281
|
+
**Returns:** `Promise<void>`
|
|
282
|
+
|
|
283
|
+
```javascript
|
|
284
|
+
await fs.writeFile('/logs/app.log', 'boot\n', { mode: 0o640 });
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
> โ ๏ธ Metadata is written **only when the file does not exist yet**. Overwriting an existing file
|
|
288
|
+
> preserves its original `mode`, `uid`, `gid` and `birthtimeMs`.
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
#### `appendFile(path, data, options?)`
|
|
293
|
+
|
|
294
|
+
Convenience wrapper around `writeFile` with `append: true`. Creates the file when missing.
|
|
295
|
+
|
|
296
|
+
```javascript
|
|
297
|
+
await fs.appendFile('/logs/app.log', 'request handled\n');
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
#### `copyFile(sourcePath, destinationPath, mode?)`
|
|
303
|
+
|
|
304
|
+
Copies a file and duplicates its metadata record.
|
|
305
|
+
|
|
306
|
+
```javascript
|
|
307
|
+
await fs.copyFile('/a.txt', '/b.txt');
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
> โ ๏ธ **Divergence:** the JSDoc advertises `number | TCopyFileOptions`, but the implementation
|
|
311
|
+
> only honours the `number` form. Passing an object silently resolves to `0`.
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
#### `truncate(path, length?)`
|
|
316
|
+
|
|
317
|
+
Resizes a file to `length` bytes. Shorter files are zero-padded; longer files are cut.
|
|
318
|
+
|
|
319
|
+
```javascript
|
|
320
|
+
await fs.truncate('/data.bin', 1024);
|
|
321
|
+
await fs.truncate('/data.bin'); // length defaults to 0
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
### ๐ Directory Operations
|
|
327
|
+
|
|
328
|
+
#### `readdir(path, options?)`
|
|
329
|
+
|
|
330
|
+
Reads directory entries.
|
|
331
|
+
|
|
332
|
+
| Option | Type | Description |
|
|
333
|
+
| --- | --- | --- |
|
|
334
|
+
| `options.withFileTypes` | `boolean` | When `true`, resolves to `Dirent[]`. |
|
|
335
|
+
| `options.recursive` | `boolean` | When `true`, walks sub-directories depth-first. |
|
|
336
|
+
|
|
337
|
+
**Returns:** `Promise<Array<string | Dirent>>`
|
|
338
|
+
|
|
339
|
+
```javascript
|
|
340
|
+
const names = await fs.readdir('/src');
|
|
341
|
+
const dirents = await fs.readdir('/src', { withFileTypes: true });
|
|
342
|
+
const tree = await fs.readdir('/src', { recursive: true });
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
> โ ๏ธ **Divergence:** in recursive mode, nested entries are always reported with the kind
|
|
346
|
+
> `'file'`, even when they are directories.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
#### `mkdir(path, options?)`
|
|
351
|
+
|
|
352
|
+
Creates a directory.
|
|
353
|
+
|
|
354
|
+
| Option | Type | Description |
|
|
355
|
+
| --- | --- | --- |
|
|
356
|
+
| `options.recursive` | `boolean` | When `true`, missing parents are created. |
|
|
357
|
+
| `options.mode` | `number` | Permission bits for the new directory. |
|
|
358
|
+
|
|
359
|
+
**Returns:** `Promise<string | undefined>` โ the created path when `recursive` is `true`.
|
|
360
|
+
|
|
361
|
+
```javascript
|
|
362
|
+
await fs.mkdir('/var/lib/app', { recursive: true, mode: 0o755 });
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
#### `rm(path, options?)`
|
|
368
|
+
|
|
369
|
+
Removes a file, or a directory tree when `recursive` is `true`.
|
|
370
|
+
|
|
371
|
+
| Option | Type | Description |
|
|
372
|
+
| --- | --- | --- |
|
|
373
|
+
| `options.recursive` | `boolean` | Removes directories and their contents. |
|
|
374
|
+
| `options.force` | `boolean` | When `true`, a missing path is not an error. |
|
|
375
|
+
|
|
376
|
+
```javascript
|
|
377
|
+
await fs.rm('/tmp/cache', { recursive: true, force: true });
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
#### `unlink(path)`
|
|
383
|
+
|
|
384
|
+
Removes a file. Throws `EISDIR` when the path is a directory.
|
|
385
|
+
|
|
386
|
+
```javascript
|
|
387
|
+
await fs.unlink('/tmp/old.log');
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
#### `rmdir(path, options?)`
|
|
393
|
+
|
|
394
|
+
Removes a directory. Forwards to `rm()`.
|
|
395
|
+
|
|
396
|
+
```javascript
|
|
397
|
+
await fs.rmdir('/tmp/empty');
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
#### `rename(oldPath, newPath)`
|
|
403
|
+
|
|
404
|
+
Moves an entry and carries its metadata record across.
|
|
405
|
+
|
|
406
|
+
```javascript
|
|
407
|
+
await fs.rename('/tmp/draft.md', '/docs/final.md');
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
### ๐ท๏ธ Metadata Operations
|
|
413
|
+
|
|
414
|
+
#### `stat(path, options?)`
|
|
415
|
+
|
|
416
|
+
Retrieves a `Stats` snapshot. Throws `ENOENT` when the path is missing.
|
|
417
|
+
|
|
418
|
+
```javascript
|
|
419
|
+
const stats = await fs.stat('/etc/hosts');
|
|
420
|
+
console.log(stats.size, stats.mode.toString(8));
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
#### `lstat(path, options?)`
|
|
426
|
+
|
|
427
|
+
Alias of `stat()`. The base class has no symbolic links, so both behave identically.
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
#### `chmod(path, mode)`
|
|
432
|
+
|
|
433
|
+
Changes the permission bits.
|
|
434
|
+
|
|
435
|
+
```javascript
|
|
436
|
+
await fs.chmod('/usr/local/bin/tool', 0o755);
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
#### `chown(path, uid, gid?)`
|
|
442
|
+
|
|
443
|
+
Changes ownership. `gid` defaults to `uid`.
|
|
444
|
+
|
|
445
|
+
```javascript
|
|
446
|
+
await fs.chown('/var/www', 33, 33);
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
#### `utimes(path, atimeMs, mtimeMs?)`
|
|
452
|
+
|
|
453
|
+
Updates the access and modification times. `mtimeMs` defaults to `atimeMs`.
|
|
454
|
+
|
|
455
|
+
```javascript
|
|
456
|
+
await fs.utimes('/var/log/app.log', Date.now(), Date.now());
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
#### `access(path, mode?)`
|
|
462
|
+
|
|
463
|
+
Checks whether a path is reachable with the requested permission.
|
|
464
|
+
|
|
465
|
+
| Constant | Meaning |
|
|
466
|
+
| --- | --- |
|
|
467
|
+
| `constants.F_OK` | Existence only (default). |
|
|
468
|
+
| `constants.R_OK` | Read permission. |
|
|
469
|
+
| `constants.W_OK` | Write permission. |
|
|
470
|
+
| `constants.X_OK` | Execute permission. |
|
|
471
|
+
|
|
472
|
+
**Throws:** `Error` with `code: 'EACCES'` when the permission is missing.
|
|
473
|
+
|
|
474
|
+
```javascript
|
|
475
|
+
try {
|
|
476
|
+
await fs.access('/etc/shadow', constants.R_OK);
|
|
477
|
+
} catch (error) {
|
|
478
|
+
console.error(error.code); // "EACCES"
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
> โ ๏ธ **Divergence:** `chmod`, `chown` and `utimes` do **not** verify that the path exists.
|
|
483
|
+
> They will happily create an orphan metadata record. Call `stat()` first if that matters.
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
### ๐ฃ๏ธ Path Operations
|
|
488
|
+
|
|
489
|
+
#### `realpath(path)`
|
|
490
|
+
|
|
491
|
+
Resolves the canonical absolute path. Throws `ENOENT` when the path is missing.
|
|
492
|
+
|
|
493
|
+
```javascript
|
|
494
|
+
await fs.realpath('/var/../var/log/./app.log');
|
|
495
|
+
// "/var/log/app.log"
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
#### `exists(path)`
|
|
501
|
+
|
|
502
|
+
Reports whether a path exists. Never throws for a missing path.
|
|
503
|
+
|
|
504
|
+
```javascript
|
|
505
|
+
if (await fs.exists('/etc/hosts')) {
|
|
506
|
+
console.log('found');
|
|
507
|
+
}
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
### ๐ Handles
|
|
513
|
+
|
|
514
|
+
#### `open(path, flags?)`
|
|
515
|
+
|
|
516
|
+
Opens a file and returns a `FileHandle`.
|
|
517
|
+
|
|
518
|
+
| Flag | Behaviour |
|
|
519
|
+
| --- | --- |
|
|
520
|
+
| `'r'` (default) | Verifies the file exists. |
|
|
521
|
+
| `'w'` | Truncates the file. |
|
|
522
|
+
| `'a'` | Opens for appending. |
|
|
523
|
+
|
|
524
|
+
```javascript
|
|
525
|
+
const handle = await fs.open('/data/report.csv', 'w');
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
---
|
|
529
|
+
|
|
530
|
+
## ๐๏ธ Building a Backend
|
|
531
|
+
|
|
532
|
+
A complete, working in-memory backend. This is the smallest useful implementation.
|
|
533
|
+
|
|
534
|
+
```javascript
|
|
535
|
+
import TinyFSCore from 'tiny-essentials/libs/fs/TinyFSCore';
|
|
536
|
+
import { createFileSystemError } from 'tiny-essentials/libs/fs/error.mjs';
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* In-memory file system used for tests and local development.
|
|
540
|
+
* @augments TinyFSCore
|
|
541
|
+
*/
|
|
542
|
+
export class MemoryFileSystem extends TinyFSCore {
|
|
543
|
+
/** @type {Map<string, Uint8Array>} */
|
|
544
|
+
#files = new Map();
|
|
545
|
+
|
|
546
|
+
/** @type {Set<string>} */
|
|
547
|
+
#directories = new Set(['/']);
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* @returns {import('tiny-essentials/libs/fs/TinyFSCore').FSCapabilities} The capabilities of this backend.
|
|
551
|
+
*/
|
|
552
|
+
static get capabilities() {
|
|
553
|
+
return Object.freeze({
|
|
554
|
+
permissions: true,
|
|
555
|
+
ownership: true,
|
|
556
|
+
symlinks: false,
|
|
557
|
+
timestamps: true,
|
|
558
|
+
atomicRename: true,
|
|
559
|
+
seekableHandles: false,
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* @param {string} targetPath Absolute path of the file.
|
|
565
|
+
* @returns {Promise<Uint8Array>} The raw file contents.
|
|
566
|
+
*/
|
|
567
|
+
async _readFile(targetPath) {
|
|
568
|
+
const bytes = this.#files.get(targetPath);
|
|
569
|
+
if (bytes === undefined) {
|
|
570
|
+
throw createFileSystemError('ENOENT', 'open', targetPath);
|
|
571
|
+
}
|
|
572
|
+
return bytes;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* @param {string} targetPath Absolute path of the file.
|
|
577
|
+
* @param {Uint8Array} bytes Payload to persist.
|
|
578
|
+
* @param {{ append: boolean, mode: number | undefined }} options Write options.
|
|
579
|
+
* @returns {Promise<void>} Resolves once the payload is committed.
|
|
580
|
+
*/
|
|
581
|
+
async _writeFile(targetPath, bytes, options) {
|
|
582
|
+
const previous = options.append ? this.#files.get(targetPath) ?? new Uint8Array(0) : new Uint8Array(0);
|
|
583
|
+
const merged = new Uint8Array(previous.length + bytes.length);
|
|
584
|
+
merged.set(previous, 0);
|
|
585
|
+
merged.set(bytes, previous.length);
|
|
586
|
+
this.#files.set(targetPath, merged);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* @param {string} targetPath Absolute path of the directory.
|
|
591
|
+
* @returns {Promise<import('tiny-essentials/libs/fs/stats.mjs').FSDirectoryEntry[]>} The directory entries.
|
|
592
|
+
*/
|
|
593
|
+
async _readdir(targetPath) {
|
|
594
|
+
const prefix = targetPath.endsWith('/') ? targetPath : `${targetPath}/`;
|
|
595
|
+
const entries = new Map();
|
|
596
|
+
|
|
597
|
+
for (const filePath of this.#files.keys()) {
|
|
598
|
+
if (!filePath.startsWith(prefix)) continue;
|
|
599
|
+
const [name, ...rest] = filePath.slice(prefix.length).split('/');
|
|
600
|
+
entries.set(name, { name, kind: rest.length === 0 ? 'file' : 'directory' });
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
return [...entries.values()];
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* @param {string} targetPath Absolute path of the directory.
|
|
608
|
+
* @returns {Promise<void>} Resolves once the directory exists.
|
|
609
|
+
*/
|
|
610
|
+
async _mkdir(targetPath) {
|
|
611
|
+
this.#directories.add(targetPath);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* @param {string} targetPath Absolute path of the entry.
|
|
616
|
+
* @returns {Promise<void>} Resolves once the entry is gone.
|
|
617
|
+
*/
|
|
618
|
+
async _rm(targetPath) {
|
|
619
|
+
this.#files.delete(targetPath);
|
|
620
|
+
this.#directories.delete(targetPath);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* @param {string} targetPath Absolute path of the entry.
|
|
625
|
+
* @returns {Promise<import('tiny-essentials/libs/fs/stats.mjs').FSStatDescriptor | undefined>} The descriptor.
|
|
626
|
+
*/
|
|
627
|
+
async _stat(targetPath) {
|
|
628
|
+
const bytes = this.#files.get(targetPath);
|
|
629
|
+
if (bytes !== undefined) {
|
|
630
|
+
return { name: targetPath.split('/').pop() ?? '', kind: 'file', size: bytes.length, mtimeMs: Date.now() };
|
|
631
|
+
}
|
|
632
|
+
if (this.#directories.has(targetPath)) {
|
|
633
|
+
return { name: targetPath.split('/').pop() ?? '', kind: 'directory', size: 0, mtimeMs: Date.now() };
|
|
634
|
+
}
|
|
635
|
+
return undefined;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* @param {string} oldPath Current absolute path.
|
|
640
|
+
* @param {string} newPath Target absolute path.
|
|
641
|
+
* @returns {Promise<void>} Resolves once the move is complete.
|
|
642
|
+
*/
|
|
643
|
+
async _rename(oldPath, newPath) {
|
|
644
|
+
const bytes = this.#files.get(oldPath);
|
|
645
|
+
if (bytes === undefined) {
|
|
646
|
+
throw createFileSystemError('ENOENT', 'rename', oldPath);
|
|
647
|
+
}
|
|
648
|
+
this.#files.set(newPath, bytes);
|
|
649
|
+
this.#files.delete(oldPath);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* @param {string} sourcePath Absolute path of the source file.
|
|
654
|
+
* @param {string} destinationPath Absolute path of the destination file.
|
|
655
|
+
* @returns {Promise<void>} Resolves once the copy is complete.
|
|
656
|
+
*/
|
|
657
|
+
async _copyFile(sourcePath, destinationPath) {
|
|
658
|
+
const bytes = await this._readFile(sourcePath);
|
|
659
|
+
this.#files.set(destinationPath, Uint8Array.from(bytes));
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
### โ
Backend Checklist
|
|
665
|
+
|
|
666
|
+
1. Extend `TinyFSCore`.
|
|
667
|
+
2. Override `static get capabilities()` and return a frozen object.
|
|
668
|
+
3. Implement only the hooks your use case needs. Everything else throws `ENOSYS`.
|
|
669
|
+
4. **Never** handle encoding, validation or metadata inside a hook. That is the core's job.
|
|
670
|
+
5. Throw `createFileSystemError(code, syscall, path)` instead of a bare `Error`.
|
|
671
|
+
|
|
672
|
+
---
|
|
673
|
+
|
|
674
|
+
## ๐จ Error Codes
|
|
675
|
+
|
|
676
|
+
All errors are created through `createFileSystemError(code, syscall, path, message?)`.
|
|
677
|
+
|
|
678
|
+
| Code | Thrown by | Meaning |
|
|
679
|
+
| --- | --- | --- |
|
|
680
|
+
| `ENOENT` | `stat`, `access`, `realpath`, `open` | No such file or directory. |
|
|
681
|
+
| `EACCES` | `access` | Permission denied. |
|
|
682
|
+
| `EISDIR` | `unlink` | The path is a directory. |
|
|
683
|
+
| `ENOSYS` | Any unoverridden hook | The backend does not implement this operation. |
|
|
684
|
+
|
|
685
|
+
```javascript
|
|
686
|
+
try {
|
|
687
|
+
await fs.readFile('/missing.txt');
|
|
688
|
+
} catch (error) {
|
|
689
|
+
console.error(error.code); // "ENOENT"
|
|
690
|
+
console.error(error.syscall); // "open"
|
|
691
|
+
console.error(error.path); // "/missing.txt"
|
|
692
|
+
}
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
---
|
|
696
|
+
|
|
697
|
+
## โ ๏ธ Known Divergences and Gotchas
|
|
698
|
+
|
|
699
|
+
Read this section before you file a bug. These are the behaviours that differ from
|
|
700
|
+
`node:fs/promises` or from the JSDoc.
|
|
701
|
+
|
|
702
|
+
| # | Location | Behaviour |
|
|
703
|
+
| --- | --- | --- |
|
|
704
|
+
| 1 | `copyFile` | Accepts `TCopyFileOptions` in JSDoc but only honours the `number` form. Passing an object silently resolves to `0`. |
|
|
705
|
+
| 2 | `readdir` | In `recursive` mode, every nested entry is reported with the kind `'file'`. |
|
|
706
|
+
| 3 | `chmod` / `chown` / `utimes` | Do **not** verify that the path exists. They create orphan metadata records. |
|
|
707
|
+
| 4 | `writeFile` | Writes metadata only on creation. Overwriting does **not** refresh `mtimeMs`. |
|
|
708
|
+
| 5 | `rm` | Deletes only the exact path from the metadata map. Descendants keep their records. |
|
|
709
|
+
| 6 | `lstat` | Alias of `stat`. There is no symlink support in the base class. |
|
|
710
|
+
| 7 | `capabilities` | It is `static`. Use `this.constructor.capabilities` inside instance methods. |
|
|
711
|
+
| 8 | `__stat` | Public by convention only. It is the internal implementation behind `stat`. |
|
|
712
|
+
| 9 | `unlink` | Calls `__stat` first, so a missing file throws `ENOENT` before `rm` runs. |
|
|
713
|
+
|
|
714
|
+
---
|
|
715
|
+
|
|
716
|
+
## ๐งพ Cheatsheet
|
|
717
|
+
|
|
718
|
+
```javascript
|
|
719
|
+
// โโโ Setup โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
720
|
+
const fs = new MemoryFileSystem({ cwd: '/app', umask: 0o022 });
|
|
721
|
+
|
|
722
|
+
// โโโ Files โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
723
|
+
await fs.writeFile('/a.txt', 'data', { encoding: 'utf8' });
|
|
724
|
+
await fs.appendFile('/a.txt', 'more');
|
|
725
|
+
const buffer = await fs.readFile('/a.txt'); // Uint8Array
|
|
726
|
+
const text = await fs.readFile('/a.txt', { encoding: 'utf8' });
|
|
727
|
+
await fs.copyFile('/a.txt', '/b.txt');
|
|
728
|
+
await fs.truncate('/a.txt', 2);
|
|
729
|
+
await fs.unlink('/a.txt');
|
|
730
|
+
|
|
731
|
+
// โโโ Directories โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
732
|
+
await fs.mkdir('/nested/dir', { recursive: true, mode: 0o755 });
|
|
733
|
+
const names = await fs.readdir('/nested');
|
|
734
|
+
const dirents = await fs.readdir('/nested', { withFileTypes: true });
|
|
735
|
+
await fs.rmdir('/nested');
|
|
736
|
+
await fs.rm('/nested', { recursive: true, force: true });
|
|
737
|
+
|
|
738
|
+
// โโโ Metadata โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
739
|
+
const stats = await fs.stat('/a.txt');
|
|
740
|
+
await fs.chmod('/a.txt', 0o600);
|
|
741
|
+
await fs.chown('/a.txt', 1000, 1000);
|
|
742
|
+
await fs.utimes('/a.txt', Date.now(), Date.now());
|
|
743
|
+
await fs.access('/a.txt', 0o4);
|
|
744
|
+
|
|
745
|
+
// โโโ Paths โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
746
|
+
await fs.rename('/a.txt', '/b.txt');
|
|
747
|
+
const absolute = await fs.realpath('/a/../a.txt');
|
|
748
|
+
const found = await fs.exists('/a.txt');
|
|
749
|
+
|
|
750
|
+
// โโโ Handles โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
751
|
+
const handle = await fs.open('/a.txt', 'w');
|
|
752
|
+
```
|