Summary
⚠️ Breaking change
Replace the static class properties (DOMObserver.ADD, DOMObserver.EXIST, etc.) with a standalone exported as const object. This removes the need to import the class just to access event name constants, improves tree-shaking, and enables better TypeScript inference.
Current state
// Must import the class even if only using constants
import { DOMObserver } from '@untemps/dom-observer'
obs.watch('#foo', cb, { events: [DOMObserver.ADD, DOMObserver.REMOVE] })
The constants live on the class:
class DOMObserver {
static EXIST = 'DOMObserver_exist'
static ADD = 'DOMObserver_add'
static REMOVE = 'DOMObserver_remove'
static CHANGE = 'DOMObserver_change'
static EVENTS = [...]
}
Proposed API
// New top-level export
export const DOMObserverEvent = {
EXIST: 'DOMObserver_exist',
ADD: 'DOMObserver_add',
REMOVE: 'DOMObserver_remove',
CHANGE: 'DOMObserver_change',
} as const
export const DOMObserverEvents = Object.values(DOMObserverEvent) as DOMObserverEventValue[]
export type DOMObserverEventValue = typeof DOMObserverEvent[keyof typeof DOMObserverEvent]
Usage:
import { DOMObserver, DOMObserverEvent } from '@untemps/dom-observer'
obs.watch('#foo', cb, {
events: [DOMObserverEvent.ADD, DOMObserverEvent.REMOVE],
})
Benefits
- Tree-shaking — bundlers can eliminate
DOMObserver class code when only constants are needed (e.g. in type-checking files or test utilities).
- No class instantiation required — constants are usable without
new DOMObserver() or even referencing the class.
- Better TypeScript narrowing —
as const values produce literal types directly; static class properties require typeof DOMObserver.ADD for the same effect.
- Conventional — aligns with the pattern used by most modern TypeScript libraries (Zod, TanStack, etc.).
Breaking changes
| Before |
After |
DOMObserver.ADD |
DOMObserverEvent.ADD |
DOMObserver.EXIST |
DOMObserverEvent.EXIST |
DOMObserver.REMOVE |
DOMObserverEvent.REMOVE |
DOMObserver.CHANGE |
DOMObserverEvent.CHANGE |
DOMObserver.EVENTS |
DOMObserverEvents |
Migration
A simple global find-and-replace handles the majority of cases. The static properties could be kept as deprecated aliases for one major version to ease migration.
Note on naming conflict
The existing exported type DOMObserverEvent (the union of four string literals) would be renamed — e.g. to DOMObserverEventValue or DOMObserverEventType — to free the name for the as const object. This is an additional (small) breaking change to the type export.
Summary
Replace the static class properties (
DOMObserver.ADD,DOMObserver.EXIST, etc.) with a standalone exportedas constobject. This removes the need to import the class just to access event name constants, improves tree-shaking, and enables better TypeScript inference.Current state
The constants live on the class:
Proposed API
Usage:
Benefits
DOMObserverclass code when only constants are needed (e.g. in type-checking files or test utilities).new DOMObserver()or even referencing the class.as constvalues produce literal types directly; static class properties requiretypeof DOMObserver.ADDfor the same effect.Breaking changes
DOMObserver.ADDDOMObserverEvent.ADDDOMObserver.EXISTDOMObserverEvent.EXISTDOMObserver.REMOVEDOMObserverEvent.REMOVEDOMObserver.CHANGEDOMObserverEvent.CHANGEDOMObserver.EVENTSDOMObserverEventsMigration
A simple global find-and-replace handles the majority of cases. The static properties could be kept as deprecated aliases for one major version to ease migration.
Note on naming conflict
The existing exported type
DOMObserverEvent(the union of four string literals) would be renamed — e.g. toDOMObserverEventValueorDOMObserverEventType— to free the name for theas constobject. This is an additional (small) breaking change to the type export.