diff --git a/README.md b/README.md index d18aaac..c2cc2f6 100755 --- a/README.md +++ b/README.md @@ -155,6 +155,23 @@ configure(mappedMounted, { log: 'enabled' }); configure([$data, loadDataFx], { log: 'enabled' }); ``` +### Whitelist mode + +If you wan't to disable logs by default and only log necessary units, you can use `mode` option of `attachLogger` + +```ts +import { createEvent } from 'effector'; +import { configure, attachLogger } from 'effector-logger'; + +// In whitelist mode, units don't log by default +attachLogger({ mode: 'whitelist' }) + +const pageMounted = createEvent(); + +// Enable logging for a specific unit +configure(pageMounted, { log: 'enabled' }); +``` + ## Redux DevTools support Redux DevTools is moved to a different package. diff --git a/src/basic.test.ts b/src/basic.test.ts index 4cfc0bc..51f5ec8 100644 --- a/src/basic.test.ts +++ b/src/basic.test.ts @@ -509,4 +509,63 @@ describe('logger tests', () => { unlogger(); }); }); + + test('configure can log whitelisted entities', () => { + const $abc = createStore(0); + const inc = createEvent(); + $abc.on(inc, (state) => state + 1); + const myFx = createEffect(() => 42); + sample({ + clock: inc, + target: myFx, + }); + + const derivedInc = inc.map((x) => 'LOGGED!!!!'); + + const logged = vi.fn(); + + vi.stubGlobal('console', { + log: logged, + warn: logged, + error: logged, + info: logged, + group: logged, + groupEnd: logged, + groupCollapsed: logged, + }); + + // Whitelist 'inc' logs + configure(inc, { log: 'enabled' }); + + const unlogger = attachLogger({ mode: 'whitelist' }); + + inc(); + + // Only inc event should be logged + expect(logged.mock.calls.length).toBe(1); // single update of derivedInc + expect(logged.mock.calls).toMatchInlineSnapshot(` + [ + [ + "%c%s%c  %c%s%c  %c%s%c  %c%o  %c%s  %c%s", + "padding-left: 4px; padding-right: 4px; font-weight: normal; line-height:1.5; color: #000; font-family: \\"Apple Emoji Font\\"; font-weight: normal !important;", + "☄️", + "padding-left: 4px; padding-right: 4px; font-weight: normal; line-height:1.5; color: #000; font-family: \\"Apple Emoji Font\\"; font-weight: normal !important;", + "padding-left: 4px; padding-right: 4px; font-weight: normal; font-family: Menlo, monospace;", + "effector", + "padding-left: 4px; padding-right: 4px; font-weight: normal; font-family: Menlo, monospace;", + "padding-left: 4px; padding-right: 4px; font-weight: normal; background-color: #9ccc65; color: #000", + "73", + "color: currentColor; background-color: transparent;", + "padding-left: 4px; padding-right: 4px; font-weight: normal; padding-left: 4px;", + undefined, + "padding-left: 4px; padding-right: 4px; font-weight: normal; color: #9e9e9e; padding-left: 20px;", + "", + "padding-left: 4px; padding-right: 4px; font-weight: normal; color: #9e9e9e; padding-left: 20px;", + "73", + ], + ] + `); + + unlogger(); + }); }); diff --git a/src/index.ts b/src/index.ts index c8b4024..bfe108f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,8 +18,14 @@ import { getNode, getName, locToString } from './lib'; const ignored = new Set(); const forceLog = new Set(); const fxRunning = new Map(); +let defaultMode = 'blacklist'; + +export function attachLogger( + config: { scope?: Scope; name?: string; mode?: 'blacklist' | 'whitelist' } = {}, +): () => void { + // update mode if provided + const mode = config.mode || defaultMode; -export function attachLogger(config: { scope?: Scope; name?: string } = {}): () => void { const name = config.name || (config.scope ? `scope: ${getNode(config.scope).id}` : ''); const logDeclarations = createDeclarationsLogger({ @@ -30,17 +36,14 @@ export function attachLogger(config: { scope?: Scope; name?: string } = {}): () const uninspect = inspect({ scope: config.scope || undefined, fn: (m) => { - if ( - /** - * Log only non-derived units by default - */ - (isLoggable(m) && !ignored.has(m.id)) || - /** - * Log any units if they are forced to be logged - */ - forceLog.has(m.id) - ) { - log(m, name); + if (mode === 'blacklist') { + if ((isLoggable(m) && !ignored.has(m.id)) || forceLog.has(m.id)) { + log(m, name); + } + } else if (mode === 'whitelist') { + if (forceLog.has(m.id)) { + log(m, name); + } } }, }); @@ -68,18 +71,22 @@ export function configure( if (config.log === 'disabled') { units.forEach((unit) => { ignored.add(getNode(unit).id); + forceLog.delete(getNode(unit).id); if (is.effect(unit)) { ignored.add(getNode(unit.finally).id); + forceLog.delete(getNode(unit.finally).id); } }); } if (config.log === 'enabled') { units.forEach((unit) => { forceLog.add(getNode(unit).id); + ignored.delete(getNode(unit).id); if (is.effect(unit)) { forceLog.add(getNode(unit.finally).id); + ignored.delete(getNode(unit.finally).id); } }); }