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,569 @@
|
|
|
1
|
+
# 🎨 ProcessSolidFilters
|
|
2
|
+
|
|
3
|
+
> Extract solid colors from PSD layers, generate separated images per filter, and get pixel statistics — in **Node.js** and the **Browser**, with the exact same API.
|
|
4
|
+
|
|
5
|
+
[](#-nodejs-usage)
|
|
6
|
+
[](#-browser-usage)
|
|
7
|
+
[](#-how-it-works)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 📖 Table of Contents
|
|
12
|
+
|
|
13
|
+
1. [What is this?](#-what-is-this)
|
|
14
|
+
2. [✨ Features](#-features)
|
|
15
|
+
3. [🧠 How It Works](#-how-it-works)
|
|
16
|
+
4. [📦 Installation](#-installation)
|
|
17
|
+
5. [🚀 Quick Start](#-quick-start)
|
|
18
|
+
- [Node.js Usage](#-nodejs-usage)
|
|
19
|
+
- [Browser Usage](#-browser-usage)
|
|
20
|
+
- [Browser File Input Usage](#-browser-file-input-usage)
|
|
21
|
+
6. [🎯 Filter Criteria (Matching Rules)](#-filter-criteria-matching-rules)
|
|
22
|
+
7. [📂 Folder Matching](#-folder-matching)
|
|
23
|
+
8. [🧩 API Reference](#-api-reference)
|
|
24
|
+
9. [📊 Understanding the Result](#-understanding-the-result)
|
|
25
|
+
10. [🍳 Recipes & Daily Workflow](#-recipes--daily-workflow)
|
|
26
|
+
11. [🔒 Validation & Error Handling](#-validation--error-handling)
|
|
27
|
+
12. [🐛 Troubleshooting](#-troubleshooting)
|
|
28
|
+
13. [🧱 Extending the Library](#-extending-the-library)
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 🤔 What is this?
|
|
33
|
+
|
|
34
|
+
`ProcessSolidFilters` is a **dependency-injected factory** that reads a `.psd` file, walks through every visible layer **from bottom to top**, and paints a "solid color map" where each pixel is colored according to the **filter** that claimed the layer.
|
|
35
|
+
|
|
36
|
+
Think of it as a **paint-by-numbers engine**:
|
|
37
|
+
|
|
38
|
+
- 🖌️ Each **filter** you define owns one color.
|
|
39
|
+
- 🧱 Layers are processed in **painting order** (bottom → top).
|
|
40
|
+
- 🏆 When two layers overlap, the **top one wins**.
|
|
41
|
+
- 📂 Filters can claim an entire **folder** at once, with configurable subfolder behavior.
|
|
42
|
+
- 🗂️ You get back a **full composite**, one **image per filter**, **pixel statistics**, and **vector metadata** for every layer.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## ✨ Features
|
|
47
|
+
|
|
48
|
+
| Feature | Description |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| 🌍 **Universal** | One core, three runtimes: Node.js, Browser (URL/Blob), Browser (File Input). |
|
|
51
|
+
| 🎨 **Solid Color Extraction** | Every matched layer is flattened into a single solid color. |
|
|
52
|
+
| 🧮 **Pixel Statistics** | Know exactly how many pixels each filter claimed. |
|
|
53
|
+
| 📐 **Vector Metadata** | Get the bounding box, opacity, and name of every layer. |
|
|
54
|
+
| 🧩 **Composable Filters** | Combine `startsWith`, `endsWith`, `contains`, `equals`, `matches`, and custom `test`. |
|
|
55
|
+
| 📂 **Folder-Aware Matching** | Claim a whole folder at once, with per-subfolder strategies. |
|
|
56
|
+
| 🛡️ **Strict Validation** | Every public function throws `TypeError` or `Error` on invalid input. |
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 🧠 How It Works
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
┌────────────────┐ ┌──────────────────┐ ┌────────────────────┐
|
|
64
|
+
│ PSD File │ ──▶ │ Walk Layer Tree │ ──▶ │ Match Each Node │
|
|
65
|
+
│ (ag-psd) │ │ (bottom → top) │ │ against filters │
|
|
66
|
+
└────────────────┘ └──────────────────┘ └─────────┬──────────┘
|
|
67
|
+
│
|
|
68
|
+
▼
|
|
69
|
+
┌────────────────┐ ┌──────────────────┐ ┌────────────────────┐
|
|
70
|
+
│ Results │ ◀── │ Paint ownerMap │ ◀── │ Read Pixel Alpha │
|
|
71
|
+
│ (4 outputs) │ │ (W × H array) │ │ (threshold > 1) │
|
|
72
|
+
└────────────────┘ └──────────────────┘ └────────────────────┘
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
1. **Read** the PSD into a raw buffer.
|
|
76
|
+
2. **Walk** the layer tree recursively, keeping only visible layers in painting order.
|
|
77
|
+
3. **Match** each layer name against your filters (first match wins).
|
|
78
|
+
4. **Claim** every layer inside a matched folder, honoring its subfolder strategy.
|
|
79
|
+
5. **Paint** the `ownerMap`: each pixel stores the `id` of the filter that owns it.
|
|
80
|
+
6. **Export** the composite image, one image per filter, stats, and vector data.
|
|
81
|
+
|
|
82
|
+
> 💡 **Why a flat `ownerMap`?** It's a single `Array<W * H>` of strings. It's cache-friendly, easy to reason about, and lets us do a single pass at the end to build every output image.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 📦 Installation
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npm install ag-psd
|
|
90
|
+
# Node.js only:
|
|
91
|
+
npm install canvas
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
> ⚠️ The `canvas` package is a **peer dependency for Node.js only**. Browsers use the native `<canvas>`.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 🚀 Quick Start
|
|
99
|
+
|
|
100
|
+
### 🟢 Node.js Usage
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
import { processPsdSolidFilters } from 'tiny-essentials/webTemplates/ag-psd/31.0/ProcessSolidFilters';
|
|
104
|
+
import { writeFile } from 'fs/promises';
|
|
105
|
+
|
|
106
|
+
const result = await processPsdSolidFilters(
|
|
107
|
+
'./artwork.psd',
|
|
108
|
+
[
|
|
109
|
+
{ id: 'artist1', color: '#FF0000', startsWith: 'Artist1_' },
|
|
110
|
+
{ id: 'artist2', color: '#00FF00', startsWith: 'Artist2_' },
|
|
111
|
+
],
|
|
112
|
+
{ color: '#0000FF' }, // fallback for everything else
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
// Save the full composite
|
|
116
|
+
await writeFile('output/full.png', result.fullImageBuffer);
|
|
117
|
+
|
|
118
|
+
// Save each separated image
|
|
119
|
+
for (const { id, buffer } of result.separatedImages) {
|
|
120
|
+
await writeFile(`output/${id}.png`, buffer);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
console.log('📊 Stats:', result.stats);
|
|
124
|
+
console.log('📐 Layers:', result.vectorData.length);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
### 🌐 Browser Usage
|
|
130
|
+
|
|
131
|
+
```javascript
|
|
132
|
+
import { processPsdSolidFilters } from 'tiny-essentials/webTemplates/ag-psd/31.0/ProcessSolidFilters/Browser';
|
|
133
|
+
|
|
134
|
+
const result = await processPsdSolidFilters(
|
|
135
|
+
'https://example.com/artwork.psd', // URL or Blob
|
|
136
|
+
[{ id: 'lineart', color: '#000000', contains: 'line' }],
|
|
137
|
+
{ color: '#FFFFFF' },
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
// `result.fullImageBuffer` is a Blob in the browser
|
|
141
|
+
const url = URL.createObjectURL(result.fullImageBuffer);
|
|
142
|
+
document.querySelector('img').src = url;
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
### 📁 Browser File Input Usage
|
|
148
|
+
|
|
149
|
+
Perfect for drag-and-drop or `<input type="file">`:
|
|
150
|
+
|
|
151
|
+
```html
|
|
152
|
+
<input type="file" id="psd-input" accept=".psd" />
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```javascript
|
|
156
|
+
import { processPsdSolidFiltersFromFile } from 'tiny-essentials/webTemplates/ag-psd/31.0/ProcessSolidFilters/FileInput';
|
|
157
|
+
|
|
158
|
+
const input = document.getElementById('psd-input');
|
|
159
|
+
|
|
160
|
+
input.addEventListener('change', async () => {
|
|
161
|
+
const result = await processPsdSolidFiltersFromFile(
|
|
162
|
+
input, // pass the HTMLInputElement directly ✨
|
|
163
|
+
[{ id: 'background', color: '#CCCCCC', equals: 'Background' }],
|
|
164
|
+
{ color: '#FF00FF' },
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
console.log('Done!', result.stats);
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 🎯 Filter Criteria (Matching Rules)
|
|
174
|
+
|
|
175
|
+
Every filter can combine **multiple criteria**. All criteria inside a single filter are combined with **AND**. Values inside a single criterion are combined with **OR**.
|
|
176
|
+
|
|
177
|
+
| Property | Type | Description |
|
|
178
|
+
| --- | --- | --- |
|
|
179
|
+
| `id` | `string` | **Required.** Unique identifier for the filter. |
|
|
180
|
+
| `color` | `string` | **Required.** HEX color (e.g., `#FF0000`). |
|
|
181
|
+
| `startsWith` | `string \| string[]` | Layer name must start with the value(s). |
|
|
182
|
+
| `endsWith` | `string \| string[]` | Layer name must end with the value(s). |
|
|
183
|
+
| `contains` | `string \| string[]` | Layer name must contain the value(s). |
|
|
184
|
+
| `equals` | `string \| string[]` | Layer name must be exactly equal to the value(s). |
|
|
185
|
+
| `matches` | `RegExp \| RegExp[]` | Layer name must match the RegExp(s). |
|
|
186
|
+
| `test` | `(name: string) => boolean` | Custom predicate for advanced matching. |
|
|
187
|
+
| `folder` | `boolean \| FolderOptions` | When enabled, the filter also claims folders. See [Folder Matching](#-folder-matching). |
|
|
188
|
+
|
|
189
|
+
### 🧪 Example: Combining criteria
|
|
190
|
+
|
|
191
|
+
```javascript
|
|
192
|
+
{
|
|
193
|
+
id: 'skin',
|
|
194
|
+
color: '#F5CBA7',
|
|
195
|
+
startsWith: ['Skin_', 'Face_'], // OR
|
|
196
|
+
contains: 'final', // AND
|
|
197
|
+
}
|
|
198
|
+
// Matches: "Skin_final", "Face_final", "Skin_final_v2"
|
|
199
|
+
// Rejects: "Skin_draft", "Face", "final"
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
> ⚠️ **Avoid the global flag (`/g`)** in `matches`. RegExp objects with `/g` are **stateful** (they remember `lastIndex`), which causes bugs across multiple layers. Use `/pattern/i` instead of `/pattern/gi`.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 📂 Folder Matching
|
|
207
|
+
|
|
208
|
+
By default, filters only match **leaf layers**. Enable the `folder` option to let a filter claim an **entire folder** — every layer inside it inherits the filter's color.
|
|
209
|
+
|
|
210
|
+
```javascript
|
|
211
|
+
{
|
|
212
|
+
id: 'character',
|
|
213
|
+
color: '#FF0000',
|
|
214
|
+
equals: 'Character', // matches the folder named "Character"
|
|
215
|
+
folder: true, // shorthand for { subfolders: 'inherit' }
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Subfolder strategies
|
|
220
|
+
|
|
221
|
+
The `folder` option accepts a `FolderOptions` object to control what happens with **nested folders**:
|
|
222
|
+
|
|
223
|
+
| `subfolders` | Behavior |
|
|
224
|
+
| --- | --- |
|
|
225
|
+
| `'inherit'` *(default)* | Every subfolder inherits the parent filter. The whole tree gets the same color. |
|
|
226
|
+
| `'exclude'` | Only the layers **directly** inside the folder are claimed. Subfolders fall back to the outer scope. |
|
|
227
|
+
| `'custom'` | Subfolders are matched against `childFilter` instead. |
|
|
228
|
+
|
|
229
|
+
### Example: three strategies
|
|
230
|
+
|
|
231
|
+
```javascript
|
|
232
|
+
const filters = [
|
|
233
|
+
// 1. Whole folder, subfolders inherit the same filter
|
|
234
|
+
{
|
|
235
|
+
id: 'character',
|
|
236
|
+
color: '#FF0000',
|
|
237
|
+
equals: 'Character',
|
|
238
|
+
folder: true,
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
// 2. Whole folder, but subfolders are ignored
|
|
242
|
+
{
|
|
243
|
+
id: 'background',
|
|
244
|
+
color: '#00FF00',
|
|
245
|
+
equals: 'Background',
|
|
246
|
+
folder: { subfolders: 'exclude' },
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
// 3. Subfolders use their own nested filters
|
|
250
|
+
{
|
|
251
|
+
id: 'ui',
|
|
252
|
+
color: '#0000FF',
|
|
253
|
+
equals: 'UI',
|
|
254
|
+
folder: {
|
|
255
|
+
subfolders: 'custom',
|
|
256
|
+
childFilter: [
|
|
257
|
+
{ id: 'ui-buttons', color: '#FFFF00', equals: 'buttons', folder: true },
|
|
258
|
+
{ id: 'ui-icons', color: '#FF00FF', equals: 'icons', folder: true },
|
|
259
|
+
],
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
];
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
> 💡 **Order matters.** Filters are evaluated top to bottom, and the **first match wins**. Folder filters are resolved before descending into their children, so they take priority over layer filters.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## 🧩 API Reference
|
|
270
|
+
|
|
271
|
+
### 🏭 `createProcessPsdSolidFilters(validator, createCanvas, readPsd, exportCanvas)`
|
|
272
|
+
|
|
273
|
+
The factory. It returns the actual `processPsdSolidFilters` function, wired to a specific environment.
|
|
274
|
+
|
|
275
|
+
| Parameter | Type | Description |
|
|
276
|
+
| --- | --- | --- |
|
|
277
|
+
| `validator` | `(input) => Promise<Buffer \| ArrayBuffer>` | Converts the input into a raw buffer. |
|
|
278
|
+
| `createCanvas` | `(w, h) => Canvas` | Creates a canvas in the target environment. |
|
|
279
|
+
| `readPsd` | `typeof import('ag-psd').readPsd` | The `readPsd` function from `ag-psd`. |
|
|
280
|
+
| `exportCanvas` | `(canvas) => Promise<Blob \| Buffer>` | Serializes a canvas to PNG. |
|
|
281
|
+
|
|
282
|
+
**Returns:** `processPsdSolidFilters(psdInput, filters, defaultConfig)`
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
### 🎛️ `processPsdSolidFilters(psdInput, filters, defaultConfig)`
|
|
287
|
+
|
|
288
|
+
| Parameter | Type | Description |
|
|
289
|
+
| --- | --- | --- |
|
|
290
|
+
| `psdInput` | `string \| Blob \| HTMLInputElement` | The PSD source (environment-dependent). |
|
|
291
|
+
| `filters` | `FilterConfig[]` | The list of filters to apply. |
|
|
292
|
+
| `defaultConfig` | `DefaultConfig` | Fallback color for unmatched layers. |
|
|
293
|
+
|
|
294
|
+
**Returns:** `Promise<ProcessedPsdResult<Data>>`
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
### 🧾 Type Definitions
|
|
299
|
+
|
|
300
|
+
#### `FilterConfig`
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
interface FilterConfig {
|
|
304
|
+
id: string;
|
|
305
|
+
color: string;
|
|
306
|
+
startsWith?: string | string[];
|
|
307
|
+
endsWith?: string | string[];
|
|
308
|
+
contains?: string | string[];
|
|
309
|
+
equals?: string | string[];
|
|
310
|
+
matches?: RegExp | RegExp[];
|
|
311
|
+
test?: (layerName: string) => boolean;
|
|
312
|
+
folder?: boolean | FolderOptions;
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
#### `FolderOptions`
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
interface FolderOptions {
|
|
320
|
+
/** How nested folders are handled. Defaults to 'inherit'. */
|
|
321
|
+
subfolders?: 'inherit' | 'exclude' | 'custom';
|
|
322
|
+
/** Nested filters used when 'subfolders' is 'custom'. */
|
|
323
|
+
childFilter?: FilterConfig | FilterConfig[];
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
#### `DefaultConfig`
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
interface DefaultConfig {
|
|
331
|
+
color: string; // HEX color for unmatched layers
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
#### `ProcessedPsdResult<Data>`
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
interface ProcessedPsdResult<Data> {
|
|
339
|
+
fullImageBuffer: Data;
|
|
340
|
+
separatedImages: Array<{ id: string; buffer: Data }>;
|
|
341
|
+
stats: Record<string, number>;
|
|
342
|
+
vectorData: LayerVectorData[];
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
#### `LayerVectorData`
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
interface LayerVectorData {
|
|
350
|
+
name: string;
|
|
351
|
+
filterId: string;
|
|
352
|
+
opacity: number; // 0 to 1
|
|
353
|
+
bounds: VectorBounds;
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
#### `VectorBounds`
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
interface VectorBounds {
|
|
361
|
+
x: number;
|
|
362
|
+
y: number;
|
|
363
|
+
width: number;
|
|
364
|
+
height: number;
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## 📊 Understanding the Result
|
|
371
|
+
|
|
372
|
+
Given this input:
|
|
373
|
+
|
|
374
|
+
```javascript
|
|
375
|
+
const result = await processPsdSolidFilters('file.psd', [
|
|
376
|
+
{ id: 'a', color: '#FF0000', startsWith: 'A_' },
|
|
377
|
+
], { color: '#0000FF' });
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
You get:
|
|
381
|
+
|
|
382
|
+
```javascript
|
|
383
|
+
{
|
|
384
|
+
fullImageBuffer: Blob, // 🖼️ The complete composite
|
|
385
|
+
separatedImages: [ // 🗂️ One image per filter
|
|
386
|
+
{ id: 'unfiltered', buffer: Blob },
|
|
387
|
+
{ id: 'a', buffer: Blob },
|
|
388
|
+
],
|
|
389
|
+
stats: { // 🧮 Pixel counts
|
|
390
|
+
unclaimed: 1024, // Pixels with no layer
|
|
391
|
+
unfiltered: 2048, // Pixels claimed by the fallback
|
|
392
|
+
a: 51200, // Pixels claimed by filter "a"
|
|
393
|
+
},
|
|
394
|
+
vectorData: [ // 📐 One entry per processed layer
|
|
395
|
+
{
|
|
396
|
+
name: 'A_background',
|
|
397
|
+
filterId: 'a',
|
|
398
|
+
opacity: 1,
|
|
399
|
+
bounds: { x: 0, y: 0, width: 1920, height: 1080 },
|
|
400
|
+
},
|
|
401
|
+
],
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
> 💡 **`unclaimed`** = pixels where no layer painted anything (transparent in the PSD).
|
|
406
|
+
> **`unfiltered`** = pixels claimed by a layer that matched **no** filter (fallback color).
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## 🍳 Recipes & Daily Workflow
|
|
411
|
+
|
|
412
|
+
### 🎨 Recipe 1: Assign a color per artist
|
|
413
|
+
|
|
414
|
+
```javascript
|
|
415
|
+
const filters = ['alice', 'bob', 'carol'].map((name, i) => ({
|
|
416
|
+
id: name,
|
|
417
|
+
color: ['#FF0000', '#00FF00', '#0000FF'][i],
|
|
418
|
+
startsWith: `${name}_`,
|
|
419
|
+
}));
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### 📂 Recipe 2: Color an entire folder, but keep subfolders separate
|
|
423
|
+
|
|
424
|
+
```javascript
|
|
425
|
+
const filters = [
|
|
426
|
+
{
|
|
427
|
+
id: 'character',
|
|
428
|
+
color: '#FF0000',
|
|
429
|
+
equals: 'Character',
|
|
430
|
+
folder: { subfolders: 'custom', childFilter: [] }, // empty = subfolders stay unfiltered
|
|
431
|
+
},
|
|
432
|
+
];
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### 🔍 Recipe 3: Debug which layer went where
|
|
436
|
+
|
|
437
|
+
```javascript
|
|
438
|
+
for (const layer of result.vectorData) {
|
|
439
|
+
console.log(`📐 ${layer.name} → ${layer.filterId} (opacity: ${layer.opacity})`);
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### 📉 Recipe 4: Detect empty filters
|
|
444
|
+
|
|
445
|
+
```javascript
|
|
446
|
+
for (const [id, count] of Object.entries(result.stats)) {
|
|
447
|
+
if (count === 0) console.warn(`⚠️ Filter "${id}" matched no pixels!`);
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### 🖼️ Recipe 5: Convert a Blob to a data URL (browser)
|
|
452
|
+
|
|
453
|
+
```javascript
|
|
454
|
+
const toDataURL = (blob) =>
|
|
455
|
+
new Promise((resolve) => {
|
|
456
|
+
const reader = new FileReader();
|
|
457
|
+
reader.onload = () => resolve(reader.result);
|
|
458
|
+
reader.readAsDataURL(blob);
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
const dataURL = await toDataURL(result.fullImageBuffer);
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
## 🔒 Validation & Error Handling
|
|
467
|
+
|
|
468
|
+
The library is **defensive by design**. Every public entry point validates its arguments and throws a **specific** error.
|
|
469
|
+
|
|
470
|
+
| Scenario | Error Type |
|
|
471
|
+
| --- | --- |
|
|
472
|
+
| `filters` is not an array | `TypeError` |
|
|
473
|
+
| `defaultConfig.color` is missing | `Error` |
|
|
474
|
+
| A filter has no `id` | `TypeError` |
|
|
475
|
+
| A filter has no matching criteria | `TypeError` |
|
|
476
|
+
| `folder.subfolders` is not `'inherit' \| 'exclude' \| 'custom'` | `TypeError` |
|
|
477
|
+
| Invalid HEX color | `Error` |
|
|
478
|
+
| File not found (Node.js) | `Error` |
|
|
479
|
+
| Wrong input type for the environment | `TypeError` |
|
|
480
|
+
|
|
481
|
+
**Always wrap calls in `try/catch`:**
|
|
482
|
+
|
|
483
|
+
```javascript
|
|
484
|
+
try {
|
|
485
|
+
const result = await processPsdSolidFilters(input, filters, { color: '#FFF' });
|
|
486
|
+
} catch (error) {
|
|
487
|
+
if (error instanceof TypeError) {
|
|
488
|
+
console.error('❌ Invalid argument:', error.message);
|
|
489
|
+
} else {
|
|
490
|
+
console.error('💥 Runtime error:', error.message);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## 🐛 Troubleshooting
|
|
498
|
+
|
|
499
|
+
<details>
|
|
500
|
+
<summary><strong>❓ My layers are not being matched</strong></summary>
|
|
501
|
+
|
|
502
|
+
- Check for **invisible characters** or **trailing spaces** in layer names.
|
|
503
|
+
- Remember: `startsWith`, `endsWith`, `contains`, and `equals` are **case-sensitive**.
|
|
504
|
+
- Use a `test` predicate to debug:
|
|
505
|
+
|
|
506
|
+
```javascript
|
|
507
|
+
{ id: 'debug', color: '#000', test: (name) => {
|
|
508
|
+
console.log('🔍', JSON.stringify(name));
|
|
509
|
+
return false;
|
|
510
|
+
}}
|
|
511
|
+
```
|
|
512
|
+
</details>
|
|
513
|
+
|
|
514
|
+
<details>
|
|
515
|
+
<summary><strong>❓ My folder filter is not claiming the layers inside it</strong></summary>
|
|
516
|
+
|
|
517
|
+
- Make sure `folder` is set to `true` or an object — omitting it disables folder matching.
|
|
518
|
+
- Confirm the folder name matches your criterion (e.g., `equals: 'Character'`).
|
|
519
|
+
- Check the `subfolders` strategy. With `'exclude'`, nested folders are **not** claimed.
|
|
520
|
+
- Verify the folder is **visible**. Hidden folders (`layer.hidden === true`) are skipped entirely.
|
|
521
|
+
</details>
|
|
522
|
+
|
|
523
|
+
<details>
|
|
524
|
+
<summary><strong>❓ The output image is fully transparent</strong></summary>
|
|
525
|
+
|
|
526
|
+
- The PSD might have all layers hidden (`layer.hidden === true`).
|
|
527
|
+
- The document dimensions might be `0 × 0`.
|
|
528
|
+
- Check `result.stats.unclaimed` — if it equals `W * H`, no layer painted anything.
|
|
529
|
+
</details>
|
|
530
|
+
|
|
531
|
+
<details>
|
|
532
|
+
<summary><strong>❓ Node.js throws "Cannot find module 'canvas'"</strong></summary>
|
|
533
|
+
|
|
534
|
+
Install the peer dependency:
|
|
535
|
+
|
|
536
|
+
```bash
|
|
537
|
+
npm install canvas
|
|
538
|
+
```
|
|
539
|
+
</details>
|
|
540
|
+
|
|
541
|
+
<details>
|
|
542
|
+
<summary><strong>❓ My RegExp filter behaves inconsistently</strong></summary>
|
|
543
|
+
|
|
544
|
+
You are probably using the `/g` flag. Remove it. RegExp objects with `/g` are **stateful** and will alternate between `true` and `false` on the same input.
|
|
545
|
+
</details>
|
|
546
|
+
|
|
547
|
+
---
|
|
548
|
+
|
|
549
|
+
## 🧱 Extending the Library
|
|
550
|
+
|
|
551
|
+
Because the core is a **factory**, you can add a new runtime in ~20 lines. Here's a Deno example:
|
|
552
|
+
|
|
553
|
+
```javascript
|
|
554
|
+
import { readPsd } from 'npm:ag-psd';
|
|
555
|
+
import { createProcessPsdSolidFilters } from './Template.mjs';
|
|
556
|
+
|
|
557
|
+
export const processPsdSolidFilters = createProcessPsdSolidFilters(
|
|
558
|
+
async (path) => Deno.readFile(path),
|
|
559
|
+
(w, h) => new OffscreenCanvas(w, h),
|
|
560
|
+
readPsd,
|
|
561
|
+
(canvas) => canvas.convertToBlob({ type: 'image/png' }),
|
|
562
|
+
);
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
The only contract is:
|
|
566
|
+
|
|
567
|
+
1. `validator` returns a `Buffer` or `ArrayBuffer`.
|
|
568
|
+
2. `createCanvas(w, h)` returns a canvas-like object.
|
|
569
|
+
3. `exportCanvas(canvas)` returns a `Promise<Blob | Buffer>`.
|