diff --git a/packages/svelte/messages/client-warnings/warnings.md b/packages/svelte/messages/client-warnings/warnings.md index 4266f75184..2baf88432a 100644 --- a/packages/svelte/messages/client-warnings/warnings.md +++ b/packages/svelte/messages/client-warnings/warnings.md @@ -4,6 +4,10 @@ > `%binding%` (%location%) is binding to a non-reactive property +## enable_custom_formatters + +> We recommend enabling custom formatters for better results when logging `$state` objects — in your devtools, click the gear icon and check the 'Custom formatters' box + ## event_handler_invalid > %handler% should be a function. Did you mean to %suggestion%? diff --git a/packages/svelte/src/internal/client/dev/log.js b/packages/svelte/src/internal/client/dev/log.js index 0e5c028896..d076d7634a 100644 --- a/packages/svelte/src/internal/client/dev/log.js +++ b/packages/svelte/src/internal/client/dev/log.js @@ -1,43 +1,43 @@ import { STATE_SYMBOL } from '../constants.js'; +import { VERSION } from '../../../version.js'; +import { snapshot } from '../../shared/clone.js'; +import * as w from '../warnings.js'; -export function monkey_patch_console() { - for (const method of Object.keys(console)) { - // @ts-expect-error - const original = console[method]; +export function install_custom_formatter() { + // Custom formatters are 'supported' in Firefox, but they're worse than useless. + // They're not supported in Firefox. We can maybe tweak this over time + var is_chrome = navigator.userAgent.includes('Chrome'); + var custom_formatters_enabled = false; + if (is_chrome) { // @ts-expect-error - console[method] = (...args) => { - for (const arg of args) { - if (contains_state_proxy(arg)) { - // TODO make this a proper warning - console.warn('contains state proxy!!!!'); - break; - } - } + (window.devtoolsFormatters ??= []).push({ + /** + * @param {any} object + * @param {any} config + */ + header(object, config) { + custom_formatters_enabled = true; - return original.apply(console, args); - }; - } -} - -/** - * @param {any} value - * @param {Set} seen - * @returns {boolean} - */ -function contains_state_proxy(value, seen = new Set()) { - if (typeof value !== 'object' || value === null) return false; + if (STATE_SYMBOL in object) { + return [ + 'div', + {}, + ['span', { style: 'font-weight: bold' }, '$state'], + ['object', { object: snapshot(object), config }] + ]; + } - if (seen.has(value)) return false; - seen.add(value); + return null; + }, - if (STATE_SYMBOL in value) { - return true; + hasBody: () => false + }); } - for (const key in value) { - if (contains_state_proxy(value[key], seen)) { - return true; - } + console.log(`Running Svelte in development mode`, { version: VERSION }); + + if (is_chrome && !custom_formatters_enabled) { + w.enable_custom_formatters(); } } diff --git a/packages/svelte/src/internal/client/index.js b/packages/svelte/src/internal/client/index.js index 6fc9033805..d7f04df654 100644 --- a/packages/svelte/src/internal/client/index.js +++ b/packages/svelte/src/internal/client/index.js @@ -1,5 +1,5 @@ import { DEV } from 'esm-env'; -import { monkey_patch_console } from './dev/log.js'; +import { install_custom_formatter } from './dev/log.js'; export { FILENAME, HMR } from '../../constants.js'; export { add_locations } from './dev/elements.js'; @@ -169,5 +169,5 @@ export { export { strict_equals, equals } from './dev/equality.js'; if (DEV) { - monkey_patch_console(); + install_custom_formatter(); } diff --git a/packages/svelte/src/internal/client/warnings.js b/packages/svelte/src/internal/client/warnings.js index 36d7345b86..134ef367c8 100644 --- a/packages/svelte/src/internal/client/warnings.js +++ b/packages/svelte/src/internal/client/warnings.js @@ -138,4 +138,16 @@ export function state_proxy_equality_mismatch(operator) { // TODO print a link to the documentation console.warn("state_proxy_equality_mismatch"); } +} + +/** + * We recommend enabling custom formatters for better results when logging `$state` objects — in your devtools, click the gear icon and check the 'Custom formatters' box + */ +export function enable_custom_formatters() { + if (DEV) { + console.warn(`%c[svelte] enable_custom_formatters\n%cWe recommend enabling custom formatters for better results when logging \`$state\` objects — in your devtools, click the gear icon and check the 'Custom formatters' box`, bold, normal); + } else { + // TODO print a link to the documentation + console.warn("enable_custom_formatters"); + } } \ No newline at end of file