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/ADDITIONAL_TERMS.md +122 -0
- package/LICENSE +694 -0
- package/README.md +295 -0
- package/dist/index.cjs +218 -77
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +218 -77
- package/dist/index.js.map +3 -3
- package/dist/index.min.js +1 -1
- package/package.json +5 -3
- package/robots.txt +79 -0
- package/LICENSE.md +0 -285
- package/Readme.md +0 -255
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/id-dom.js"],
|
|
4
|
-
"sourcesContent": ["// id-dom.js\r\n// id-dom \u2014 deterministic DOM element getters by ID (typed, tiny, modern)\r\n//\r\n// Goals:\r\n// - Prefer getElementById (fast, unambiguous)\r\n// - Return the correct type or fail predictably\r\n// - Provide strict + optional variants\r\n// - Allow app/module-level defaults (throw vs null) without bundler magic\r\n// - Zero deps, framework-agnostic\r\n\r\nconst DEFAULT_ROOT =\r\n typeof document !== 'undefined' && document ? document : /** @type {any} */ (null)\r\n\r\n/**\r\n * @typedef {'throw' | 'null'} DomMode\r\n */\r\n\r\n/**\r\n * @typedef {{\r\n * mode?: DomMode\r\n * warn?: boolean\r\n * onError?: (error: Error, ctx: any) => void\r\n * root?: any\r\n * }} DomConfig\r\n */\r\n\r\n/**\r\n * @param {DomConfig | undefined} cfg\r\n */\r\nfunction normalizeConfig(cfg) {\r\n return {\r\n mode: cfg?.mode ?? 'throw', // default strict\r\n warn: cfg?.warn ?? false,\r\n onError: typeof cfg?.onError === 'function' ? cfg.onError : null,\r\n root: cfg?.root ?? DEFAULT_ROOT,\r\n }\r\n}\r\n\r\n/**\r\n * @param {unknown} v\r\n * @returns {v is { getElementById(id: string): HTMLElement | null }}\r\n */\r\nfunction hasGetElementById(v) {\r\n return !!v && typeof v === 'object' && typeof v.getElementById === 'function'\r\n}\r\n\r\n/**\r\n * @param {unknown} v\r\n * @returns {v is { querySelector(sel: string): Element | null }}\r\n */\r\nfunction hasQuerySelector(v) {\r\n return !!v && typeof v === 'object' && typeof v.querySelector === 'function'\r\n}\r\n\r\n\r\nconst SAFE_ID_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/\r\nconst NEEDS_START_ESCAPE_RE = /^(?:\\d|-\\d)/\r\n\r\n/**\r\n * Minimal CSS.escape fallback for environments where CSS.escape is missing (e.g. some jsdom builds).\r\n * We only need to safely build `#${id}` selectors.\r\n *\r\n * @param {string} id\r\n */\r\nfunction cssEscape(id) {\r\n const s = String(id)\r\n\r\n // Prefer native when available\r\n if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\r\n return CSS.escape(s)\r\n }\r\n\r\n // Fast path: most app IDs are already safe\r\n if (!NEEDS_START_ESCAPE_RE.test(s) && SAFE_ID_RE.test(s)) return s\r\n\r\n // One-pass escape:\r\n // - Escape any char outside a conservative \"safe\" set\r\n // - Also escape the start if it begins with a digit OR \"-<digit>\"\r\n let out = ''\r\n for (let i = 0; i < s.length; ) {\r\n const cp = s.codePointAt(i)\r\n const ch = String.fromCodePoint(cp)\r\n\r\n const isAsciiSafe =\r\n (cp >= 48 && cp <= 57) || // 0-9\r\n (cp >= 65 && cp <= 90) || // A-Z\r\n (cp >= 97 && cp <= 122) || // a-z\r\n cp === 95 || // _\r\n cp === 45 // -\r\n\r\n const needsStartEscape =\r\n i === 0 && ((cp >= 48 && cp <= 57) || (cp === 45 && s.length > 1 && s.codePointAt(1) >= 48 && s.codePointAt(1) <= 57))\r\n\r\n if (!needsStartEscape && (isAsciiSafe || cp >= 0x00A0)) {\r\n // allow non-ascii chars directly (common CSS ident behavior)\r\n out += ch\r\n } else if (cp === 45 && i === 0 && s.length > 1 && s.codePointAt(1) >= 48 && s.codePointAt(1) <= 57) {\r\n // \"-<digit>\" start: escaping just the leading hyphen is a simple fix\r\n out += '\\\\-'\r\n } else {\r\n // hex escape + trailing space is safest\r\n out += `\\\\${cp.toString(16).toUpperCase()} `\r\n }\r\n\r\n i += ch.length\r\n }\r\n\r\n return out\r\n}\r\n\r\n\r\n/**\r\n * Resolve an element by id from a \"root\".\r\n * Supports:\r\n * - Document (getElementById)\r\n * - ShadowRoot / DocumentFragment / Element (querySelector fallback)\r\n *\r\n * @param {any} root\r\n * @param {string} id\r\n * @returns {HTMLElement | null}\r\n */\r\nfunction getById(root, id) {\r\n if (!root) return null\r\n\r\n if (hasGetElementById(root)) return root.getElementById(id)\r\n\r\n // ShadowRoot/DocumentFragment/Element don\u2019t have getElementById\r\n if (hasQuerySelector(root)) {\r\n const sel = `#${cssEscape(id)}`\r\n const el = root.querySelector(sel)\r\n return el instanceof HTMLElement ? el : null\r\n }\r\n\r\n return null\r\n}\r\n\r\n/**\r\n * @param {string} id\r\n * @returns {string}\r\n */\r\nfunction fmtId(id) {\r\n return id.startsWith('#') ? id : `#${id}`\r\n}\r\n\r\n/**\r\n * @param {string} id\r\n * @param {string} expected\r\n */\r\nfunction missingElError(id, expected) {\r\n return new Error(`id-dom: missing ${expected} element ${fmtId(id)}`)\r\n}\r\n\r\n/**\r\n * @param {string} id\r\n * @param {string} expected\r\n * @param {string} got\r\n */\r\nfunction wrongTypeError(id, expected, got) {\r\n return new Error(`id-dom: expected ${expected} for ${fmtId(id)}, got ${got}`)\r\n}\r\n\r\n/**\r\n * Centralized error policy:\r\n * - always call onError if present\r\n * - optionally warn\r\n * - throw or return null depending on mode\r\n *\r\n * @template T\r\n * @param {Error} err\r\n * @param {any} ctx\r\n * @param {ReturnType<typeof normalizeConfig>} cfg\r\n * @returns {T | null}\r\n */\r\nfunction handleLookupError(err, ctx, cfg) {\r\n try {\r\n cfg.onError?.(err, ctx)\r\n } catch {\r\n // do not let reporting break app logic\r\n }\r\n\r\n if (cfg.warn) console.warn(err)\r\n\r\n if (cfg.mode === 'throw') throw err\r\n return null\r\n}\r\n\r\n/**\r\n * Typed lookup by ID.\r\n * Behavior is controlled by config:\r\n * - mode: 'throw' (default) or 'null'\r\n * - warn: boolean\r\n * - onError(err, ctx)\r\n *\r\n * @template {Element} T\r\n * @param {string} id\r\n * @param {{ new (...args: any[]): T }} Type\r\n * @param {DomConfig} [config]\r\n * @returns {T | null}\r\n */\r\nexport function byId(id, Type, config) {\r\n const cfg = normalizeConfig(config)\r\n const el = getById(cfg.root, id)\r\n\r\n if (!el) {\r\n return handleLookupError(\r\n missingElError(id, Type.name),\r\n { id, Type, root: cfg.root, reason: 'missing' },\r\n cfg\r\n )\r\n }\r\n\r\n if (!(el instanceof Type)) {\r\n const got = el?.constructor?.name || typeof el\r\n return handleLookupError(\r\n wrongTypeError(id, Type.name, got),\r\n { id, Type, root: cfg.root, reason: 'wrong-type', got },\r\n cfg\r\n )\r\n }\r\n\r\n return el\r\n}\r\n\r\n/**\r\n * Optional typed lookup: ALWAYS returns T | null (never throws for missing/wrong-type).\r\n *\r\n * @template {Element} T\r\n * @param {string} id\r\n * @param {{ new (...args: any[]): T }} Type\r\n * @param {DomConfig} [config]\r\n * @returns {T | null}\r\n */\r\nbyId.optional = function byIdOptional(id, Type, config) {\r\n return byId(id, Type, { ...config, mode: 'null' })\r\n}\r\n\r\n// Short alias (module-level; do not reassign inside factories)\r\nbyId.opt = byId.optional\r\n\r\n/**\r\n * Tag-name lookup (HTMLElement only).\r\n * Useful for semantic elements that don\u2019t have unique constructors.\r\n *\r\n * @param {string} id\r\n * @param {string} tagName\r\n * @param {DomConfig} [config]\r\n * @returns {HTMLElement | null}\r\n */\r\nexport function tag(id, tagName, config) {\r\n const cfg = normalizeConfig(config)\r\n const el = getById(cfg.root, id)\r\n\r\n if (!el) {\r\n return handleLookupError(\r\n missingElError(id, `<${tagName}>`),\r\n { id, tagName, root: cfg.root, reason: 'missing' },\r\n cfg\r\n )\r\n }\r\n\r\n const expected = String(tagName).toUpperCase()\r\n const got = String(el.tagName || '').toUpperCase()\r\n\r\n if (got !== expected) {\r\n return handleLookupError(\r\n wrongTypeError(id, `<${expected.toLowerCase()}>`, `<${got.toLowerCase()}>`),\r\n { id, tagName, root: cfg.root, reason: 'wrong-tag', got },\r\n cfg\r\n )\r\n }\r\n\r\n return el\r\n}\r\n\r\n/**\r\n * Optional tag lookup: ALWAYS returns HTMLElement | null (never throws for missing/wrong-tag).\r\n *\r\n * @param {string} id\r\n * @param {string} tagName\r\n * @param {DomConfig} [config]\r\n * @returns {HTMLElement | null}\r\n */\r\ntag.optional = function tagOptional(id, tagName, config) {\r\n return tag(id, tagName, { ...config, mode: 'null' })\r\n}\r\n\r\n// Short alias (module-level; do not reassign inside factories)\r\ntag.opt = tag.optional\r\n\r\n// --- internal maps for factory helpers ---\r\nconst TYPE_HELPERS = /** @type {Record<string, any>} */ ({\r\n el: typeof HTMLElement !== 'undefined' ? HTMLElement : null,\r\n input: typeof HTMLInputElement !== 'undefined' ? HTMLInputElement : null,\r\n button: typeof HTMLButtonElement !== 'undefined' ? HTMLButtonElement : null,\r\n textarea: typeof HTMLTextAreaElement !== 'undefined' ? HTMLTextAreaElement : null,\r\n select: typeof HTMLSelectElement !== 'undefined' ? HTMLSelectElement : null,\r\n form: typeof HTMLFormElement !== 'undefined' ? HTMLFormElement : null,\r\n div: typeof HTMLDivElement !== 'undefined' ? HTMLDivElement : null,\r\n span: typeof HTMLSpanElement !== 'undefined' ? HTMLSpanElement : null,\r\n label: typeof HTMLLabelElement !== 'undefined' ? HTMLLabelElement : null,\r\n canvas: typeof HTMLCanvasElement !== 'undefined' ? HTMLCanvasElement : null,\r\n template: typeof HTMLTemplateElement !== 'undefined' ? HTMLTemplateElement : null,\r\n svg: typeof SVGSVGElement !== 'undefined' ? SVGSVGElement : null,\r\n})\r\n\r\nconst TAG_HELPERS = /** @type {Record<string, string>} */ ({\r\n main: 'main',\r\n section: 'section',\r\n small: 'small',\r\n})\r\n\r\n/**\r\n * Factory: scope getters to a specific root + default policy.\r\n *\r\n * @param {any} root\r\n * @param {Omit<DomConfig, 'root'>} [config]\r\n */\r\nexport function createDom(root, config) {\r\n const base = normalizeConfig({ ...config, root })\r\n const baseNull = { ...base, mode: 'null' }\r\n\r\n /** @type {any} */\r\n const api = {\r\n // generic\r\n byId: (id, Type) => byId(id, Type, base),\r\n tag: (id, name) => tag(id, name, base),\r\n }\r\n\r\n // typed helpers\r\n for (const [name, Type] of Object.entries(TYPE_HELPERS)) {\r\n if (!Type) continue\r\n api[name] = (id) => byId(id, Type, base)\r\n }\r\n\r\n // semantic tag helpers\r\n for (const [name, tagName] of Object.entries(TAG_HELPERS)) {\r\n api[name] = (id) => tag(id, tagName, base)\r\n }\r\n\r\n // --- Optional variants (policy-based; never swallow unrelated exceptions) ---\r\n api.byId.optional = (id, Type) => byId(id, Type, baseNull)\r\n api.byId.opt = api.byId.optional\r\n\r\n api.tag.optional = (id, name) => tag(id, name, baseNull)\r\n api.tag.opt = api.tag.optional\r\n\r\n // Add `.optional` + `.opt` to every helper using the same \"null\" policy\r\n for (const k of Object.keys(api)) {\r\n const fn = api[k]\r\n if (typeof fn !== 'function') continue\r\n if (fn.optional) continue\r\n\r\n if (k in TAG_HELPERS) {\r\n const tagName = TAG_HELPERS[k]\r\n fn.optional = (id) => tag(id, tagName, baseNull)\r\n fn.opt = fn.optional\r\n continue\r\n }\r\n\r\n if (k in TYPE_HELPERS) {\r\n const Type = TYPE_HELPERS[k]\r\n if (Type) {\r\n fn.optional = (id) => byId(id, Type, baseNull)\r\n fn.opt = fn.optional\r\n }\r\n }\r\n }\r\n\r\n return api\r\n}\r\n\r\n// Default export: root = document (if available), strict by default\r\nconst dom = createDom(DEFAULT_ROOT, { mode: 'throw' })\r\nexport default dom\r\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,MAAM,eACF,OAAO,aAAa,eAAe,WAAW;AAAA;AAAA,EAA+B;AAAA;
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["// id-dom.js\n// id-dom \u2014 deterministic DOM element getters by ID (typed, tiny, modern)\n//\n// Goals:\n// - Prefer getElementById (fast, unambiguous)\n// - Return the correct type or fail predictably\n// - Provide strict + optional variants\n// - Allow app/module-level defaults (throw vs null) without bundler magic\n// - Zero deps, framework-agnostic\n\nconst DEFAULT_ROOT =\n typeof document !== 'undefined' && document ? document : /** @type {any} */ (null)\n\nconst REASON = /** @type {const} */ ({\n INVALID_ID: 'invalid-id',\n INVALID_TYPE: 'invalid-type',\n INVALID_TAG: 'invalid-tag',\n MISSING: 'missing',\n WRONG_TYPE: 'wrong-type',\n WRONG_TAG: 'wrong-tag',\n})\n\nconst SAFE_ID_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/\nconst NEEDS_START_ESCAPE_RE = /^(?:\\d|-\\d)/\n\n/**\n * @typedef {'throw' | 'null'} DomMode\n */\n\n/**\n * @typedef {{\n * mode?: DomMode\n * warn?: boolean\n * onError?: (error: Error, ctx: any) => void\n * root?: any\n * }} DomConfig\n */\n\n// -----------------------------------------------------------------------------\n// Config\n// -----------------------------------------------------------------------------\n\n/**\n * @param {DomConfig | undefined} cfg\n */\nfunction normalizeConfig(cfg) {\n return {\n mode: cfg?.mode ?? 'throw',\n warn: cfg?.warn ?? false,\n onError: typeof cfg?.onError === 'function' ? cfg.onError : null,\n root: cfg?.root ?? DEFAULT_ROOT,\n }\n}\n\n// -----------------------------------------------------------------------------\n// Root / DOM helpers\n// -----------------------------------------------------------------------------\n\n/**\n * @param {unknown} v\n * @returns {v is { getElementById(id: string): Element | null }}\n */\nfunction hasGetElementById(v) {\n return !!v && typeof v === 'object' && typeof v.getElementById === 'function'\n}\n\n/**\n * @param {unknown} v\n * @returns {v is { querySelector(sel: string): Element | null }}\n */\nfunction hasQuerySelector(v) {\n return !!v && typeof v === 'object' && typeof v.querySelector === 'function'\n}\n\n/**\n * Minimal CSS.escape fallback for environments where CSS.escape is missing.\n * We only need to safely build `#${id}` selectors.\n *\n * @param {string} id\n * @returns {string}\n */\nfunction cssEscape(id) {\n const s = String(id)\n\n if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\n return CSS.escape(s)\n }\n\n if (!NEEDS_START_ESCAPE_RE.test(s) && SAFE_ID_RE.test(s)) return s\n\n let out = ''\n for (let i = 0; i < s.length;) {\n const cp = s.codePointAt(i)\n const ch = String.fromCodePoint(cp)\n\n const isAsciiSafe =\n (cp >= 48 && cp <= 57) || // 0-9\n (cp >= 65 && cp <= 90) || // A-Z\n (cp >= 97 && cp <= 122) || // a-z\n cp === 95 || // _\n cp === 45 // -\n\n const next = s.codePointAt(i + 1)\n const startsWithDigit = cp >= 48 && cp <= 57\n const startsWithDashDigit = cp === 45 && s.length > 1 && next >= 48 && next <= 57\n const needsStartEscape = i === 0 && (startsWithDigit || startsWithDashDigit)\n\n if (!needsStartEscape && (isAsciiSafe || cp >= 0x00a0)) {\n out += ch\n } else if (i === 0 && startsWithDashDigit) {\n out += '\\\\-'\n } else {\n out += `\\\\${cp.toString(16).toUpperCase()} `\n }\n\n i += ch.length\n }\n\n return out\n}\n\n/**\n * @param {unknown} v\n * @returns {v is Element}\n */\nfunction isElementNode(v) {\n if (!v || typeof v !== 'object') return false\n if (typeof Element !== 'undefined') return v instanceof Element\n return /** @type {any} */ (v).nodeType === 1\n}\n\n/**\n * Resolve an element by id from a root.\n * Supports:\n * - Document (getElementById)\n * - ShadowRoot / DocumentFragment / Element (querySelector fallback)\n *\n * @param {any} root\n * @param {string} id\n * @returns {Element | null}\n */\nfunction getById(root, id) {\n if (!root) return null\n\n if (hasGetElementById(root)) return root.getElementById(id)\n\n if (hasQuerySelector(root)) {\n const el = root.querySelector(`#${cssEscape(id)}`)\n return isElementNode(el) ? el : null\n }\n\n return null\n}\n\n// -----------------------------------------------------------------------------\n// Validation helpers\n// -----------------------------------------------------------------------------\n\n/**\n * @param {unknown} v\n * @returns {v is string}\n */\nfunction isValidId(v) {\n return typeof v === 'string' && v.length > 0\n}\n\n/**\n * @param {unknown} v\n * @returns {v is string}\n */\nfunction isValidTagName(v) {\n return typeof v === 'string' && v.trim().length > 0\n}\n\n/**\n * @param {unknown} v\n * @returns {v is Function}\n */\nfunction isConstructor(v) {\n return typeof v === 'function'\n}\n\n// -----------------------------------------------------------------------------\n// Error / policy helpers\n// -----------------------------------------------------------------------------\n\n/**\n * @param {string} id\n * @returns {string}\n */\nfunction fmtId(id) {\n return id.startsWith('#') ? id : `#${id}`\n}\n\n/**\n * @param {string} id\n * @param {string} expected\n * @returns {Error}\n */\nfunction missingElError(id, expected) {\n return new Error(`id-dom: missing ${expected} element ${fmtId(id)}`)\n}\n\n/**\n * @param {string} id\n * @param {string} expected\n * @param {string} got\n * @returns {Error}\n */\nfunction wrongTypeError(id, expected, got) {\n return new Error(`id-dom: expected ${expected} for ${fmtId(id)}, got ${got}`)\n}\n\n/**\n * @template T\n * @param {Error} err\n * @param {any} ctx\n * @param {ReturnType<typeof normalizeConfig>} cfg\n * @returns {T | null}\n */\nfunction handleLookupError(err, ctx, cfg) {\n try {\n cfg.onError?.(err, ctx)\n } catch {\n // reporting must never break app logic\n }\n\n if (cfg.warn) console.warn(err, ctx)\n\n if (cfg.mode === 'throw') throw err\n return null\n}\n\n/**\n * @param {string} id\n * @param {any} root\n * @param {string} reason\n * @param {object} [extra]\n * @returns {any}\n */\nfunction createCtx(id, root, reason, extra) {\n return {\n id,\n root,\n reason,\n ...(extra || {}),\n }\n}\n\n// -----------------------------------------------------------------------------\n// Internal generic resolver\n// -----------------------------------------------------------------------------\n\n/**\n * @template T\n * @param {DomConfig | undefined} config\n * @param {{\n * id: string,\n * validateInput: (cfg: ReturnType<typeof normalizeConfig>) => { err: Error, ctx: any } | null,\n * onMissing: (cfg: ReturnType<typeof normalizeConfig>) => { err: Error, ctx: any },\n * matches: (el: Element, cfg: ReturnType<typeof normalizeConfig>) => boolean,\n * onMismatch: (el: Element, cfg: ReturnType<typeof normalizeConfig>) => { err: Error, ctx: any },\n * }} spec\n * @returns {T | null}\n */\nfunction resolveLookup(config, spec) {\n const cfg = normalizeConfig(config)\n\n const inputFailure = spec.validateInput(cfg)\n if (inputFailure) {\n return handleLookupError(inputFailure.err, inputFailure.ctx, cfg)\n }\n\n const el = getById(cfg.root, spec.id)\n if (!el) {\n const failure = spec.onMissing(cfg)\n return handleLookupError(failure.err, failure.ctx, cfg)\n }\n\n if (!spec.matches(el, cfg)) {\n const failure = spec.onMismatch(el, cfg)\n return handleLookupError(failure.err, failure.ctx, cfg)\n }\n\n return /** @type {T} */ (el)\n}\n\n// -----------------------------------------------------------------------------\n// Public APIs\n// -----------------------------------------------------------------------------\n\n/**\n * Typed lookup by ID.\n *\n * @template {Element} T\n * @param {string} id\n * @param {{ new (...args: any[]): T }} Type\n * @param {DomConfig} [config]\n * @returns {T | null}\n */\nexport function byId(id, Type, config) {\n return resolveLookup(config, {\n id,\n\n validateInput(cfg) {\n if (!isValidId(id)) {\n return {\n err: new Error('id-dom: invalid id (expected non-empty string)'),\n ctx: createCtx(String(id), cfg.root, REASON.INVALID_ID, { Type }),\n }\n }\n\n if (!isConstructor(Type)) {\n return {\n err: new Error(`id-dom: invalid Type for ${fmtId(id)}`),\n ctx: createCtx(id, cfg.root, REASON.INVALID_TYPE, { Type }),\n }\n }\n\n return null\n },\n\n onMissing(cfg) {\n return {\n err: missingElError(id, Type.name),\n ctx: createCtx(id, cfg.root, REASON.MISSING, { Type }),\n }\n },\n\n matches(el) {\n return el instanceof Type\n },\n\n onMismatch(el, cfg) {\n const got = el?.constructor?.name || typeof el\n return {\n err: wrongTypeError(id, Type.name, got),\n ctx: createCtx(id, cfg.root, REASON.WRONG_TYPE, { Type, got }),\n }\n },\n })\n}\n\n/**\n * Optional typed lookup: always returns T | null.\n *\n * @template {Element} T\n * @param {string} id\n * @param {{ new (...args: any[]): T }} Type\n * @param {DomConfig} [config]\n * @returns {T | null}\n */\nbyId.optional = function byIdOptional(id, Type, config) {\n return byId(id, Type, { ...config, mode: 'null' })\n}\n\nbyId.opt = byId.optional\n\n/**\n * Tag-name lookup by element tag.\n * Useful when constructor checks are not the right fit.\n *\n * @param {string} id\n * @param {string} tagName\n * @param {DomConfig} [config]\n * @returns {Element | null}\n */\nexport function tag(id, tagName, config) {\n return resolveLookup(config, {\n id,\n\n validateInput(cfg) {\n if (!isValidId(id)) {\n return {\n err: new Error('id-dom: invalid id (expected non-empty string)'),\n ctx: createCtx(String(id), cfg.root, REASON.INVALID_ID, { tagName }),\n }\n }\n\n if (!isValidTagName(tagName)) {\n return {\n err: new Error(`id-dom: invalid tagName for ${fmtId(id)}`),\n ctx: createCtx(id, cfg.root, REASON.INVALID_TAG, { tagName }),\n }\n }\n\n return null\n },\n\n onMissing(cfg) {\n return {\n err: missingElError(id, `<${tagName}>`),\n ctx: createCtx(id, cfg.root, REASON.MISSING, { tagName }),\n }\n },\n\n matches(el) {\n return String(el.tagName || '').toUpperCase() === String(tagName).toUpperCase()\n },\n\n onMismatch(el, cfg) {\n const expected = String(tagName).toUpperCase()\n const got = String(el.tagName || '').toUpperCase()\n\n return {\n err: wrongTypeError(id, `<${expected.toLowerCase()}>`, `<${got.toLowerCase()}>`),\n ctx: createCtx(id, cfg.root, REASON.WRONG_TAG, { tagName, got }),\n }\n },\n })\n}\n\n/**\n * Optional tag lookup: always returns Element | null.\n *\n * @param {string} id\n * @param {string} tagName\n * @param {DomConfig} [config]\n * @returns {Element | null}\n */\ntag.optional = function tagOptional(id, tagName, config) {\n return tag(id, tagName, { ...config, mode: 'null' })\n}\n\ntag.opt = tag.optional\n\n// -----------------------------------------------------------------------------\n// Helper registries\n// -----------------------------------------------------------------------------\n\nconst TYPE_HELPERS = /** @type {Record<string, any>} */ ({\n el: typeof HTMLElement !== 'undefined' ? HTMLElement : null,\n input: typeof HTMLInputElement !== 'undefined' ? HTMLInputElement : null,\n button: typeof HTMLButtonElement !== 'undefined' ? HTMLButtonElement : null,\n textarea: typeof HTMLTextAreaElement !== 'undefined' ? HTMLTextAreaElement : null,\n select: typeof HTMLSelectElement !== 'undefined' ? HTMLSelectElement : null,\n form: typeof HTMLFormElement !== 'undefined' ? HTMLFormElement : null,\n div: typeof HTMLDivElement !== 'undefined' ? HTMLDivElement : null,\n span: typeof HTMLSpanElement !== 'undefined' ? HTMLSpanElement : null,\n label: typeof HTMLLabelElement !== 'undefined' ? HTMLLabelElement : null,\n canvas: typeof HTMLCanvasElement !== 'undefined' ? HTMLCanvasElement : null,\n template: typeof HTMLTemplateElement !== 'undefined' ? HTMLTemplateElement : null,\n svg: typeof SVGSVGElement !== 'undefined' ? SVGSVGElement : null,\n body: typeof HTMLBodyElement !== 'undefined' ? HTMLBodyElement : null,\n})\n\nconst TAG_HELPERS = /** @type {Record<string, string>} */ ({\n main: 'main',\n section: 'section',\n small: 'small',\n})\n\n// -----------------------------------------------------------------------------\n// Helper builders\n// -----------------------------------------------------------------------------\n\n/**\n * @template {Function} T\n * @param {T} fn\n * @param {Function} optionalFn\n * @returns {T & { optional: Function, opt: Function }}\n */\nfunction attachOptional(fn, optionalFn) {\n if (typeof fn !== 'function') {\n throw new TypeError('id-dom: attachOptional expected fn to be a function')\n }\n\n if (typeof optionalFn !== 'function') {\n throw new TypeError('id-dom: attachOptional expected optionalFn to be a function')\n }\n\n fn.optional = optionalFn\n fn.opt = optionalFn\n return fn\n}\n\n/**\n * @param {any} Type\n * @param {ReturnType<typeof normalizeConfig>} base\n * @param {ReturnType<typeof normalizeConfig>} baseNull\n */\nfunction makeTypedHelper(Type, base, baseNull) {\n if (!Type) {\n throw new TypeError('id-dom: makeTypedHelper received an invalid Type')\n }\n\n return attachOptional(\n (id) => byId(id, Type, base),\n (id) => byId(id, Type, baseNull)\n )\n}\n\n/**\n * @param {string} tagName\n * @param {ReturnType<typeof normalizeConfig>} base\n * @param {ReturnType<typeof normalizeConfig>} baseNull\n */\nfunction makeTagHelper(tagName, base, baseNull) {\n if (!tagName) {\n throw new TypeError('id-dom: makeTagHelper received an invalid tagName')\n }\n\n return attachOptional(\n (id) => tag(id, tagName, base),\n (id) => tag(id, tagName, baseNull)\n )\n}\n// -----------------------------------------------------------------------------\n// Factory\n// -----------------------------------------------------------------------------\n\n/**\n * Factory: scope getters to a specific root + default policy.\n *\n * @param {any} root\n * @param {Omit<DomConfig, 'root'>} [config]\n */\nexport function createDom(root, config) {\n const base = normalizeConfig({ ...config, root })\n const baseNull = { ...base, mode: 'null' }\n\n /** @type {any} */\n const api = {}\n\n api.byId = attachOptional(\n (id, Type) => byId(id, Type, base),\n (id, Type) => byId(id, Type, baseNull)\n )\n\n api.tag = attachOptional(\n (id, name) => tag(id, name, base),\n (id, name) => tag(id, name, baseNull)\n )\n\n for (const [name, Type] of Object.entries(TYPE_HELPERS)) {\n if (!Type) continue\n api[name] = makeTypedHelper(Type, base, baseNull)\n }\n\n for (const [name, tagName] of Object.entries(TAG_HELPERS)) {\n api[name] = makeTagHelper(tagName, base, baseNull)\n }\n\n return api\n}\n\n// -----------------------------------------------------------------------------\n// Default-root config (shared by the default export and the named typed helpers)\n// -----------------------------------------------------------------------------\n\nconst DEFAULT_BASE = normalizeConfig({ mode: 'throw', root: DEFAULT_ROOT })\nconst DEFAULT_BASE_NULL = { ...DEFAULT_BASE, mode: 'null' }\n\n/**\n * Build a typed helper bound to the default root.\n * Internal \u2014 exposed via the per-helper named exports below.\n *\n * @param {any} Type\n */\nfunction defaultTypedHelper(Type) {\n return Type ? makeTypedHelper(Type, DEFAULT_BASE, DEFAULT_BASE_NULL) : null\n}\n\n/**\n * Build a tag-name helper bound to the default root.\n *\n * @param {string} tagName\n */\nfunction defaultTagHelper(tagName) {\n return makeTagHelper(tagName, DEFAULT_BASE, DEFAULT_BASE_NULL)\n}\n\n// -----------------------------------------------------------------------------\n// Named typed-element helpers (per-helper exports \u2014 tree-shakeable)\n//\n// Each one is a `const` initialized to a tiny closure produced by\n// makeTypedHelper. Modern bundlers (esbuild, rollup, vite) drop the\n// unused ones because the package declares sideEffects: false.\n//\n// SSR-safe: in environments where the corresponding global constructor\n// isn't defined (Node without jsdom, etc.), the export is `null` rather\n// than a thrown construction error.\n// -----------------------------------------------------------------------------\n\nexport const el = defaultTypedHelper(typeof HTMLElement !== 'undefined' ? HTMLElement : null)\nexport const input = defaultTypedHelper(typeof HTMLInputElement !== 'undefined' ? HTMLInputElement : null)\nexport const button = defaultTypedHelper(typeof HTMLButtonElement !== 'undefined' ? HTMLButtonElement : null)\nexport const textarea = defaultTypedHelper(typeof HTMLTextAreaElement !== 'undefined' ? HTMLTextAreaElement : null)\nexport const select = defaultTypedHelper(typeof HTMLSelectElement !== 'undefined' ? HTMLSelectElement : null)\nexport const form = defaultTypedHelper(typeof HTMLFormElement !== 'undefined' ? HTMLFormElement : null)\nexport const div = defaultTypedHelper(typeof HTMLDivElement !== 'undefined' ? HTMLDivElement : null)\nexport const span = defaultTypedHelper(typeof HTMLSpanElement !== 'undefined' ? HTMLSpanElement : null)\nexport const label = defaultTypedHelper(typeof HTMLLabelElement !== 'undefined' ? HTMLLabelElement : null)\nexport const canvas = defaultTypedHelper(typeof HTMLCanvasElement !== 'undefined' ? HTMLCanvasElement : null)\nexport const template = defaultTypedHelper(typeof HTMLTemplateElement !== 'undefined' ? HTMLTemplateElement : null)\nexport const svg = defaultTypedHelper(typeof SVGSVGElement !== 'undefined' ? SVGSVGElement : null)\nexport const body = defaultTypedHelper(typeof HTMLBodyElement !== 'undefined' ? HTMLBodyElement : null)\n\n// Named tag-name helpers (no dedicated constructor)\nexport const main = defaultTagHelper('main')\nexport const section = defaultTagHelper('section')\nexport const small = defaultTagHelper('small')\n\n// -----------------------------------------------------------------------------\n// Default export \u2014 the convenience object aggregating every helper. Use\n// named imports above for tree-shake-friendly bundles; use this default\n// when you want all helpers under one namespace (`dom.button(\u2026)`).\n// -----------------------------------------------------------------------------\n\nconst dom = createDom(DEFAULT_ROOT, { mode: 'throw' })\nexport default dom"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["el"]
|
|
7
7
|
}
|
package/dist/index.js
CHANGED
|
@@ -2,10 +2,22 @@ const DEFAULT_ROOT = typeof document !== "undefined" && document ? document : (
|
|
|
2
2
|
/** @type {any} */
|
|
3
3
|
null
|
|
4
4
|
);
|
|
5
|
+
const REASON = (
|
|
6
|
+
/** @type {const} */
|
|
7
|
+
{
|
|
8
|
+
INVALID_ID: "invalid-id",
|
|
9
|
+
INVALID_TYPE: "invalid-type",
|
|
10
|
+
INVALID_TAG: "invalid-tag",
|
|
11
|
+
MISSING: "missing",
|
|
12
|
+
WRONG_TYPE: "wrong-type",
|
|
13
|
+
WRONG_TAG: "wrong-tag"
|
|
14
|
+
}
|
|
15
|
+
);
|
|
16
|
+
const SAFE_ID_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
|
|
17
|
+
const NEEDS_START_ESCAPE_RE = /^(?:\d|-\d)/;
|
|
5
18
|
function normalizeConfig(cfg) {
|
|
6
19
|
return {
|
|
7
20
|
mode: cfg?.mode ?? "throw",
|
|
8
|
-
// default strict
|
|
9
21
|
warn: cfg?.warn ?? false,
|
|
10
22
|
onError: typeof cfg?.onError === "function" ? cfg.onError : null,
|
|
11
23
|
root: cfg?.root ?? DEFAULT_ROOT
|
|
@@ -17,8 +29,6 @@ function hasGetElementById(v) {
|
|
|
17
29
|
function hasQuerySelector(v) {
|
|
18
30
|
return !!v && typeof v === "object" && typeof v.querySelector === "function";
|
|
19
31
|
}
|
|
20
|
-
const SAFE_ID_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
|
|
21
|
-
const NEEDS_START_ESCAPE_RE = /^(?:\d|-\d)/;
|
|
22
32
|
function cssEscape(id) {
|
|
23
33
|
const s = String(id);
|
|
24
34
|
if (typeof CSS !== "undefined" && typeof CSS.escape === "function") {
|
|
@@ -34,10 +44,13 @@ function cssEscape(id) {
|
|
|
34
44
|
cp >= 97 && cp <= 122 || // a-z
|
|
35
45
|
cp === 95 || // _
|
|
36
46
|
cp === 45;
|
|
37
|
-
const
|
|
47
|
+
const next = s.codePointAt(i + 1);
|
|
48
|
+
const startsWithDigit = cp >= 48 && cp <= 57;
|
|
49
|
+
const startsWithDashDigit = cp === 45 && s.length > 1 && next >= 48 && next <= 57;
|
|
50
|
+
const needsStartEscape = i === 0 && (startsWithDigit || startsWithDashDigit);
|
|
38
51
|
if (!needsStartEscape && (isAsciiSafe || cp >= 160)) {
|
|
39
52
|
out += ch;
|
|
40
|
-
} else if (
|
|
53
|
+
} else if (i === 0 && startsWithDashDigit) {
|
|
41
54
|
out += "\\-";
|
|
42
55
|
} else {
|
|
43
56
|
out += `\\${cp.toString(16).toUpperCase()} `;
|
|
@@ -46,16 +59,32 @@ function cssEscape(id) {
|
|
|
46
59
|
}
|
|
47
60
|
return out;
|
|
48
61
|
}
|
|
62
|
+
function isElementNode(v) {
|
|
63
|
+
if (!v || typeof v !== "object") return false;
|
|
64
|
+
if (typeof Element !== "undefined") return v instanceof Element;
|
|
65
|
+
return (
|
|
66
|
+
/** @type {any} */
|
|
67
|
+
v.nodeType === 1
|
|
68
|
+
);
|
|
69
|
+
}
|
|
49
70
|
function getById(root, id) {
|
|
50
71
|
if (!root) return null;
|
|
51
72
|
if (hasGetElementById(root)) return root.getElementById(id);
|
|
52
73
|
if (hasQuerySelector(root)) {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
return el instanceof HTMLElement ? el : null;
|
|
74
|
+
const el2 = root.querySelector(`#${cssEscape(id)}`);
|
|
75
|
+
return isElementNode(el2) ? el2 : null;
|
|
56
76
|
}
|
|
57
77
|
return null;
|
|
58
78
|
}
|
|
79
|
+
function isValidId(v) {
|
|
80
|
+
return typeof v === "string" && v.length > 0;
|
|
81
|
+
}
|
|
82
|
+
function isValidTagName(v) {
|
|
83
|
+
return typeof v === "string" && v.trim().length > 0;
|
|
84
|
+
}
|
|
85
|
+
function isConstructor(v) {
|
|
86
|
+
return typeof v === "function";
|
|
87
|
+
}
|
|
59
88
|
function fmtId(id) {
|
|
60
89
|
return id.startsWith("#") ? id : `#${id}`;
|
|
61
90
|
}
|
|
@@ -70,54 +99,114 @@ function handleLookupError(err, ctx, cfg) {
|
|
|
70
99
|
cfg.onError?.(err, ctx);
|
|
71
100
|
} catch {
|
|
72
101
|
}
|
|
73
|
-
if (cfg.warn) console.warn(err);
|
|
102
|
+
if (cfg.warn) console.warn(err, ctx);
|
|
74
103
|
if (cfg.mode === "throw") throw err;
|
|
75
104
|
return null;
|
|
76
105
|
}
|
|
77
|
-
function
|
|
106
|
+
function createCtx(id, root, reason, extra) {
|
|
107
|
+
return {
|
|
108
|
+
id,
|
|
109
|
+
root,
|
|
110
|
+
reason,
|
|
111
|
+
...extra || {}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function resolveLookup(config, spec) {
|
|
78
115
|
const cfg = normalizeConfig(config);
|
|
79
|
-
const
|
|
80
|
-
if (
|
|
81
|
-
return handleLookupError(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
116
|
+
const inputFailure = spec.validateInput(cfg);
|
|
117
|
+
if (inputFailure) {
|
|
118
|
+
return handleLookupError(inputFailure.err, inputFailure.ctx, cfg);
|
|
119
|
+
}
|
|
120
|
+
const el2 = getById(cfg.root, spec.id);
|
|
121
|
+
if (!el2) {
|
|
122
|
+
const failure = spec.onMissing(cfg);
|
|
123
|
+
return handleLookupError(failure.err, failure.ctx, cfg);
|
|
124
|
+
}
|
|
125
|
+
if (!spec.matches(el2, cfg)) {
|
|
126
|
+
const failure = spec.onMismatch(el2, cfg);
|
|
127
|
+
return handleLookupError(failure.err, failure.ctx, cfg);
|
|
128
|
+
}
|
|
129
|
+
return (
|
|
130
|
+
/** @type {T} */
|
|
131
|
+
el2
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
function byId(id, Type, config) {
|
|
135
|
+
return resolveLookup(config, {
|
|
136
|
+
id,
|
|
137
|
+
validateInput(cfg) {
|
|
138
|
+
if (!isValidId(id)) {
|
|
139
|
+
return {
|
|
140
|
+
err: new Error("id-dom: invalid id (expected non-empty string)"),
|
|
141
|
+
ctx: createCtx(String(id), cfg.root, REASON.INVALID_ID, { Type })
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
if (!isConstructor(Type)) {
|
|
145
|
+
return {
|
|
146
|
+
err: new Error(`id-dom: invalid Type for ${fmtId(id)}`),
|
|
147
|
+
ctx: createCtx(id, cfg.root, REASON.INVALID_TYPE, { Type })
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
},
|
|
152
|
+
onMissing(cfg) {
|
|
153
|
+
return {
|
|
154
|
+
err: missingElError(id, Type.name),
|
|
155
|
+
ctx: createCtx(id, cfg.root, REASON.MISSING, { Type })
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
matches(el2) {
|
|
159
|
+
return el2 instanceof Type;
|
|
160
|
+
},
|
|
161
|
+
onMismatch(el2, cfg) {
|
|
162
|
+
const got = el2?.constructor?.name || typeof el2;
|
|
163
|
+
return {
|
|
164
|
+
err: wrongTypeError(id, Type.name, got),
|
|
165
|
+
ctx: createCtx(id, cfg.root, REASON.WRONG_TYPE, { Type, got })
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
});
|
|
96
169
|
}
|
|
97
170
|
byId.optional = function byIdOptional(id, Type, config) {
|
|
98
171
|
return byId(id, Type, { ...config, mode: "null" });
|
|
99
172
|
};
|
|
100
173
|
byId.opt = byId.optional;
|
|
101
174
|
function tag(id, tagName, config) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
175
|
+
return resolveLookup(config, {
|
|
176
|
+
id,
|
|
177
|
+
validateInput(cfg) {
|
|
178
|
+
if (!isValidId(id)) {
|
|
179
|
+
return {
|
|
180
|
+
err: new Error("id-dom: invalid id (expected non-empty string)"),
|
|
181
|
+
ctx: createCtx(String(id), cfg.root, REASON.INVALID_ID, { tagName })
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
if (!isValidTagName(tagName)) {
|
|
185
|
+
return {
|
|
186
|
+
err: new Error(`id-dom: invalid tagName for ${fmtId(id)}`),
|
|
187
|
+
ctx: createCtx(id, cfg.root, REASON.INVALID_TAG, { tagName })
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
},
|
|
192
|
+
onMissing(cfg) {
|
|
193
|
+
return {
|
|
194
|
+
err: missingElError(id, `<${tagName}>`),
|
|
195
|
+
ctx: createCtx(id, cfg.root, REASON.MISSING, { tagName })
|
|
196
|
+
};
|
|
197
|
+
},
|
|
198
|
+
matches(el2) {
|
|
199
|
+
return String(el2.tagName || "").toUpperCase() === String(tagName).toUpperCase();
|
|
200
|
+
},
|
|
201
|
+
onMismatch(el2, cfg) {
|
|
202
|
+
const expected = String(tagName).toUpperCase();
|
|
203
|
+
const got = String(el2.tagName || "").toUpperCase();
|
|
204
|
+
return {
|
|
205
|
+
err: wrongTypeError(id, `<${expected.toLowerCase()}>`, `<${got.toLowerCase()}>`),
|
|
206
|
+
ctx: createCtx(id, cfg.root, REASON.WRONG_TAG, { tagName, got })
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
});
|
|
121
210
|
}
|
|
122
211
|
tag.optional = function tagOptional(id, tagName, config) {
|
|
123
212
|
return tag(id, tagName, { ...config, mode: "null" });
|
|
@@ -137,7 +226,8 @@ const TYPE_HELPERS = (
|
|
|
137
226
|
label: typeof HTMLLabelElement !== "undefined" ? HTMLLabelElement : null,
|
|
138
227
|
canvas: typeof HTMLCanvasElement !== "undefined" ? HTMLCanvasElement : null,
|
|
139
228
|
template: typeof HTMLTemplateElement !== "undefined" ? HTMLTemplateElement : null,
|
|
140
|
-
svg: typeof SVGSVGElement !== "undefined" ? SVGSVGElement : null
|
|
229
|
+
svg: typeof SVGSVGElement !== "undefined" ? SVGSVGElement : null,
|
|
230
|
+
body: typeof HTMLBodyElement !== "undefined" ? HTMLBodyElement : null
|
|
141
231
|
}
|
|
142
232
|
);
|
|
143
233
|
const TAG_HELPERS = (
|
|
@@ -148,51 +238,102 @@ const TAG_HELPERS = (
|
|
|
148
238
|
small: "small"
|
|
149
239
|
}
|
|
150
240
|
);
|
|
241
|
+
function attachOptional(fn, optionalFn) {
|
|
242
|
+
if (typeof fn !== "function") {
|
|
243
|
+
throw new TypeError("id-dom: attachOptional expected fn to be a function");
|
|
244
|
+
}
|
|
245
|
+
if (typeof optionalFn !== "function") {
|
|
246
|
+
throw new TypeError("id-dom: attachOptional expected optionalFn to be a function");
|
|
247
|
+
}
|
|
248
|
+
fn.optional = optionalFn;
|
|
249
|
+
fn.opt = optionalFn;
|
|
250
|
+
return fn;
|
|
251
|
+
}
|
|
252
|
+
function makeTypedHelper(Type, base, baseNull) {
|
|
253
|
+
if (!Type) {
|
|
254
|
+
throw new TypeError("id-dom: makeTypedHelper received an invalid Type");
|
|
255
|
+
}
|
|
256
|
+
return attachOptional(
|
|
257
|
+
(id) => byId(id, Type, base),
|
|
258
|
+
(id) => byId(id, Type, baseNull)
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
function makeTagHelper(tagName, base, baseNull) {
|
|
262
|
+
if (!tagName) {
|
|
263
|
+
throw new TypeError("id-dom: makeTagHelper received an invalid tagName");
|
|
264
|
+
}
|
|
265
|
+
return attachOptional(
|
|
266
|
+
(id) => tag(id, tagName, base),
|
|
267
|
+
(id) => tag(id, tagName, baseNull)
|
|
268
|
+
);
|
|
269
|
+
}
|
|
151
270
|
function createDom(root, config) {
|
|
152
271
|
const base = normalizeConfig({ ...config, root });
|
|
153
272
|
const baseNull = { ...base, mode: "null" };
|
|
154
|
-
const api = {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
273
|
+
const api = {};
|
|
274
|
+
api.byId = attachOptional(
|
|
275
|
+
(id, Type) => byId(id, Type, base),
|
|
276
|
+
(id, Type) => byId(id, Type, baseNull)
|
|
277
|
+
);
|
|
278
|
+
api.tag = attachOptional(
|
|
279
|
+
(id, name) => tag(id, name, base),
|
|
280
|
+
(id, name) => tag(id, name, baseNull)
|
|
281
|
+
);
|
|
159
282
|
for (const [name, Type] of Object.entries(TYPE_HELPERS)) {
|
|
160
283
|
if (!Type) continue;
|
|
161
|
-
api[name] = (
|
|
284
|
+
api[name] = makeTypedHelper(Type, base, baseNull);
|
|
162
285
|
}
|
|
163
286
|
for (const [name, tagName] of Object.entries(TAG_HELPERS)) {
|
|
164
|
-
api[name] = (
|
|
165
|
-
}
|
|
166
|
-
api.byId.optional = (id, Type) => byId(id, Type, baseNull);
|
|
167
|
-
api.byId.opt = api.byId.optional;
|
|
168
|
-
api.tag.optional = (id, name) => tag(id, name, baseNull);
|
|
169
|
-
api.tag.opt = api.tag.optional;
|
|
170
|
-
for (const k of Object.keys(api)) {
|
|
171
|
-
const fn = api[k];
|
|
172
|
-
if (typeof fn !== "function") continue;
|
|
173
|
-
if (fn.optional) continue;
|
|
174
|
-
if (k in TAG_HELPERS) {
|
|
175
|
-
const tagName = TAG_HELPERS[k];
|
|
176
|
-
fn.optional = (id) => tag(id, tagName, baseNull);
|
|
177
|
-
fn.opt = fn.optional;
|
|
178
|
-
continue;
|
|
179
|
-
}
|
|
180
|
-
if (k in TYPE_HELPERS) {
|
|
181
|
-
const Type = TYPE_HELPERS[k];
|
|
182
|
-
if (Type) {
|
|
183
|
-
fn.optional = (id) => byId(id, Type, baseNull);
|
|
184
|
-
fn.opt = fn.optional;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
287
|
+
api[name] = makeTagHelper(tagName, base, baseNull);
|
|
187
288
|
}
|
|
188
289
|
return api;
|
|
189
290
|
}
|
|
291
|
+
const DEFAULT_BASE = normalizeConfig({ mode: "throw", root: DEFAULT_ROOT });
|
|
292
|
+
const DEFAULT_BASE_NULL = { ...DEFAULT_BASE, mode: "null" };
|
|
293
|
+
function defaultTypedHelper(Type) {
|
|
294
|
+
return Type ? makeTypedHelper(Type, DEFAULT_BASE, DEFAULT_BASE_NULL) : null;
|
|
295
|
+
}
|
|
296
|
+
function defaultTagHelper(tagName) {
|
|
297
|
+
return makeTagHelper(tagName, DEFAULT_BASE, DEFAULT_BASE_NULL);
|
|
298
|
+
}
|
|
299
|
+
const el = defaultTypedHelper(typeof HTMLElement !== "undefined" ? HTMLElement : null);
|
|
300
|
+
const input = defaultTypedHelper(typeof HTMLInputElement !== "undefined" ? HTMLInputElement : null);
|
|
301
|
+
const button = defaultTypedHelper(typeof HTMLButtonElement !== "undefined" ? HTMLButtonElement : null);
|
|
302
|
+
const textarea = defaultTypedHelper(typeof HTMLTextAreaElement !== "undefined" ? HTMLTextAreaElement : null);
|
|
303
|
+
const select = defaultTypedHelper(typeof HTMLSelectElement !== "undefined" ? HTMLSelectElement : null);
|
|
304
|
+
const form = defaultTypedHelper(typeof HTMLFormElement !== "undefined" ? HTMLFormElement : null);
|
|
305
|
+
const div = defaultTypedHelper(typeof HTMLDivElement !== "undefined" ? HTMLDivElement : null);
|
|
306
|
+
const span = defaultTypedHelper(typeof HTMLSpanElement !== "undefined" ? HTMLSpanElement : null);
|
|
307
|
+
const label = defaultTypedHelper(typeof HTMLLabelElement !== "undefined" ? HTMLLabelElement : null);
|
|
308
|
+
const canvas = defaultTypedHelper(typeof HTMLCanvasElement !== "undefined" ? HTMLCanvasElement : null);
|
|
309
|
+
const template = defaultTypedHelper(typeof HTMLTemplateElement !== "undefined" ? HTMLTemplateElement : null);
|
|
310
|
+
const svg = defaultTypedHelper(typeof SVGSVGElement !== "undefined" ? SVGSVGElement : null);
|
|
311
|
+
const body = defaultTypedHelper(typeof HTMLBodyElement !== "undefined" ? HTMLBodyElement : null);
|
|
312
|
+
const main = defaultTagHelper("main");
|
|
313
|
+
const section = defaultTagHelper("section");
|
|
314
|
+
const small = defaultTagHelper("small");
|
|
190
315
|
const dom = createDom(DEFAULT_ROOT, { mode: "throw" });
|
|
191
316
|
var id_dom_default = dom;
|
|
192
317
|
export {
|
|
318
|
+
body,
|
|
319
|
+
button,
|
|
193
320
|
byId,
|
|
321
|
+
canvas,
|
|
194
322
|
createDom,
|
|
195
323
|
id_dom_default as default,
|
|
196
|
-
|
|
324
|
+
div,
|
|
325
|
+
el,
|
|
326
|
+
form,
|
|
327
|
+
input,
|
|
328
|
+
label,
|
|
329
|
+
main,
|
|
330
|
+
section,
|
|
331
|
+
select,
|
|
332
|
+
small,
|
|
333
|
+
span,
|
|
334
|
+
svg,
|
|
335
|
+
tag,
|
|
336
|
+
template,
|
|
337
|
+
textarea
|
|
197
338
|
};
|
|
198
339
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/id-dom.js"],
|
|
4
|
-
"sourcesContent": ["// id-dom.js\r\n// id-dom \u2014 deterministic DOM element getters by ID (typed, tiny, modern)\r\n//\r\n// Goals:\r\n// - Prefer getElementById (fast, unambiguous)\r\n// - Return the correct type or fail predictably\r\n// - Provide strict + optional variants\r\n// - Allow app/module-level defaults (throw vs null) without bundler magic\r\n// - Zero deps, framework-agnostic\r\n\r\nconst DEFAULT_ROOT =\r\n typeof document !== 'undefined' && document ? document : /** @type {any} */ (null)\r\n\r\n/**\r\n * @typedef {'throw' | 'null'} DomMode\r\n */\r\n\r\n/**\r\n * @typedef {{\r\n * mode?: DomMode\r\n * warn?: boolean\r\n * onError?: (error: Error, ctx: any) => void\r\n * root?: any\r\n * }} DomConfig\r\n */\r\n\r\n/**\r\n * @param {DomConfig | undefined} cfg\r\n */\r\nfunction normalizeConfig(cfg) {\r\n return {\r\n mode: cfg?.mode ?? 'throw', // default strict\r\n warn: cfg?.warn ?? false,\r\n onError: typeof cfg?.onError === 'function' ? cfg.onError : null,\r\n root: cfg?.root ?? DEFAULT_ROOT,\r\n }\r\n}\r\n\r\n/**\r\n * @param {unknown} v\r\n * @returns {v is { getElementById(id: string): HTMLElement | null }}\r\n */\r\nfunction hasGetElementById(v) {\r\n return !!v && typeof v === 'object' && typeof v.getElementById === 'function'\r\n}\r\n\r\n/**\r\n * @param {unknown} v\r\n * @returns {v is { querySelector(sel: string): Element | null }}\r\n */\r\nfunction hasQuerySelector(v) {\r\n return !!v && typeof v === 'object' && typeof v.querySelector === 'function'\r\n}\r\n\r\n\r\nconst SAFE_ID_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/\r\nconst NEEDS_START_ESCAPE_RE = /^(?:\\d|-\\d)/\r\n\r\n/**\r\n * Minimal CSS.escape fallback for environments where CSS.escape is missing (e.g. some jsdom builds).\r\n * We only need to safely build `#${id}` selectors.\r\n *\r\n * @param {string} id\r\n */\r\nfunction cssEscape(id) {\r\n const s = String(id)\r\n\r\n // Prefer native when available\r\n if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\r\n return CSS.escape(s)\r\n }\r\n\r\n // Fast path: most app IDs are already safe\r\n if (!NEEDS_START_ESCAPE_RE.test(s) && SAFE_ID_RE.test(s)) return s\r\n\r\n // One-pass escape:\r\n // - Escape any char outside a conservative \"safe\" set\r\n // - Also escape the start if it begins with a digit OR \"-<digit>\"\r\n let out = ''\r\n for (let i = 0; i < s.length; ) {\r\n const cp = s.codePointAt(i)\r\n const ch = String.fromCodePoint(cp)\r\n\r\n const isAsciiSafe =\r\n (cp >= 48 && cp <= 57) || // 0-9\r\n (cp >= 65 && cp <= 90) || // A-Z\r\n (cp >= 97 && cp <= 122) || // a-z\r\n cp === 95 || // _\r\n cp === 45 // -\r\n\r\n const needsStartEscape =\r\n i === 0 && ((cp >= 48 && cp <= 57) || (cp === 45 && s.length > 1 && s.codePointAt(1) >= 48 && s.codePointAt(1) <= 57))\r\n\r\n if (!needsStartEscape && (isAsciiSafe || cp >= 0x00A0)) {\r\n // allow non-ascii chars directly (common CSS ident behavior)\r\n out += ch\r\n } else if (cp === 45 && i === 0 && s.length > 1 && s.codePointAt(1) >= 48 && s.codePointAt(1) <= 57) {\r\n // \"-<digit>\" start: escaping just the leading hyphen is a simple fix\r\n out += '\\\\-'\r\n } else {\r\n // hex escape + trailing space is safest\r\n out += `\\\\${cp.toString(16).toUpperCase()} `\r\n }\r\n\r\n i += ch.length\r\n }\r\n\r\n return out\r\n}\r\n\r\n\r\n/**\r\n * Resolve an element by id from a \"root\".\r\n * Supports:\r\n * - Document (getElementById)\r\n * - ShadowRoot / DocumentFragment / Element (querySelector fallback)\r\n *\r\n * @param {any} root\r\n * @param {string} id\r\n * @returns {HTMLElement | null}\r\n */\r\nfunction getById(root, id) {\r\n if (!root) return null\r\n\r\n if (hasGetElementById(root)) return root.getElementById(id)\r\n\r\n // ShadowRoot/DocumentFragment/Element don\u2019t have getElementById\r\n if (hasQuerySelector(root)) {\r\n const sel = `#${cssEscape(id)}`\r\n const el = root.querySelector(sel)\r\n return el instanceof HTMLElement ? el : null\r\n }\r\n\r\n return null\r\n}\r\n\r\n/**\r\n * @param {string} id\r\n * @returns {string}\r\n */\r\nfunction fmtId(id) {\r\n return id.startsWith('#') ? id : `#${id}`\r\n}\r\n\r\n/**\r\n * @param {string} id\r\n * @param {string} expected\r\n */\r\nfunction missingElError(id, expected) {\r\n return new Error(`id-dom: missing ${expected} element ${fmtId(id)}`)\r\n}\r\n\r\n/**\r\n * @param {string} id\r\n * @param {string} expected\r\n * @param {string} got\r\n */\r\nfunction wrongTypeError(id, expected, got) {\r\n return new Error(`id-dom: expected ${expected} for ${fmtId(id)}, got ${got}`)\r\n}\r\n\r\n/**\r\n * Centralized error policy:\r\n * - always call onError if present\r\n * - optionally warn\r\n * - throw or return null depending on mode\r\n *\r\n * @template T\r\n * @param {Error} err\r\n * @param {any} ctx\r\n * @param {ReturnType<typeof normalizeConfig>} cfg\r\n * @returns {T | null}\r\n */\r\nfunction handleLookupError(err, ctx, cfg) {\r\n try {\r\n cfg.onError?.(err, ctx)\r\n } catch {\r\n // do not let reporting break app logic\r\n }\r\n\r\n if (cfg.warn) console.warn(err)\r\n\r\n if (cfg.mode === 'throw') throw err\r\n return null\r\n}\r\n\r\n/**\r\n * Typed lookup by ID.\r\n * Behavior is controlled by config:\r\n * - mode: 'throw' (default) or 'null'\r\n * - warn: boolean\r\n * - onError(err, ctx)\r\n *\r\n * @template {Element} T\r\n * @param {string} id\r\n * @param {{ new (...args: any[]): T }} Type\r\n * @param {DomConfig} [config]\r\n * @returns {T | null}\r\n */\r\nexport function byId(id, Type, config) {\r\n const cfg = normalizeConfig(config)\r\n const el = getById(cfg.root, id)\r\n\r\n if (!el) {\r\n return handleLookupError(\r\n missingElError(id, Type.name),\r\n { id, Type, root: cfg.root, reason: 'missing' },\r\n cfg\r\n )\r\n }\r\n\r\n if (!(el instanceof Type)) {\r\n const got = el?.constructor?.name || typeof el\r\n return handleLookupError(\r\n wrongTypeError(id, Type.name, got),\r\n { id, Type, root: cfg.root, reason: 'wrong-type', got },\r\n cfg\r\n )\r\n }\r\n\r\n return el\r\n}\r\n\r\n/**\r\n * Optional typed lookup: ALWAYS returns T | null (never throws for missing/wrong-type).\r\n *\r\n * @template {Element} T\r\n * @param {string} id\r\n * @param {{ new (...args: any[]): T }} Type\r\n * @param {DomConfig} [config]\r\n * @returns {T | null}\r\n */\r\nbyId.optional = function byIdOptional(id, Type, config) {\r\n return byId(id, Type, { ...config, mode: 'null' })\r\n}\r\n\r\n// Short alias (module-level; do not reassign inside factories)\r\nbyId.opt = byId.optional\r\n\r\n/**\r\n * Tag-name lookup (HTMLElement only).\r\n * Useful for semantic elements that don\u2019t have unique constructors.\r\n *\r\n * @param {string} id\r\n * @param {string} tagName\r\n * @param {DomConfig} [config]\r\n * @returns {HTMLElement | null}\r\n */\r\nexport function tag(id, tagName, config) {\r\n const cfg = normalizeConfig(config)\r\n const el = getById(cfg.root, id)\r\n\r\n if (!el) {\r\n return handleLookupError(\r\n missingElError(id, `<${tagName}>`),\r\n { id, tagName, root: cfg.root, reason: 'missing' },\r\n cfg\r\n )\r\n }\r\n\r\n const expected = String(tagName).toUpperCase()\r\n const got = String(el.tagName || '').toUpperCase()\r\n\r\n if (got !== expected) {\r\n return handleLookupError(\r\n wrongTypeError(id, `<${expected.toLowerCase()}>`, `<${got.toLowerCase()}>`),\r\n { id, tagName, root: cfg.root, reason: 'wrong-tag', got },\r\n cfg\r\n )\r\n }\r\n\r\n return el\r\n}\r\n\r\n/**\r\n * Optional tag lookup: ALWAYS returns HTMLElement | null (never throws for missing/wrong-tag).\r\n *\r\n * @param {string} id\r\n * @param {string} tagName\r\n * @param {DomConfig} [config]\r\n * @returns {HTMLElement | null}\r\n */\r\ntag.optional = function tagOptional(id, tagName, config) {\r\n return tag(id, tagName, { ...config, mode: 'null' })\r\n}\r\n\r\n// Short alias (module-level; do not reassign inside factories)\r\ntag.opt = tag.optional\r\n\r\n// --- internal maps for factory helpers ---\r\nconst TYPE_HELPERS = /** @type {Record<string, any>} */ ({\r\n el: typeof HTMLElement !== 'undefined' ? HTMLElement : null,\r\n input: typeof HTMLInputElement !== 'undefined' ? HTMLInputElement : null,\r\n button: typeof HTMLButtonElement !== 'undefined' ? HTMLButtonElement : null,\r\n textarea: typeof HTMLTextAreaElement !== 'undefined' ? HTMLTextAreaElement : null,\r\n select: typeof HTMLSelectElement !== 'undefined' ? HTMLSelectElement : null,\r\n form: typeof HTMLFormElement !== 'undefined' ? HTMLFormElement : null,\r\n div: typeof HTMLDivElement !== 'undefined' ? HTMLDivElement : null,\r\n span: typeof HTMLSpanElement !== 'undefined' ? HTMLSpanElement : null,\r\n label: typeof HTMLLabelElement !== 'undefined' ? HTMLLabelElement : null,\r\n canvas: typeof HTMLCanvasElement !== 'undefined' ? HTMLCanvasElement : null,\r\n template: typeof HTMLTemplateElement !== 'undefined' ? HTMLTemplateElement : null,\r\n svg: typeof SVGSVGElement !== 'undefined' ? SVGSVGElement : null,\r\n})\r\n\r\nconst TAG_HELPERS = /** @type {Record<string, string>} */ ({\r\n main: 'main',\r\n section: 'section',\r\n small: 'small',\r\n})\r\n\r\n/**\r\n * Factory: scope getters to a specific root + default policy.\r\n *\r\n * @param {any} root\r\n * @param {Omit<DomConfig, 'root'>} [config]\r\n */\r\nexport function createDom(root, config) {\r\n const base = normalizeConfig({ ...config, root })\r\n const baseNull = { ...base, mode: 'null' }\r\n\r\n /** @type {any} */\r\n const api = {\r\n // generic\r\n byId: (id, Type) => byId(id, Type, base),\r\n tag: (id, name) => tag(id, name, base),\r\n }\r\n\r\n // typed helpers\r\n for (const [name, Type] of Object.entries(TYPE_HELPERS)) {\r\n if (!Type) continue\r\n api[name] = (id) => byId(id, Type, base)\r\n }\r\n\r\n // semantic tag helpers\r\n for (const [name, tagName] of Object.entries(TAG_HELPERS)) {\r\n api[name] = (id) => tag(id, tagName, base)\r\n }\r\n\r\n // --- Optional variants (policy-based; never swallow unrelated exceptions) ---\r\n api.byId.optional = (id, Type) => byId(id, Type, baseNull)\r\n api.byId.opt = api.byId.optional\r\n\r\n api.tag.optional = (id, name) => tag(id, name, baseNull)\r\n api.tag.opt = api.tag.optional\r\n\r\n // Add `.optional` + `.opt` to every helper using the same \"null\" policy\r\n for (const k of Object.keys(api)) {\r\n const fn = api[k]\r\n if (typeof fn !== 'function') continue\r\n if (fn.optional) continue\r\n\r\n if (k in TAG_HELPERS) {\r\n const tagName = TAG_HELPERS[k]\r\n fn.optional = (id) => tag(id, tagName, baseNull)\r\n fn.opt = fn.optional\r\n continue\r\n }\r\n\r\n if (k in TYPE_HELPERS) {\r\n const Type = TYPE_HELPERS[k]\r\n if (Type) {\r\n fn.optional = (id) => byId(id, Type, baseNull)\r\n fn.opt = fn.optional\r\n }\r\n }\r\n }\r\n\r\n return api\r\n}\r\n\r\n// Default export: root = document (if available), strict by default\r\nconst dom = createDom(DEFAULT_ROOT, { mode: 'throw' })\r\nexport default dom\r\n"],
|
|
5
|
-
"mappings": "AAUA,MAAM,eACF,OAAO,aAAa,eAAe,WAAW;AAAA;AAAA,EAA+B;AAAA;
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["// id-dom.js\n// id-dom \u2014 deterministic DOM element getters by ID (typed, tiny, modern)\n//\n// Goals:\n// - Prefer getElementById (fast, unambiguous)\n// - Return the correct type or fail predictably\n// - Provide strict + optional variants\n// - Allow app/module-level defaults (throw vs null) without bundler magic\n// - Zero deps, framework-agnostic\n\nconst DEFAULT_ROOT =\n typeof document !== 'undefined' && document ? document : /** @type {any} */ (null)\n\nconst REASON = /** @type {const} */ ({\n INVALID_ID: 'invalid-id',\n INVALID_TYPE: 'invalid-type',\n INVALID_TAG: 'invalid-tag',\n MISSING: 'missing',\n WRONG_TYPE: 'wrong-type',\n WRONG_TAG: 'wrong-tag',\n})\n\nconst SAFE_ID_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/\nconst NEEDS_START_ESCAPE_RE = /^(?:\\d|-\\d)/\n\n/**\n * @typedef {'throw' | 'null'} DomMode\n */\n\n/**\n * @typedef {{\n * mode?: DomMode\n * warn?: boolean\n * onError?: (error: Error, ctx: any) => void\n * root?: any\n * }} DomConfig\n */\n\n// -----------------------------------------------------------------------------\n// Config\n// -----------------------------------------------------------------------------\n\n/**\n * @param {DomConfig | undefined} cfg\n */\nfunction normalizeConfig(cfg) {\n return {\n mode: cfg?.mode ?? 'throw',\n warn: cfg?.warn ?? false,\n onError: typeof cfg?.onError === 'function' ? cfg.onError : null,\n root: cfg?.root ?? DEFAULT_ROOT,\n }\n}\n\n// -----------------------------------------------------------------------------\n// Root / DOM helpers\n// -----------------------------------------------------------------------------\n\n/**\n * @param {unknown} v\n * @returns {v is { getElementById(id: string): Element | null }}\n */\nfunction hasGetElementById(v) {\n return !!v && typeof v === 'object' && typeof v.getElementById === 'function'\n}\n\n/**\n * @param {unknown} v\n * @returns {v is { querySelector(sel: string): Element | null }}\n */\nfunction hasQuerySelector(v) {\n return !!v && typeof v === 'object' && typeof v.querySelector === 'function'\n}\n\n/**\n * Minimal CSS.escape fallback for environments where CSS.escape is missing.\n * We only need to safely build `#${id}` selectors.\n *\n * @param {string} id\n * @returns {string}\n */\nfunction cssEscape(id) {\n const s = String(id)\n\n if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\n return CSS.escape(s)\n }\n\n if (!NEEDS_START_ESCAPE_RE.test(s) && SAFE_ID_RE.test(s)) return s\n\n let out = ''\n for (let i = 0; i < s.length;) {\n const cp = s.codePointAt(i)\n const ch = String.fromCodePoint(cp)\n\n const isAsciiSafe =\n (cp >= 48 && cp <= 57) || // 0-9\n (cp >= 65 && cp <= 90) || // A-Z\n (cp >= 97 && cp <= 122) || // a-z\n cp === 95 || // _\n cp === 45 // -\n\n const next = s.codePointAt(i + 1)\n const startsWithDigit = cp >= 48 && cp <= 57\n const startsWithDashDigit = cp === 45 && s.length > 1 && next >= 48 && next <= 57\n const needsStartEscape = i === 0 && (startsWithDigit || startsWithDashDigit)\n\n if (!needsStartEscape && (isAsciiSafe || cp >= 0x00a0)) {\n out += ch\n } else if (i === 0 && startsWithDashDigit) {\n out += '\\\\-'\n } else {\n out += `\\\\${cp.toString(16).toUpperCase()} `\n }\n\n i += ch.length\n }\n\n return out\n}\n\n/**\n * @param {unknown} v\n * @returns {v is Element}\n */\nfunction isElementNode(v) {\n if (!v || typeof v !== 'object') return false\n if (typeof Element !== 'undefined') return v instanceof Element\n return /** @type {any} */ (v).nodeType === 1\n}\n\n/**\n * Resolve an element by id from a root.\n * Supports:\n * - Document (getElementById)\n * - ShadowRoot / DocumentFragment / Element (querySelector fallback)\n *\n * @param {any} root\n * @param {string} id\n * @returns {Element | null}\n */\nfunction getById(root, id) {\n if (!root) return null\n\n if (hasGetElementById(root)) return root.getElementById(id)\n\n if (hasQuerySelector(root)) {\n const el = root.querySelector(`#${cssEscape(id)}`)\n return isElementNode(el) ? el : null\n }\n\n return null\n}\n\n// -----------------------------------------------------------------------------\n// Validation helpers\n// -----------------------------------------------------------------------------\n\n/**\n * @param {unknown} v\n * @returns {v is string}\n */\nfunction isValidId(v) {\n return typeof v === 'string' && v.length > 0\n}\n\n/**\n * @param {unknown} v\n * @returns {v is string}\n */\nfunction isValidTagName(v) {\n return typeof v === 'string' && v.trim().length > 0\n}\n\n/**\n * @param {unknown} v\n * @returns {v is Function}\n */\nfunction isConstructor(v) {\n return typeof v === 'function'\n}\n\n// -----------------------------------------------------------------------------\n// Error / policy helpers\n// -----------------------------------------------------------------------------\n\n/**\n * @param {string} id\n * @returns {string}\n */\nfunction fmtId(id) {\n return id.startsWith('#') ? id : `#${id}`\n}\n\n/**\n * @param {string} id\n * @param {string} expected\n * @returns {Error}\n */\nfunction missingElError(id, expected) {\n return new Error(`id-dom: missing ${expected} element ${fmtId(id)}`)\n}\n\n/**\n * @param {string} id\n * @param {string} expected\n * @param {string} got\n * @returns {Error}\n */\nfunction wrongTypeError(id, expected, got) {\n return new Error(`id-dom: expected ${expected} for ${fmtId(id)}, got ${got}`)\n}\n\n/**\n * @template T\n * @param {Error} err\n * @param {any} ctx\n * @param {ReturnType<typeof normalizeConfig>} cfg\n * @returns {T | null}\n */\nfunction handleLookupError(err, ctx, cfg) {\n try {\n cfg.onError?.(err, ctx)\n } catch {\n // reporting must never break app logic\n }\n\n if (cfg.warn) console.warn(err, ctx)\n\n if (cfg.mode === 'throw') throw err\n return null\n}\n\n/**\n * @param {string} id\n * @param {any} root\n * @param {string} reason\n * @param {object} [extra]\n * @returns {any}\n */\nfunction createCtx(id, root, reason, extra) {\n return {\n id,\n root,\n reason,\n ...(extra || {}),\n }\n}\n\n// -----------------------------------------------------------------------------\n// Internal generic resolver\n// -----------------------------------------------------------------------------\n\n/**\n * @template T\n * @param {DomConfig | undefined} config\n * @param {{\n * id: string,\n * validateInput: (cfg: ReturnType<typeof normalizeConfig>) => { err: Error, ctx: any } | null,\n * onMissing: (cfg: ReturnType<typeof normalizeConfig>) => { err: Error, ctx: any },\n * matches: (el: Element, cfg: ReturnType<typeof normalizeConfig>) => boolean,\n * onMismatch: (el: Element, cfg: ReturnType<typeof normalizeConfig>) => { err: Error, ctx: any },\n * }} spec\n * @returns {T | null}\n */\nfunction resolveLookup(config, spec) {\n const cfg = normalizeConfig(config)\n\n const inputFailure = spec.validateInput(cfg)\n if (inputFailure) {\n return handleLookupError(inputFailure.err, inputFailure.ctx, cfg)\n }\n\n const el = getById(cfg.root, spec.id)\n if (!el) {\n const failure = spec.onMissing(cfg)\n return handleLookupError(failure.err, failure.ctx, cfg)\n }\n\n if (!spec.matches(el, cfg)) {\n const failure = spec.onMismatch(el, cfg)\n return handleLookupError(failure.err, failure.ctx, cfg)\n }\n\n return /** @type {T} */ (el)\n}\n\n// -----------------------------------------------------------------------------\n// Public APIs\n// -----------------------------------------------------------------------------\n\n/**\n * Typed lookup by ID.\n *\n * @template {Element} T\n * @param {string} id\n * @param {{ new (...args: any[]): T }} Type\n * @param {DomConfig} [config]\n * @returns {T | null}\n */\nexport function byId(id, Type, config) {\n return resolveLookup(config, {\n id,\n\n validateInput(cfg) {\n if (!isValidId(id)) {\n return {\n err: new Error('id-dom: invalid id (expected non-empty string)'),\n ctx: createCtx(String(id), cfg.root, REASON.INVALID_ID, { Type }),\n }\n }\n\n if (!isConstructor(Type)) {\n return {\n err: new Error(`id-dom: invalid Type for ${fmtId(id)}`),\n ctx: createCtx(id, cfg.root, REASON.INVALID_TYPE, { Type }),\n }\n }\n\n return null\n },\n\n onMissing(cfg) {\n return {\n err: missingElError(id, Type.name),\n ctx: createCtx(id, cfg.root, REASON.MISSING, { Type }),\n }\n },\n\n matches(el) {\n return el instanceof Type\n },\n\n onMismatch(el, cfg) {\n const got = el?.constructor?.name || typeof el\n return {\n err: wrongTypeError(id, Type.name, got),\n ctx: createCtx(id, cfg.root, REASON.WRONG_TYPE, { Type, got }),\n }\n },\n })\n}\n\n/**\n * Optional typed lookup: always returns T | null.\n *\n * @template {Element} T\n * @param {string} id\n * @param {{ new (...args: any[]): T }} Type\n * @param {DomConfig} [config]\n * @returns {T | null}\n */\nbyId.optional = function byIdOptional(id, Type, config) {\n return byId(id, Type, { ...config, mode: 'null' })\n}\n\nbyId.opt = byId.optional\n\n/**\n * Tag-name lookup by element tag.\n * Useful when constructor checks are not the right fit.\n *\n * @param {string} id\n * @param {string} tagName\n * @param {DomConfig} [config]\n * @returns {Element | null}\n */\nexport function tag(id, tagName, config) {\n return resolveLookup(config, {\n id,\n\n validateInput(cfg) {\n if (!isValidId(id)) {\n return {\n err: new Error('id-dom: invalid id (expected non-empty string)'),\n ctx: createCtx(String(id), cfg.root, REASON.INVALID_ID, { tagName }),\n }\n }\n\n if (!isValidTagName(tagName)) {\n return {\n err: new Error(`id-dom: invalid tagName for ${fmtId(id)}`),\n ctx: createCtx(id, cfg.root, REASON.INVALID_TAG, { tagName }),\n }\n }\n\n return null\n },\n\n onMissing(cfg) {\n return {\n err: missingElError(id, `<${tagName}>`),\n ctx: createCtx(id, cfg.root, REASON.MISSING, { tagName }),\n }\n },\n\n matches(el) {\n return String(el.tagName || '').toUpperCase() === String(tagName).toUpperCase()\n },\n\n onMismatch(el, cfg) {\n const expected = String(tagName).toUpperCase()\n const got = String(el.tagName || '').toUpperCase()\n\n return {\n err: wrongTypeError(id, `<${expected.toLowerCase()}>`, `<${got.toLowerCase()}>`),\n ctx: createCtx(id, cfg.root, REASON.WRONG_TAG, { tagName, got }),\n }\n },\n })\n}\n\n/**\n * Optional tag lookup: always returns Element | null.\n *\n * @param {string} id\n * @param {string} tagName\n * @param {DomConfig} [config]\n * @returns {Element | null}\n */\ntag.optional = function tagOptional(id, tagName, config) {\n return tag(id, tagName, { ...config, mode: 'null' })\n}\n\ntag.opt = tag.optional\n\n// -----------------------------------------------------------------------------\n// Helper registries\n// -----------------------------------------------------------------------------\n\nconst TYPE_HELPERS = /** @type {Record<string, any>} */ ({\n el: typeof HTMLElement !== 'undefined' ? HTMLElement : null,\n input: typeof HTMLInputElement !== 'undefined' ? HTMLInputElement : null,\n button: typeof HTMLButtonElement !== 'undefined' ? HTMLButtonElement : null,\n textarea: typeof HTMLTextAreaElement !== 'undefined' ? HTMLTextAreaElement : null,\n select: typeof HTMLSelectElement !== 'undefined' ? HTMLSelectElement : null,\n form: typeof HTMLFormElement !== 'undefined' ? HTMLFormElement : null,\n div: typeof HTMLDivElement !== 'undefined' ? HTMLDivElement : null,\n span: typeof HTMLSpanElement !== 'undefined' ? HTMLSpanElement : null,\n label: typeof HTMLLabelElement !== 'undefined' ? HTMLLabelElement : null,\n canvas: typeof HTMLCanvasElement !== 'undefined' ? HTMLCanvasElement : null,\n template: typeof HTMLTemplateElement !== 'undefined' ? HTMLTemplateElement : null,\n svg: typeof SVGSVGElement !== 'undefined' ? SVGSVGElement : null,\n body: typeof HTMLBodyElement !== 'undefined' ? HTMLBodyElement : null,\n})\n\nconst TAG_HELPERS = /** @type {Record<string, string>} */ ({\n main: 'main',\n section: 'section',\n small: 'small',\n})\n\n// -----------------------------------------------------------------------------\n// Helper builders\n// -----------------------------------------------------------------------------\n\n/**\n * @template {Function} T\n * @param {T} fn\n * @param {Function} optionalFn\n * @returns {T & { optional: Function, opt: Function }}\n */\nfunction attachOptional(fn, optionalFn) {\n if (typeof fn !== 'function') {\n throw new TypeError('id-dom: attachOptional expected fn to be a function')\n }\n\n if (typeof optionalFn !== 'function') {\n throw new TypeError('id-dom: attachOptional expected optionalFn to be a function')\n }\n\n fn.optional = optionalFn\n fn.opt = optionalFn\n return fn\n}\n\n/**\n * @param {any} Type\n * @param {ReturnType<typeof normalizeConfig>} base\n * @param {ReturnType<typeof normalizeConfig>} baseNull\n */\nfunction makeTypedHelper(Type, base, baseNull) {\n if (!Type) {\n throw new TypeError('id-dom: makeTypedHelper received an invalid Type')\n }\n\n return attachOptional(\n (id) => byId(id, Type, base),\n (id) => byId(id, Type, baseNull)\n )\n}\n\n/**\n * @param {string} tagName\n * @param {ReturnType<typeof normalizeConfig>} base\n * @param {ReturnType<typeof normalizeConfig>} baseNull\n */\nfunction makeTagHelper(tagName, base, baseNull) {\n if (!tagName) {\n throw new TypeError('id-dom: makeTagHelper received an invalid tagName')\n }\n\n return attachOptional(\n (id) => tag(id, tagName, base),\n (id) => tag(id, tagName, baseNull)\n )\n}\n// -----------------------------------------------------------------------------\n// Factory\n// -----------------------------------------------------------------------------\n\n/**\n * Factory: scope getters to a specific root + default policy.\n *\n * @param {any} root\n * @param {Omit<DomConfig, 'root'>} [config]\n */\nexport function createDom(root, config) {\n const base = normalizeConfig({ ...config, root })\n const baseNull = { ...base, mode: 'null' }\n\n /** @type {any} */\n const api = {}\n\n api.byId = attachOptional(\n (id, Type) => byId(id, Type, base),\n (id, Type) => byId(id, Type, baseNull)\n )\n\n api.tag = attachOptional(\n (id, name) => tag(id, name, base),\n (id, name) => tag(id, name, baseNull)\n )\n\n for (const [name, Type] of Object.entries(TYPE_HELPERS)) {\n if (!Type) continue\n api[name] = makeTypedHelper(Type, base, baseNull)\n }\n\n for (const [name, tagName] of Object.entries(TAG_HELPERS)) {\n api[name] = makeTagHelper(tagName, base, baseNull)\n }\n\n return api\n}\n\n// -----------------------------------------------------------------------------\n// Default-root config (shared by the default export and the named typed helpers)\n// -----------------------------------------------------------------------------\n\nconst DEFAULT_BASE = normalizeConfig({ mode: 'throw', root: DEFAULT_ROOT })\nconst DEFAULT_BASE_NULL = { ...DEFAULT_BASE, mode: 'null' }\n\n/**\n * Build a typed helper bound to the default root.\n * Internal \u2014 exposed via the per-helper named exports below.\n *\n * @param {any} Type\n */\nfunction defaultTypedHelper(Type) {\n return Type ? makeTypedHelper(Type, DEFAULT_BASE, DEFAULT_BASE_NULL) : null\n}\n\n/**\n * Build a tag-name helper bound to the default root.\n *\n * @param {string} tagName\n */\nfunction defaultTagHelper(tagName) {\n return makeTagHelper(tagName, DEFAULT_BASE, DEFAULT_BASE_NULL)\n}\n\n// -----------------------------------------------------------------------------\n// Named typed-element helpers (per-helper exports \u2014 tree-shakeable)\n//\n// Each one is a `const` initialized to a tiny closure produced by\n// makeTypedHelper. Modern bundlers (esbuild, rollup, vite) drop the\n// unused ones because the package declares sideEffects: false.\n//\n// SSR-safe: in environments where the corresponding global constructor\n// isn't defined (Node without jsdom, etc.), the export is `null` rather\n// than a thrown construction error.\n// -----------------------------------------------------------------------------\n\nexport const el = defaultTypedHelper(typeof HTMLElement !== 'undefined' ? HTMLElement : null)\nexport const input = defaultTypedHelper(typeof HTMLInputElement !== 'undefined' ? HTMLInputElement : null)\nexport const button = defaultTypedHelper(typeof HTMLButtonElement !== 'undefined' ? HTMLButtonElement : null)\nexport const textarea = defaultTypedHelper(typeof HTMLTextAreaElement !== 'undefined' ? HTMLTextAreaElement : null)\nexport const select = defaultTypedHelper(typeof HTMLSelectElement !== 'undefined' ? HTMLSelectElement : null)\nexport const form = defaultTypedHelper(typeof HTMLFormElement !== 'undefined' ? HTMLFormElement : null)\nexport const div = defaultTypedHelper(typeof HTMLDivElement !== 'undefined' ? HTMLDivElement : null)\nexport const span = defaultTypedHelper(typeof HTMLSpanElement !== 'undefined' ? HTMLSpanElement : null)\nexport const label = defaultTypedHelper(typeof HTMLLabelElement !== 'undefined' ? HTMLLabelElement : null)\nexport const canvas = defaultTypedHelper(typeof HTMLCanvasElement !== 'undefined' ? HTMLCanvasElement : null)\nexport const template = defaultTypedHelper(typeof HTMLTemplateElement !== 'undefined' ? HTMLTemplateElement : null)\nexport const svg = defaultTypedHelper(typeof SVGSVGElement !== 'undefined' ? SVGSVGElement : null)\nexport const body = defaultTypedHelper(typeof HTMLBodyElement !== 'undefined' ? HTMLBodyElement : null)\n\n// Named tag-name helpers (no dedicated constructor)\nexport const main = defaultTagHelper('main')\nexport const section = defaultTagHelper('section')\nexport const small = defaultTagHelper('small')\n\n// -----------------------------------------------------------------------------\n// Default export \u2014 the convenience object aggregating every helper. Use\n// named imports above for tree-shake-friendly bundles; use this default\n// when you want all helpers under one namespace (`dom.button(\u2026)`).\n// -----------------------------------------------------------------------------\n\nconst dom = createDom(DEFAULT_ROOT, { mode: 'throw' })\nexport default dom"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["el"]
|
|
7
7
|
}
|