id-dom 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,295 @@
1
+ # id-dom
2
+
3
+ [![npm](https://img.shields.io/npm/v/id-dom)](https://www.npmjs.com/package/id-dom)
4
+ [![downloads](https://img.shields.io/npm/dm/id-dom)](https://www.npmjs.com/package/id-dom)
5
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/id-dom)](https://bundlephobia.com/package/id-dom)
6
+ [![license](https://img.shields.io/npm/l/id-dom)](https://github.com/iWhatty/id-dom/blob/main/LICENSE)
7
+ [![stars](https://img.shields.io/github/stars/iWhatty/id-dom?style=social)](https://github.com/iWhatty/id-dom)
8
+
9
+ Deterministic DOM element getters by ID. Typed, tiny, modern. A small utility for grabbing DOM references safely by `id`, with predictable behavior.
10
+
11
+ ## Features
12
+
13
+ - Typed getters like `button('saveBtn')`, `input('nameInput')`, `svg('icon')`
14
+ - Strict or optional mode (`throw` vs `null`)
15
+ - Short optional alias via `.opt`
16
+ - Scoped lookups for `document`, `ShadowRoot`, `DocumentFragment`, or an `Element`
17
+ - Centralized error handling with `onError` and optional `warn`
18
+ - Zero dependencies
19
+
20
+ This is deliberately **not** a selector framework. It is a tiny, ID-first primitive for safe DOM wiring.
21
+
22
+ ---
23
+
24
+ ## Install
25
+
26
+ ```sh
27
+ pnpm add id-dom
28
+ ```
29
+
30
+ ---
31
+
32
+ ## Quick start
33
+
34
+ Two import styles, same root, same behavior. Pick by preference:
35
+
36
+ ```js
37
+ // Default-object style. Every typed helper lives under one namespace.
38
+ import dom from 'id-dom'
39
+
40
+ const saveBtn = dom.button('saveBtn')
41
+ saveBtn.addEventListener('click', save)
42
+ ```
43
+
44
+ ```js
45
+ // Named-import style, added in 0.0.5. Makes the dependency surface explicit
46
+ // in the import declaration. Tree-shaken identically by modern bundlers
47
+ // (esbuild, vite, rollup, webpack 5) since the package ships
48
+ // `sideEffects: false`.
49
+ import { button, input, div } from 'id-dom'
50
+
51
+ const saveBtn = button('saveBtn')
52
+ const email = input('email')
53
+ const panel = div('mainPanel')
54
+ ```
55
+
56
+ Optional access never throws for missing or wrong-type elements:
57
+
58
+ ```js
59
+ const debug = dom.div.optional('debugPanel') // default-object style
60
+ debug?.append('hello')
61
+
62
+ import { canvas } from 'id-dom'
63
+ const maybeCanvas = canvas.opt('game') // named style
64
+ ```
65
+
66
+ ---
67
+
68
+ ## API
69
+
70
+ ### Default export: `dom`
71
+
72
+ The default export is a scoped instance using `document` (when available) with **strict** behavior:
73
+
74
+ - missing element → **throws**
75
+ - wrong type or wrong tag → **throws**
76
+ - invalid input → **throws**
77
+
78
+ ```js
79
+ import dom from 'id-dom'
80
+
81
+ const name = dom.input('nameInput')
82
+ const submit = dom.button('submitBtn')
83
+ ```
84
+
85
+ ### `createDom(root, config?)`
86
+
87
+ Create a scoped instance that searches within a specific root:
88
+
89
+ - `document` → uses `getElementById`
90
+ - `ShadowRoot`, `DocumentFragment`, or `Element` → uses `querySelector(#id)` fallback
91
+
92
+ ```js
93
+ import { createDom } from 'id-dom'
94
+
95
+ const d = createDom(document, { mode: 'null', warn: true })
96
+ const sidebar = d.div('sidebar')
97
+ ```
98
+
99
+ **Config:**
100
+
101
+ ```ts
102
+ type DomMode = 'throw' | 'null'
103
+
104
+ {
105
+ mode?: DomMode
106
+ warn?: boolean
107
+ onError?: (err: Error, ctx: any) => void
108
+ }
109
+ ```
110
+
111
+ ### `byId(id, Type, config?)`
112
+
113
+ Generic typed lookup:
114
+
115
+ ```js
116
+ import { byId } from 'id-dom'
117
+
118
+ const btn = byId('saveBtn', HTMLButtonElement)
119
+ ```
120
+
121
+ Optional variants:
122
+
123
+ ```js
124
+ const maybeBtn = byId.optional('saveBtn', HTMLButtonElement)
125
+ const maybeBtn2 = byId.opt('saveBtn', HTMLButtonElement)
126
+ ```
127
+
128
+ Behavior:
129
+
130
+ - valid match → returns the element
131
+ - missing element → throws or returns `null`
132
+ - wrong type → throws or returns `null`
133
+ - invalid `id` → throws or returns `null`
134
+ - invalid `Type` → throws or returns `null`
135
+
136
+ ### `tag(id, tagName, config?)`
137
+
138
+ Tag-based validation when constructor checks are not the right fit:
139
+
140
+ ```js
141
+ import { tag } from 'id-dom'
142
+
143
+ const main = tag('appMain', 'main')
144
+ const icon = tag('icon', 'svg', { root: container })
145
+ ```
146
+
147
+ Optional variants:
148
+
149
+ ```js
150
+ const maybeMain = tag.optional('appMain', 'main')
151
+ const maybeMain2 = tag.opt('appMain', 'main')
152
+ ```
153
+
154
+ Behavior:
155
+
156
+ - valid tag match → returns the element
157
+ - missing element → throws or returns `null`
158
+ - wrong tag → throws or returns `null`
159
+ - invalid `id` → throws or returns `null`
160
+ - invalid `tagName` → throws or returns `null`
161
+
162
+ ### Built-in getters
163
+
164
+ Typed getters available on `dom` and on any `createDom()` instance:
165
+
166
+ - `el(id)` → `HTMLElement`
167
+ - `input(id)` → `HTMLInputElement`
168
+ - `button(id)` → `HTMLButtonElement`
169
+ - `textarea(id)` → `HTMLTextAreaElement`
170
+ - `select(id)` → `HTMLSelectElement`
171
+ - `form(id)` → `HTMLFormElement`
172
+ - `div(id)` → `HTMLDivElement`
173
+ - `span(id)` → `HTMLSpanElement`
174
+ - `label(id)` → `HTMLLabelElement`
175
+ - `canvas(id)` → `HTMLCanvasElement`
176
+ - `template(id)` → `HTMLTemplateElement`
177
+ - `svg(id)` → `SVGSVGElement`
178
+ - `body(id)` → `HTMLBodyElement`
179
+
180
+ Each getter also has `.optional` and `.opt` variants:
181
+
182
+ ```js
183
+ dom.canvas.optional('game')
184
+ dom.canvas.opt('game')
185
+ ```
186
+
187
+ Common tag helpers:
188
+
189
+ - `main(id)` → validates `<main>`
190
+ - `section(id)` → validates `<section>`
191
+ - `small(id)` → validates `<small>`
192
+
193
+ Each also supports `.optional` and `.opt`.
194
+
195
+ ### Error handling
196
+
197
+ **Throwing mode:**
198
+
199
+ ```js
200
+ import dom from 'id-dom'
201
+
202
+ dom.button('missing') // throws
203
+ ```
204
+
205
+ **Null-returning mode:**
206
+
207
+ ```js
208
+ import { createDom } from 'id-dom'
209
+
210
+ const d = createDom(document, { mode: 'null' })
211
+ d.button('missing') // null
212
+ ```
213
+
214
+ **Central reporting:**
215
+
216
+ ```js
217
+ const d = createDom(document, {
218
+ mode: 'null',
219
+ onError: (err, ctx) => {
220
+ // sendToSentry({ err, ctx })
221
+ },
222
+ })
223
+ ```
224
+
225
+ Enable console warnings too:
226
+
227
+ ```js
228
+ createDom(document, { mode: 'null', warn: true })
229
+ ```
230
+
231
+ ---
232
+
233
+ ## Notes
234
+
235
+ ### Why id-first?
236
+
237
+ Using `getElementById` is fast, unambiguous, and easy to reason about. With typed getters, you immediately know whether you got a `HTMLButtonElement`, `HTMLInputElement`, `SVGSVGElement`, and so on.
238
+
239
+ When scoped roots do not support `getElementById`, id-dom falls back to `querySelector(#id)` and safely escapes edge-case IDs.
240
+
241
+ ### Bundle-size note
242
+
243
+ The shared lookup machinery (validation, CSS-escape fallback, error policy, root resolution) is the bulk of the package, roughly 1.9 KB gzipped in a modern bundler. Importing 4 helpers vs 1 vs the full default object lands in the same ballpark. The named-import style is recommended for readability and explicit-surface clarity, not for size.
244
+
245
+ ### Scoped roots
246
+
247
+ **Shadow DOM:**
248
+
249
+ ```js
250
+ import { createDom } from 'id-dom'
251
+
252
+ const host = document.querySelector('#widget')
253
+ const shadow = host.attachShadow({ mode: 'open' })
254
+ shadow.innerHTML = `<button id="shadowBtn">Click</button>`
255
+
256
+ const d = createDom(shadow)
257
+ const btn = d.button('shadowBtn')
258
+ ```
259
+
260
+ **Element root:**
261
+
262
+ ```js
263
+ const container = document.querySelector('#settings-panel')
264
+ const d = createDom(container)
265
+ const input = d.input('emailInput')
266
+ ```
267
+
268
+ **SVG in scoped roots:**
269
+
270
+ ```js
271
+ const container = document.querySelector('#icons')
272
+ const d = createDom(container)
273
+ const icon = d.svg('logoMark')
274
+ ```
275
+
276
+ ### Misc
277
+
278
+ - `el(id)` is specifically for `HTMLElement`, not every possible DOM `Element`.
279
+ - `body(id)` looks up a `<body>` **by ID**. This library stays ID-first on purpose.
280
+ - `tag()` can validate non-HTML tags too, such as `svg`, when used against supported scoped roots.
281
+
282
+ ### Browser support
283
+
284
+ Modern browsers supporting:
285
+
286
+ - `getElementById`
287
+ - `querySelector`
288
+
289
+ `CSS.escape` is used when available. A safe internal fallback is included for environments such as some jsdom builds where it may be missing.
290
+
291
+ ---
292
+
293
+ ## License
294
+
295
+ Licensed under AGPL-3.0 with WATT3D Additional Terms. See [LICENSE](./LICENSE) and [ADDITIONAL_TERMS.md](./ADDITIONAL_TERMS.md). Commercial AI/model-training use requires compliance with those terms or a separate WATT3D license. © WATT3D.
package/dist/index.cjs CHANGED
@@ -17,20 +17,48 @@ var __copyProps = (to, from, except, desc) => {
17
17
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
18
  var id_dom_exports = {};
19
19
  __export(id_dom_exports, {
20
+ body: () => body,
21
+ button: () => button,
20
22
  byId: () => byId,
23
+ canvas: () => canvas,
21
24
  createDom: () => createDom,
22
25
  default: () => id_dom_default,
23
- tag: () => tag
26
+ div: () => div,
27
+ el: () => el,
28
+ form: () => form,
29
+ input: () => input,
30
+ label: () => label,
31
+ main: () => main,
32
+ section: () => section,
33
+ select: () => select,
34
+ small: () => small,
35
+ span: () => span,
36
+ svg: () => svg,
37
+ tag: () => tag,
38
+ template: () => template,
39
+ textarea: () => textarea
24
40
  });
25
41
  module.exports = __toCommonJS(id_dom_exports);
26
42
  const DEFAULT_ROOT = typeof document !== "undefined" && document ? document : (
27
43
  /** @type {any} */
28
44
  null
29
45
  );
46
+ const REASON = (
47
+ /** @type {const} */
48
+ {
49
+ INVALID_ID: "invalid-id",
50
+ INVALID_TYPE: "invalid-type",
51
+ INVALID_TAG: "invalid-tag",
52
+ MISSING: "missing",
53
+ WRONG_TYPE: "wrong-type",
54
+ WRONG_TAG: "wrong-tag"
55
+ }
56
+ );
57
+ const SAFE_ID_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
58
+ const NEEDS_START_ESCAPE_RE = /^(?:\d|-\d)/;
30
59
  function normalizeConfig(cfg) {
31
60
  return {
32
61
  mode: cfg?.mode ?? "throw",
33
- // default strict
34
62
  warn: cfg?.warn ?? false,
35
63
  onError: typeof cfg?.onError === "function" ? cfg.onError : null,
36
64
  root: cfg?.root ?? DEFAULT_ROOT
@@ -42,8 +70,6 @@ function hasGetElementById(v) {
42
70
  function hasQuerySelector(v) {
43
71
  return !!v && typeof v === "object" && typeof v.querySelector === "function";
44
72
  }
45
- const SAFE_ID_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
46
- const NEEDS_START_ESCAPE_RE = /^(?:\d|-\d)/;
47
73
  function cssEscape(id) {
48
74
  const s = String(id);
49
75
  if (typeof CSS !== "undefined" && typeof CSS.escape === "function") {
@@ -59,10 +85,13 @@ function cssEscape(id) {
59
85
  cp >= 97 && cp <= 122 || // a-z
60
86
  cp === 95 || // _
61
87
  cp === 45;
62
- const needsStartEscape = i === 0 && (cp >= 48 && cp <= 57 || cp === 45 && s.length > 1 && s.codePointAt(1) >= 48 && s.codePointAt(1) <= 57);
88
+ const next = s.codePointAt(i + 1);
89
+ const startsWithDigit = cp >= 48 && cp <= 57;
90
+ const startsWithDashDigit = cp === 45 && s.length > 1 && next >= 48 && next <= 57;
91
+ const needsStartEscape = i === 0 && (startsWithDigit || startsWithDashDigit);
63
92
  if (!needsStartEscape && (isAsciiSafe || cp >= 160)) {
64
93
  out += ch;
65
- } else if (cp === 45 && i === 0 && s.length > 1 && s.codePointAt(1) >= 48 && s.codePointAt(1) <= 57) {
94
+ } else if (i === 0 && startsWithDashDigit) {
66
95
  out += "\\-";
67
96
  } else {
68
97
  out += `\\${cp.toString(16).toUpperCase()} `;
@@ -71,16 +100,32 @@ function cssEscape(id) {
71
100
  }
72
101
  return out;
73
102
  }
103
+ function isElementNode(v) {
104
+ if (!v || typeof v !== "object") return false;
105
+ if (typeof Element !== "undefined") return v instanceof Element;
106
+ return (
107
+ /** @type {any} */
108
+ v.nodeType === 1
109
+ );
110
+ }
74
111
  function getById(root, id) {
75
112
  if (!root) return null;
76
113
  if (hasGetElementById(root)) return root.getElementById(id);
77
114
  if (hasQuerySelector(root)) {
78
- const sel = `#${cssEscape(id)}`;
79
- const el = root.querySelector(sel);
80
- return el instanceof HTMLElement ? el : null;
115
+ const el2 = root.querySelector(`#${cssEscape(id)}`);
116
+ return isElementNode(el2) ? el2 : null;
81
117
  }
82
118
  return null;
83
119
  }
120
+ function isValidId(v) {
121
+ return typeof v === "string" && v.length > 0;
122
+ }
123
+ function isValidTagName(v) {
124
+ return typeof v === "string" && v.trim().length > 0;
125
+ }
126
+ function isConstructor(v) {
127
+ return typeof v === "function";
128
+ }
84
129
  function fmtId(id) {
85
130
  return id.startsWith("#") ? id : `#${id}`;
86
131
  }
@@ -95,54 +140,114 @@ function handleLookupError(err, ctx, cfg) {
95
140
  cfg.onError?.(err, ctx);
96
141
  } catch {
97
142
  }
98
- if (cfg.warn) console.warn(err);
143
+ if (cfg.warn) console.warn(err, ctx);
99
144
  if (cfg.mode === "throw") throw err;
100
145
  return null;
101
146
  }
102
- function byId(id, Type, config) {
147
+ function createCtx(id, root, reason, extra) {
148
+ return {
149
+ id,
150
+ root,
151
+ reason,
152
+ ...extra || {}
153
+ };
154
+ }
155
+ function resolveLookup(config, spec) {
103
156
  const cfg = normalizeConfig(config);
104
- const el = getById(cfg.root, id);
105
- if (!el) {
106
- return handleLookupError(
107
- missingElError(id, Type.name),
108
- { id, Type, root: cfg.root, reason: "missing" },
109
- cfg
110
- );
111
- }
112
- if (!(el instanceof Type)) {
113
- const got = el?.constructor?.name || typeof el;
114
- return handleLookupError(
115
- wrongTypeError(id, Type.name, got),
116
- { id, Type, root: cfg.root, reason: "wrong-type", got },
117
- cfg
118
- );
119
- }
120
- return el;
157
+ const inputFailure = spec.validateInput(cfg);
158
+ if (inputFailure) {
159
+ return handleLookupError(inputFailure.err, inputFailure.ctx, cfg);
160
+ }
161
+ const el2 = getById(cfg.root, spec.id);
162
+ if (!el2) {
163
+ const failure = spec.onMissing(cfg);
164
+ return handleLookupError(failure.err, failure.ctx, cfg);
165
+ }
166
+ if (!spec.matches(el2, cfg)) {
167
+ const failure = spec.onMismatch(el2, cfg);
168
+ return handleLookupError(failure.err, failure.ctx, cfg);
169
+ }
170
+ return (
171
+ /** @type {T} */
172
+ el2
173
+ );
174
+ }
175
+ function byId(id, Type, config) {
176
+ return resolveLookup(config, {
177
+ id,
178
+ validateInput(cfg) {
179
+ if (!isValidId(id)) {
180
+ return {
181
+ err: new Error("id-dom: invalid id (expected non-empty string)"),
182
+ ctx: createCtx(String(id), cfg.root, REASON.INVALID_ID, { Type })
183
+ };
184
+ }
185
+ if (!isConstructor(Type)) {
186
+ return {
187
+ err: new Error(`id-dom: invalid Type for ${fmtId(id)}`),
188
+ ctx: createCtx(id, cfg.root, REASON.INVALID_TYPE, { Type })
189
+ };
190
+ }
191
+ return null;
192
+ },
193
+ onMissing(cfg) {
194
+ return {
195
+ err: missingElError(id, Type.name),
196
+ ctx: createCtx(id, cfg.root, REASON.MISSING, { Type })
197
+ };
198
+ },
199
+ matches(el2) {
200
+ return el2 instanceof Type;
201
+ },
202
+ onMismatch(el2, cfg) {
203
+ const got = el2?.constructor?.name || typeof el2;
204
+ return {
205
+ err: wrongTypeError(id, Type.name, got),
206
+ ctx: createCtx(id, cfg.root, REASON.WRONG_TYPE, { Type, got })
207
+ };
208
+ }
209
+ });
121
210
  }
122
211
  byId.optional = function byIdOptional(id, Type, config) {
123
212
  return byId(id, Type, { ...config, mode: "null" });
124
213
  };
125
214
  byId.opt = byId.optional;
126
215
  function tag(id, tagName, config) {
127
- const cfg = normalizeConfig(config);
128
- const el = getById(cfg.root, id);
129
- if (!el) {
130
- return handleLookupError(
131
- missingElError(id, `<${tagName}>`),
132
- { id, tagName, root: cfg.root, reason: "missing" },
133
- cfg
134
- );
135
- }
136
- const expected = String(tagName).toUpperCase();
137
- const got = String(el.tagName || "").toUpperCase();
138
- if (got !== expected) {
139
- return handleLookupError(
140
- wrongTypeError(id, `<${expected.toLowerCase()}>`, `<${got.toLowerCase()}>`),
141
- { id, tagName, root: cfg.root, reason: "wrong-tag", got },
142
- cfg
143
- );
144
- }
145
- return el;
216
+ return resolveLookup(config, {
217
+ id,
218
+ validateInput(cfg) {
219
+ if (!isValidId(id)) {
220
+ return {
221
+ err: new Error("id-dom: invalid id (expected non-empty string)"),
222
+ ctx: createCtx(String(id), cfg.root, REASON.INVALID_ID, { tagName })
223
+ };
224
+ }
225
+ if (!isValidTagName(tagName)) {
226
+ return {
227
+ err: new Error(`id-dom: invalid tagName for ${fmtId(id)}`),
228
+ ctx: createCtx(id, cfg.root, REASON.INVALID_TAG, { tagName })
229
+ };
230
+ }
231
+ return null;
232
+ },
233
+ onMissing(cfg) {
234
+ return {
235
+ err: missingElError(id, `<${tagName}>`),
236
+ ctx: createCtx(id, cfg.root, REASON.MISSING, { tagName })
237
+ };
238
+ },
239
+ matches(el2) {
240
+ return String(el2.tagName || "").toUpperCase() === String(tagName).toUpperCase();
241
+ },
242
+ onMismatch(el2, cfg) {
243
+ const expected = String(tagName).toUpperCase();
244
+ const got = String(el2.tagName || "").toUpperCase();
245
+ return {
246
+ err: wrongTypeError(id, `<${expected.toLowerCase()}>`, `<${got.toLowerCase()}>`),
247
+ ctx: createCtx(id, cfg.root, REASON.WRONG_TAG, { tagName, got })
248
+ };
249
+ }
250
+ });
146
251
  }
147
252
  tag.optional = function tagOptional(id, tagName, config) {
148
253
  return tag(id, tagName, { ...config, mode: "null" });
@@ -162,7 +267,8 @@ const TYPE_HELPERS = (
162
267
  label: typeof HTMLLabelElement !== "undefined" ? HTMLLabelElement : null,
163
268
  canvas: typeof HTMLCanvasElement !== "undefined" ? HTMLCanvasElement : null,
164
269
  template: typeof HTMLTemplateElement !== "undefined" ? HTMLTemplateElement : null,
165
- svg: typeof SVGSVGElement !== "undefined" ? SVGSVGElement : null
270
+ svg: typeof SVGSVGElement !== "undefined" ? SVGSVGElement : null,
271
+ body: typeof HTMLBodyElement !== "undefined" ? HTMLBodyElement : null
166
272
  }
167
273
  );
168
274
  const TAG_HELPERS = (
@@ -173,45 +279,80 @@ const TAG_HELPERS = (
173
279
  small: "small"
174
280
  }
175
281
  );
282
+ function attachOptional(fn, optionalFn) {
283
+ if (typeof fn !== "function") {
284
+ throw new TypeError("id-dom: attachOptional expected fn to be a function");
285
+ }
286
+ if (typeof optionalFn !== "function") {
287
+ throw new TypeError("id-dom: attachOptional expected optionalFn to be a function");
288
+ }
289
+ fn.optional = optionalFn;
290
+ fn.opt = optionalFn;
291
+ return fn;
292
+ }
293
+ function makeTypedHelper(Type, base, baseNull) {
294
+ if (!Type) {
295
+ throw new TypeError("id-dom: makeTypedHelper received an invalid Type");
296
+ }
297
+ return attachOptional(
298
+ (id) => byId(id, Type, base),
299
+ (id) => byId(id, Type, baseNull)
300
+ );
301
+ }
302
+ function makeTagHelper(tagName, base, baseNull) {
303
+ if (!tagName) {
304
+ throw new TypeError("id-dom: makeTagHelper received an invalid tagName");
305
+ }
306
+ return attachOptional(
307
+ (id) => tag(id, tagName, base),
308
+ (id) => tag(id, tagName, baseNull)
309
+ );
310
+ }
176
311
  function createDom(root, config) {
177
312
  const base = normalizeConfig({ ...config, root });
178
313
  const baseNull = { ...base, mode: "null" };
179
- const api = {
180
- // generic
181
- byId: (id, Type) => byId(id, Type, base),
182
- tag: (id, name) => tag(id, name, base)
183
- };
314
+ const api = {};
315
+ api.byId = attachOptional(
316
+ (id, Type) => byId(id, Type, base),
317
+ (id, Type) => byId(id, Type, baseNull)
318
+ );
319
+ api.tag = attachOptional(
320
+ (id, name) => tag(id, name, base),
321
+ (id, name) => tag(id, name, baseNull)
322
+ );
184
323
  for (const [name, Type] of Object.entries(TYPE_HELPERS)) {
185
324
  if (!Type) continue;
186
- api[name] = (id) => byId(id, Type, base);
325
+ api[name] = makeTypedHelper(Type, base, baseNull);
187
326
  }
188
327
  for (const [name, tagName] of Object.entries(TAG_HELPERS)) {
189
- api[name] = (id) => tag(id, tagName, base);
190
- }
191
- api.byId.optional = (id, Type) => byId(id, Type, baseNull);
192
- api.byId.opt = api.byId.optional;
193
- api.tag.optional = (id, name) => tag(id, name, baseNull);
194
- api.tag.opt = api.tag.optional;
195
- for (const k of Object.keys(api)) {
196
- const fn = api[k];
197
- if (typeof fn !== "function") continue;
198
- if (fn.optional) continue;
199
- if (k in TAG_HELPERS) {
200
- const tagName = TAG_HELPERS[k];
201
- fn.optional = (id) => tag(id, tagName, baseNull);
202
- fn.opt = fn.optional;
203
- continue;
204
- }
205
- if (k in TYPE_HELPERS) {
206
- const Type = TYPE_HELPERS[k];
207
- if (Type) {
208
- fn.optional = (id) => byId(id, Type, baseNull);
209
- fn.opt = fn.optional;
210
- }
211
- }
328
+ api[name] = makeTagHelper(tagName, base, baseNull);
212
329
  }
213
330
  return api;
214
331
  }
332
+ const DEFAULT_BASE = normalizeConfig({ mode: "throw", root: DEFAULT_ROOT });
333
+ const DEFAULT_BASE_NULL = { ...DEFAULT_BASE, mode: "null" };
334
+ function defaultTypedHelper(Type) {
335
+ return Type ? makeTypedHelper(Type, DEFAULT_BASE, DEFAULT_BASE_NULL) : null;
336
+ }
337
+ function defaultTagHelper(tagName) {
338
+ return makeTagHelper(tagName, DEFAULT_BASE, DEFAULT_BASE_NULL);
339
+ }
340
+ const el = defaultTypedHelper(typeof HTMLElement !== "undefined" ? HTMLElement : null);
341
+ const input = defaultTypedHelper(typeof HTMLInputElement !== "undefined" ? HTMLInputElement : null);
342
+ const button = defaultTypedHelper(typeof HTMLButtonElement !== "undefined" ? HTMLButtonElement : null);
343
+ const textarea = defaultTypedHelper(typeof HTMLTextAreaElement !== "undefined" ? HTMLTextAreaElement : null);
344
+ const select = defaultTypedHelper(typeof HTMLSelectElement !== "undefined" ? HTMLSelectElement : null);
345
+ const form = defaultTypedHelper(typeof HTMLFormElement !== "undefined" ? HTMLFormElement : null);
346
+ const div = defaultTypedHelper(typeof HTMLDivElement !== "undefined" ? HTMLDivElement : null);
347
+ const span = defaultTypedHelper(typeof HTMLSpanElement !== "undefined" ? HTMLSpanElement : null);
348
+ const label = defaultTypedHelper(typeof HTMLLabelElement !== "undefined" ? HTMLLabelElement : null);
349
+ const canvas = defaultTypedHelper(typeof HTMLCanvasElement !== "undefined" ? HTMLCanvasElement : null);
350
+ const template = defaultTypedHelper(typeof HTMLTemplateElement !== "undefined" ? HTMLTemplateElement : null);
351
+ const svg = defaultTypedHelper(typeof SVGSVGElement !== "undefined" ? SVGSVGElement : null);
352
+ const body = defaultTypedHelper(typeof HTMLBodyElement !== "undefined" ? HTMLBodyElement : null);
353
+ const main = defaultTagHelper("main");
354
+ const section = defaultTagHelper("section");
355
+ const small = defaultTagHelper("small");
215
356
  const dom = createDom(DEFAULT_ROOT, { mode: "throw" });
216
357
  var id_dom_default = dom;
217
358
  //# sourceMappingURL=index.cjs.map