fix(domtools): stabilize DomTools lifecycle, cleanup, and singleton behavior

This commit is contained in:
2026-04-24 04:54:40 +00:00
parent 6c5271015d
commit 06f0ea4f92
10 changed files with 781 additions and 163 deletions
+26
View File
@@ -23,6 +23,8 @@ pnpm add @design.estate/dees-domtools
- `TypedRequest` re-exported from `@api.global/typedrequest`
- `plugins` for direct access to the package ecosystem used internally
The `plugins` export keeps the commonly used downstream namespaces available, including `plugins.smartdelay`, `plugins.smartstate`, `plugins.smartpromise`, `plugins.smartrouter`, `plugins.smartrx`, `plugins.smarturl`, and `plugins.typedrequest`.
## Quick Start
```ts
@@ -37,6 +39,8 @@ console.log(domtools.elements.bodyElement);
`setupDomTools()` is safe to call repeatedly. By default it returns a shared global instance and avoids duplicate initialization work.
If you need an isolated instance for testing or short-lived usage, pass `ignoreGlobal: true`. Isolated instances follow the same `domToolsReady` and `domReady` lifecycle as the shared singleton.
## DomTools Lifecycle
```ts
@@ -50,6 +54,8 @@ await domtools.domToolsReady.promise;
await domtools.domReady.promise;
```
`setupDomTools()` resolves once the instance is initialized and its readiness listeners are installed. `domReady` resolves later, once `document.head` and `document.body` are available.
Main instance properties:
- `elements.headElement` and `elements.bodyElement`
@@ -64,6 +70,22 @@ Main instance properties:
If you need the already-created global instance synchronously, use `DomTools.getGlobalDomToolsSync()` after startup has completed.
## Cleanup
```ts
import { DomTools } from '@design.estate/dees-domtools';
const domtools = await DomTools.setupDomTools({
ignoreGlobal: true,
});
// ...use the instance
domtools.dispose();
```
`dispose()` removes the listeners and DOM resources owned by that `DomTools` instance. For shared global usage you usually keep the singleton alive for the lifetime of the page, but disposal is useful for tests and intentionally short-lived isolated instances.
## DOM, CSS, and External Resources
```ts
@@ -122,6 +144,8 @@ await themeManager.enableAutomaticGlobalThemeChange();
The theme manager starts from `prefers-color-scheme` and publishes updates through an RxJS `ReplaySubject<boolean>`.
`enableAutomaticGlobalThemeChange()` waits for `domReady`, so it is safe to call before `document.body` exists.
## Keyboard Shortcuts
The keyboard helper is created after `document.body` exists, so wait for `domReady` before using it.
@@ -249,6 +273,8 @@ class DemoElement extends LitElement {
`elementBasic.setup()` performs the shared `DomTools` setup and injects the package's global base styles once.
The returned promise resolves after the shared base styles have been injected, and `domtools.globalStylesReady` resolves at the same point.
## State and One-Time Work
`domToolsStatePart` starts with this shape: