Debugging Features and Runtime Inspection in Cotomy

Explain the debugging philosophy of Cotomy and the runtime debug logging system implemented in the framework.

This is a continuation of CotomyApi in Practice . The previous article focused on transport behavior and exception handling. This time the focus is how debugging is actually done when developing with Cotomy and how runtime behavior can be inspected without changing application code.

Introduction

One design concern when creating Cotomy was debuggability. When I first started using TypeScript, debugging was often harder than writing the code itself. Older JavaScript environments created a large gap between the TypeScript source and the transpiled output. In the browser, the code that actually ran often did not resemble the TypeScript code I had written, so stepping through behavior became confusing.

Modern editors such as VS Code improved this situation, but in practice the setup was not always simple. Debug configurations were often fragile, browser attachment could be unreliable, and the result was not always worth the friction for normal screen development. Because of that experience, I thought carefully about debugging when the internal utilities were reorganized into Cotomy.

In practice, browser debugging is still the most reliable method. Cotomy now targets ES2020 or later, so the distance between TypeScript and executed JavaScript is much smaller than it used to be. Modern browsers are easier to debug directly, and many screens contain only a small amount of custom TypeScript, so source-level debugging is less painful than before.

That does not remove the need for runtime inspection. When a form submits unexpected values, when a page controller initializes in the wrong order, or when API-bound HTML is filled incorrectly, logs are still useful. That is why Cotomy includes a small debug logging mechanism instead of trying to replace normal browser tools.

Debug Logging Philosophy

Debug information should not always be emitted. In some business systems it may not be catastrophic if logs remain enabled, but that is usually not the right default. During development, detailed runtime information is helpful. In production, unnecessary log output should usually be minimized.

Cotomy handles this by categorizing debug logs. The framework does not treat debugging as one permanent on or off switch for all runtime behavior. Instead, it separates logs by concern so that API traffic, form payload inspection, page initialization, and other runtime areas can be enabled independently.

Cotomy Debug Logging System

The implementation is centered on the debug classes documented in the Cotomy reference. See CotomyDebugFeature . Cotomy defines a CotomyDebugSettings class and a CotomyDebugFeature enum. The mechanism is deliberately small. It does not use a remote logger or a framework-wide diagnostics pipeline. It reads debug flags directly from localStorage.

The storage key prefix is cotomy:debug. There are two levels of enablement.

Global enable uses the key cotomy:debug. If that value is true, all debug categories are considered enabled.

Feature-specific enable uses keys such as cotomy:debug:api or cotomy:debug:formdata. When a specific feature key is true, that category logs even if the global flag is not enabled.

The class methods are thin wrappers around those keys. enableAll() sets the global key to true. disableAll() sets the global key to false. enable(feature) sets one feature key to true. disable(feature) sets one feature key to false. clear() removes the global key only. clear(feature) removes the key for that specific feature.

Because the state lives in localStorage, developers can toggle debugging directly from the browser console. That is the practical goal of the design. Runtime inspection can be turned on at the browser level without editing page code, rebuilding, or adding temporary console statements into the application.

Debug Feature Categories

The current categories are defined by the CotomyDebugFeature enum. See CotomyDebugFeature . Their meaning becomes clearer when you trace where they are used in the framework.

Feature Purpose Typical scenario
Api Logs request and response behavior around CotomyApi operations. Inspecting request URLs, request bodies, response bodies, or error responses during submit and load flows.
Fill Logs form input fill operations in CotomyEntityFillApiForm. Checking which input name is being filled and what value is being written into it.
Bind Logs data binding into elements that use data-cotomy-bind. Inspecting why displayed text does or does not match API response data.
FormData Logs the FormData entries generated from a form before submit. Confirming the exact submitted payload, especially with datetime-local conversion and browser-native form behavior.
Html Logs CotomyElement creation paths that build HTML or apply scoped CSS. Inspecting how a CotomyElement was created from HTML, tag metadata, or inline scoped CSS.
Page Logs CotomyPageController initialization. Confirming when the page controller starts its initializeAsync flow on load.
FormLoad Logs entity form load warnings around entity key handling. Investigating cases such as an existing entity key combined with a 201 Created response.

These categories are intentionally narrow. They are tied to concrete runtime boundaries inside Cotomy rather than broad generic logging levels.

Enabling Debug Logs

The simplest way to enable logs is from the browser console by setting localStorage flags directly. That works because CotomyDebugSettings reads those keys each time it checks whether a category is enabled.

Enable all debug output:

localStorage.setItem("cotomy:debug", "true");

Disable all debug output:

localStorage.setItem("cotomy:debug", "false");

Enable one feature:

localStorage.setItem("cotomy:debug:api", "true");
localStorage.setItem("cotomy:debug:formdata", "true");

Disable one feature:

localStorage.setItem("cotomy:debug:api", "false");

Clear the global flag through the framework API:

CotomyDebugSettings.clear();
CotomyDebugSettings.clear(CotomyDebugFeature.Api);
CotomyDebugSettings.clear(CotomyDebugFeature.FormData);

Reset all debug-related keys manually from the browser console:

localStorage.removeItem("cotomy:debug");
localStorage.removeItem("cotomy:debug:api");
localStorage.removeItem("cotomy:debug:formdata");

These correspond to the same storage keys that CotomyDebugSettings uses through enableAll(), disableAll(), enable(feature), disable(feature), and clear(). The important point is not the class call itself. The important point is that runtime inspection can be switched on from devtools without modifying application code.

How Debugging Works in Practice

The normal workflow is simple.

  1. Open browser devtools.
  2. Enable the relevant debug category in the console.
  3. Reproduce the behavior on the screen.
  4. Inspect the emitted logs in the console.

Chrome is my usual development browser, and in practice this is still the fastest path. If I need to step through code, I use the normal browser debugger. If I need to inspect runtime boundaries such as generated FormData, bind targets, page initialization, or API response handling, I enable the relevant Cotomy debug category and reproduce the screen flow.

This combination is important. Cotomy does not assume that logs alone are enough, and it also does not assume that source-level stepping is enough. Browser debugging handles execution flow. The debug categories make runtime state easier to inspect at the exact framework boundaries where business screens usually become confusing.

Conclusion

Cotomy does not try to replace browser debugging tools. The practical answer is still to use the browser debugger for execution flow and stack inspection.

What Cotomy adds is a small runtime logging layer around clear framework boundaries: API transport, form payload creation, binding, HTML generation, page initialization, and form loading. That fits the broader design direction of the framework. The goal is predictable DOM behavior, explicit runtime boundaries, and optional inspection when the screen needs it.

With that combination, developers can inspect runtime behavior with minimal tooling friction.

Usage Series

This article is part of the Cotomy Usage Series, which focuses on concrete runtime behavior and day-to-day API usage.

Series articles: CotomyElement in Practice , CotomyElement Value and Form Behavior , CotomyApi in Practice , and Debugging Features and Runtime Inspection in Cotomy.

Previous article: CotomyApi in Practice

Learn Cotomy

Cotomy is a DOM-first UI runtime for long-lived business applications.