# @symbo.ls/utils

> Core utility functions for the DOMQL element system.

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

## Install

```sh
npm install @symbo.ls/utils
pnpm add @symbo.ls/utils
yarn add @symbo.ls/utils
bun add @symbo.ls/utils
```

## Health

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

Positive: esm support; no vulnerabilities; recently updated; high maintenance score.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 3.14.771 |
| Published | 2026-09-03 |
| First published | 2022-09-12 |
| Weekly downloads | 0 |
| License | CC-BY-NC-4.0 |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 377 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | elanor, nikoloza, bala-symbols, gallenjohnson, tiny, zajim, lberia, svinchy, chejuichen, tokoyoung, baronsilver, zacharybetzen, bsachdeva, tthomasagg, bneeli33 |

## Links

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

## Recent versions

- 3.14.771 (latest) — 2026-09-03
- 3.14.770 — 2026-08-30
- 3.14.769 — 2026-08-26
- 3.14.768 — 2026-08-11
- 3.14.756 — 2026-08-09
- 3.14.743 — 2026-08-09
- 3.14.742 — 2026-08-09
- 3.14.741 — 2026-08-09
- 3.14.740 — 2026-08-09
- 3.14.739 — 2026-08-09
- 3.14.738 — 2026-08-09
- 3.14.737 — 2026-08-09
- 3.14.736 — 2026-08-09
- 3.14.735 — 2026-08-09
- 3.14.707 — 2026-08-08
- … 448 more at https://npm.io/package/@symbo.ls/utils/versions

## README

# @domql/utils

Core utility functions for the DOMQL element system.

## Propertization (`props.js`)

The propertization system normalizes element definitions by classifying keys into child elements, framework keys, and CSS/design-token properties.

In v3.14, properties go directly on the element (no `props:` wrapper needed). The propertization system operates internally to route properties to the atomic CSS engine (`@symbo.ls/css`).

### Two-phase process

1. **`pickupPropsFromElement`** — Scans element root keys and classifies non-element, non-builtin keys for CSS processing
2. **`pickupElementFromProps`** — Scans classified keys and moves element-like or builtin keys back to the element root

### Key classification rules

In v3.14, properties go directly on the element (no `props:` wrapper needed). The propertization system still operates internally for the CSS engine.

| 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`, `state` |
| 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/lifecycle handler | `onClick`, `onSubmit`, `onInit`, `onRender` |
| Everything else | CSS/design token 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`). The propertization checks for define handlers before applying prefix rules to ensure define keys stay at the element root.

### childProps handling

`childProps` is a framework property that configures child element properties. Its value may contain uppercase keys that look like child elements but are not:

```javascript
// childProps: { Icon: { name: 'star' }, Hgroup: { ... } }
// The uppercase keys inside are NOT child elements — they target named children
```

### 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/@symbo.ls/utils · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
