# @domql/utils

> Core utility functions for the DOMQL element system.

Latest version **3.8.9** (published 2026-03-29) · CC-BY-NC-4.0 license · 0 weekly downloads

## Install

```sh
npm install @domql/utils
pnpm add @domql/utils
yarn add @domql/utils
bun add @domql/utils
```

## Health

**Score 50/100 (C)** — status: active.

Positive: esm support; no vulnerabilities.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 3.8.9 |
| Published | 2026-03-29 |
| First published | 2021-12-02 |
| Weekly downloads | 0 |
| License | CC-BY-NC-4.0 |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 494.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | nikoloza |

## Links

- npm: https://www.npmjs.com/package/@domql/utils
- npm.io page: https://npm.io/package/@domql/utils

## Recent versions

- 3.8.9 (latest) — 2026-03-29
- 3.8.8 — 2026-03-29
- 3.8.7 — 2026-03-28
- 3.8.6 — 2026-03-24
- 3.8.1 — 2026-03-24
- 3.8.0 — 2026-03-17
- 3.7.6 — 2026-03-16
- 3.7.5 — 2026-03-15
- 3.7.4 — 2026-03-14
- 3.7.3 — 2026-03-14
- 3.7.0 — 2026-03-13
- 3.6.8 — 2026-03-13
- 3.6.7 — 2026-03-13
- 3.6.6 — 2026-03-12
- 3.6.4 — 2026-03-11
- … 524 more at https://npm.io/package/@domql/utils/versions

## README

# @domql/utils

Core utility functions for the DOMQL element system.

## Propertization (`props.js`)

The propertization system normalizes element definitions by sorting keys between the element root (child elements, framework keys) and `props` (CSS properties, design tokens, custom data).

### Two-phase process

1. **`pickupPropsFromElement`** — Scans element root keys and moves non-element, non-builtin keys into `props`
2. **`pickupElementFromProps`** — Scans `props` keys and moves element-like or builtin keys back to the element root

### Key classification rules

| Pattern | Classification | Example |
|---------|---------------|---------|
| Starts with uppercase | Child element | `Header`, `Button`, `Nav` |
| Numeric key | Child element | `0`, `1`, `2` |
| In `DOMQ_PROPERTIES` | Framework builtin | `tag`, `extends`, `on` |
| In `CSS_SELECTOR_PREFIXES` | CSS-in-props | `:hover`, `@mobileS`, `$isActive` |
| Has define handler | Define key (stays at root) | `$router`, deprecated: `$propsCollection` |
| `childProps` | Always in props | `childProps` |
| `onXxx` + function | Event handler | `onClick`, `onSubmit` |
| Everything else | Prop | `padding`, `theme`, `color` |

### CSS_SELECTOR_PREFIXES

```javascript
const CSS_SELECTOR_PREFIXES = new Set([
  ':', '@', '[', '*', '+', '~', '&', '>', '$', '-', '.', '!'
])
```

These single-character prefixes identify keys that should be processed by `css-in-props` via `transformersByPrefix`. When a key starts with one of these characters, it gets moved into `props`.

### Define-awareness

The `$` prefix is shared between css-in-props conditionals (`$isActive`) and define handlers (built-in `$router`, plus deprecated v2 handlers like `$propsCollection`, `$collection` that some older projects still use). The propertization must check for define handlers **before** applying prefix rules:

```javascript
// Check define handlers first — these stay at root
const defineValue = this.define?.[key]
const globalDefineValue = this.context?.define?.[key]
if (isFunction(defineValue) || isFunction(globalDefineValue)) continue

// Only then apply prefix-based classification
if (CSS_SELECTOR_PREFIXES.has(firstChar)) {
  obj.props[key] = value
}
```

Without this check, define keys like `$router` (or deprecated `$propsCollection` in older projects) get moved into `props` and become invisible to `throughInitialDefine`, breaking routing and collection-based rendering.

### childProps handling

`childProps` is a framework property that configures child element props. It must always stay in `props` (consumed by `inheritParentProps`) even though its value may contain uppercase keys that look like child elements:

```javascript
// childProps: { Icon: { name: 'star' }, Hgroup: { ... } }
// The uppercase keys inside are NOT child elements
if (key === 'childProps') {
  obj.props[key] = value
  delete obj[key]
  continue
}
```

### ignoreChildProps

When set on `element.props`, prevents the element from inheriting `childProps` from its parent via `inheritParentProps`. Used by fragment elements to avoid double-application of childProps (since fragments explicitly forward childProps to their children).

## Scope (`scope.js`)

### `createScope(element, parent)`

Creates the scope for an element with prototype-chain inheritance:

```
el.scope → parent.scope → grandparent.scope → ... → root.scope → context.globalScope
```

**Behavior:**
- **No own scope** — element inherits `parent.scope` directly (same reference)
- **Own scope defined** (`scope: { myVar: 1 }`) — prototype is set to parent's scope, chaining up to `globalScope`
- **No parent/root scope** — new scope created with `Object.create(context.globalScope)`
- **No context** — plain `{}`

### `globalScope`

Automatically initialized as `context.globalScope = {}` if context exists. Sits at the bottom of every scope prototype chain, making its properties accessible from any element via `el.scope.X`.

```js
// In context or set by the serialization pipeline:
context.globalScope = {
  API_URL: 'https://api.example.com',
  helpers: { capitalize: (s) => s[0].toUpperCase() + s.slice(1) }
}

// Accessible from any element — no import needed:
onClick: (e, el) => fetch(el.scope.API_URL)

// Also directly accessible:
el.context.globalScope.API_URL
```

When a component defines its own scope, properties shadow parent/global values but the chain remains walkable:

```js
// Parent: scope = { theme: 'dark' }
// Child:  scope = { count: 0 }
// el.scope.count → 0      (own)
// el.scope.theme → 'dark'  (parent, via prototype)
// el.scope.API_URL → '...' (globalScope, via prototype chain)
```

## Key Sets (`keys.js`)

- **`DOMQ_PROPERTIES`** — Framework-level keys that stay at element root
- **`PROPS_METHODS`** — Keys on the props prototype (update, __element)
- **`STATE_METHODS`** — State management methods (update, parse, set, toggle, etc.)

---
_Source: https://npm.io/package/@domql/utils · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
