jj 2.5.0 → 2.6.0

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.
Files changed (77) hide show
  1. package/README.md +29 -1
  2. package/SKILL.md +671 -0
  3. package/lib/bundle.cjs +2031 -0
  4. package/lib/bundle.cjs.map +1 -0
  5. package/lib/bundle.d.cts +1782 -0
  6. package/lib/bundle.d.ts +1782 -1
  7. package/lib/bundle.global.js +1953 -0
  8. package/lib/bundle.global.js.map +1 -0
  9. package/lib/bundle.js +232 -230
  10. package/lib/bundle.js.map +1 -7
  11. package/lib/bundle.min.cjs +2 -0
  12. package/lib/bundle.min.cjs.map +1 -0
  13. package/lib/bundle.min.d.cts +1782 -0
  14. package/lib/bundle.min.d.ts +1782 -1
  15. package/lib/bundle.min.global.js +2 -0
  16. package/lib/bundle.min.global.js.map +1 -0
  17. package/lib/bundle.min.js +2 -1
  18. package/lib/bundle.min.js.map +1 -0
  19. package/package.json +5 -5
  20. package/lib/JJD.d.ts +0 -87
  21. package/lib/JJD.js +0 -119
  22. package/lib/JJD.js.map +0 -1
  23. package/lib/JJDF.d.ts +0 -74
  24. package/lib/JJDF.js +0 -98
  25. package/lib/JJDF.js.map +0 -1
  26. package/lib/JJE.d.ts +0 -299
  27. package/lib/JJE.js +0 -401
  28. package/lib/JJE.js.map +0 -1
  29. package/lib/JJET.d.ts +0 -79
  30. package/lib/JJET.js +0 -114
  31. package/lib/JJET.js.map +0 -1
  32. package/lib/JJEx.d.ts +0 -63
  33. package/lib/JJEx.js +0 -83
  34. package/lib/JJEx.js.map +0 -1
  35. package/lib/JJHE.d.ts +0 -109
  36. package/lib/JJHE.js +0 -136
  37. package/lib/JJHE.js.map +0 -1
  38. package/lib/JJN-wrap.d.ts +0 -1
  39. package/lib/JJN-wrap.js +0 -46
  40. package/lib/JJN-wrap.js.map +0 -1
  41. package/lib/JJN.d.ts +0 -126
  42. package/lib/JJN.js +0 -166
  43. package/lib/JJN.js.map +0 -1
  44. package/lib/JJNx.d.ts +0 -126
  45. package/lib/JJNx.js +0 -157
  46. package/lib/JJNx.js.map +0 -1
  47. package/lib/JJSE.d.ts +0 -170
  48. package/lib/JJSE.js +0 -217
  49. package/lib/JJSE.js.map +0 -1
  50. package/lib/JJSR.d.ts +0 -71
  51. package/lib/JJSR.js +0 -90
  52. package/lib/JJSR.js.map +0 -1
  53. package/lib/JJT.d.ts +0 -92
  54. package/lib/JJT.js +0 -116
  55. package/lib/JJT.js.map +0 -1
  56. package/lib/case.d.ts +0 -60
  57. package/lib/case.js +0 -92
  58. package/lib/case.js.map +0 -1
  59. package/lib/components.d.ts +0 -147
  60. package/lib/components.js +0 -287
  61. package/lib/components.js.map +0 -1
  62. package/lib/helpers.d.ts +0 -159
  63. package/lib/helpers.js +0 -233
  64. package/lib/helpers.js.map +0 -1
  65. package/lib/index.d.ts +0 -33
  66. package/lib/index.js +0 -35
  67. package/lib/index.js.map +0 -1
  68. package/lib/internal.d.ts +0 -30
  69. package/lib/internal.js +0 -35
  70. package/lib/internal.js.map +0 -1
  71. package/lib/types.d.ts +0 -65
  72. package/lib/types.js +0 -2
  73. package/lib/types.js.map +0 -1
  74. package/lib/util.d.ts +0 -68
  75. package/lib/util.js +0 -90
  76. package/lib/util.js.map +0 -1
  77. package/llms.txt +0 -214
package/lib/bundle.js CHANGED
@@ -1,3 +1,12 @@
1
+ var __typeError = (msg) => {
2
+ throw TypeError(msg);
3
+ };
4
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
5
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
8
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
9
+
1
10
  // node_modules/jty/lib/misc.js
2
11
  function isDef(x) {
3
12
  return x !== void 0;
@@ -76,10 +85,18 @@ function isStr(x) {
76
85
  var { hasOwnProperty: hasOwnProperty2 } = Object;
77
86
  var { isArray: isArray2 } = Array;
78
87
 
88
+ // src/internal.ts
89
+ function errMsg(varName, expected, received) {
90
+ return `Expected '${varName}' to be ${expected}. Got ${received} (${typeof received})`;
91
+ }
92
+ function typeErr(varName, expected, received) {
93
+ return new TypeError(errMsg(varName, expected, received));
94
+ }
95
+
79
96
  // src/util.ts
80
97
  function fileExt(path) {
81
98
  if (!isStr(path)) {
82
- throw new TypeError(`Expected a string file path. Got ${path} (${typeof path})`);
99
+ throw typeErr("path", "a string", path);
83
100
  }
84
101
  const lastDotIndex = path.lastIndexOf(".");
85
102
  if (lastDotIndex === -1) {
@@ -105,33 +122,30 @@ async function cssToStyle(css) {
105
122
  // src/case.ts
106
123
  function pas2keb(str) {
107
124
  if (!isStr(str)) {
108
- throw new TypeError(`Expected a string. Got ${str} (${typeof str})`);
125
+ throw typeErr("str", "a string", str);
109
126
  }
110
127
  if (/[^a-zA-Z0-9_]/.test(str)) {
111
- throw new TypeError(`Invalid characters in string. Only alphanumeric and underscores are allowed. Got: ${str}`);
128
+ throw new SyntaxError(errMsg("str", "alphanumeric characters and underscores", str));
112
129
  }
113
130
  return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").replace(/_/g, "-").toLowerCase();
114
131
  }
115
132
  function keb2pas(str) {
116
133
  if (!isStr(str)) {
117
- throw new TypeError(`Expected a string. Got ${str} (${typeof str})`);
134
+ throw typeErr("str", "a string", str);
118
135
  }
119
136
  return str.split("-").filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("") || // Handle strings that were not kebab-case to begin with (e.g. 'single', 'camelCase')
120
137
  (str.length > 0 ? str.charAt(0).toUpperCase() + str.slice(1) : "");
121
138
  }
122
139
  function keb2cam(str) {
123
140
  if (!isStr(str)) {
124
- throw new TypeError(`Expected a string. Got ${str} (${typeof str})`);
141
+ throw typeErr("str", "a string", str);
125
142
  }
126
143
  return str.replace(/^-+|-+$/g, "").replace(/-+([a-z])/g, (g, c) => c.toUpperCase());
127
144
  }
128
145
 
129
- // src/JJET.ts
130
- var JJET = class _JJET {
131
- static from(ref) {
132
- return new _JJET(ref);
133
- }
134
- #ref;
146
+ // src/wrappers/JJET.ts
147
+ var _ref, _boundHandlers, _JJET_instances, getBoundHandler_fn;
148
+ var _JJET = class _JJET {
135
149
  /**
136
150
  * Creates a JJET instance.
137
151
  *
@@ -139,23 +153,36 @@ var JJET = class _JJET {
139
153
  * @throws {TypeError} If `ref` is not an EventTarget.
140
154
  */
141
155
  constructor(ref) {
156
+ __privateAdd(this, _JJET_instances);
157
+ __privateAdd(this, _ref);
158
+ __privateAdd(this, _boundHandlers, /* @__PURE__ */ new WeakMap());
142
159
  if (!isA(ref, EventTarget)) {
143
160
  throw new TypeError(`JJET expects an EventTarget instance. Got ${ref} (${typeof ref}). `);
144
161
  }
145
- this.#ref = ref;
162
+ __privateSet(this, _ref, ref);
163
+ }
164
+ static from(ref) {
165
+ return new _JJET(ref);
146
166
  }
147
167
  /**
148
168
  * Gets the underlying DOM object.
149
169
  */
150
170
  get ref() {
151
- return this.#ref;
171
+ return __privateGet(this, _ref);
152
172
  }
153
173
  /**
154
174
  * Adds an event listener.
155
175
  *
156
- * * @example
176
+ * @remarks
177
+ * The handler is automatically bound to this JJET instance, so `this` inside the handler
178
+ * refers to the JJET instance, not the DOM element. To access the DOM element, use `this.ref`.
179
+ *
180
+ * @example
157
181
  * ```ts
158
- * JJET.from(window).on('resize', () => console.log('resized'))
182
+ * JJET.from(window).on('resize', function() {
183
+ * console.log(this) // JJET instance
184
+ * console.log(this.ref) // window object
185
+ * })
159
186
  * ```
160
187
  * @param eventName - The name of the event.
161
188
  * @param handler - The event handler.
@@ -164,15 +191,21 @@ var JJET = class _JJET {
164
191
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener | EventTarget.addEventListener}
165
192
  */
166
193
  on(eventName, handler, options) {
167
- this.ref.addEventListener(eventName, handler, options);
194
+ const boundHandler = __privateMethod(this, _JJET_instances, getBoundHandler_fn).call(this, handler);
195
+ this.ref.addEventListener(eventName, boundHandler, options);
168
196
  return this;
169
197
  }
170
198
  /**
171
199
  * Removes an event listener.
172
200
  *
173
- * * @example
201
+ * @remarks
202
+ * Pass the same handler reference that was used in `on()` to properly remove the listener.
203
+ *
204
+ * @example
174
205
  * ```ts
175
- * JJET.from(window).off('resize', previouslyAttachedHandler)
206
+ * const handler = function() { console.log(this) }
207
+ * JJET.from(window).on('resize', handler)
208
+ * JJET.from(window).off('resize', handler)
176
209
  * ```
177
210
  * @param eventName - The name of the event.
178
211
  * @param handler - The event handler.
@@ -181,7 +214,8 @@ var JJET = class _JJET {
181
214
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener | EventTarget.removeEventListener}
182
215
  */
183
216
  off(eventName, handler, options) {
184
- this.ref.removeEventListener(eventName, handler, options);
217
+ const boundHandler = __privateMethod(this, _JJET_instances, getBoundHandler_fn).call(this, handler);
218
+ this.ref.removeEventListener(eventName, boundHandler, options);
185
219
  return this;
186
220
  }
187
221
  /**
@@ -218,8 +252,35 @@ var JJET = class _JJET {
218
252
  return fn.call(this, ...args);
219
253
  }
220
254
  };
255
+ _ref = new WeakMap();
256
+ _boundHandlers = new WeakMap();
257
+ _JJET_instances = new WeakSet();
258
+ /**
259
+ * Gets or creates a bound version of the handler.
260
+ *
261
+ * @remarks
262
+ * Bound handlers are cached in a WeakMap to ensure `off()` can properly remove listeners.
263
+ * When the original handler is garbage collected, the bound version is automatically removed.
264
+ *
265
+ * @param handler - The event handler to bind.
266
+ * @returns The bound handler, or null if the input is null.
267
+ */
268
+ getBoundHandler_fn = function(handler) {
269
+ if (handler === null) return null;
270
+ let bound = __privateGet(this, _boundHandlers).get(handler);
271
+ if (!bound) {
272
+ if (typeof handler === "function") {
273
+ bound = handler.bind(this);
274
+ } else {
275
+ bound = { handleEvent: handler.handleEvent.bind(this) };
276
+ }
277
+ __privateGet(this, _boundHandlers).set(handler, bound);
278
+ }
279
+ return bound;
280
+ };
281
+ var JJET = _JJET;
221
282
 
222
- // src/JJN.ts
283
+ // src/wrappers/JJN-raw.ts
223
284
  var JJN = class _JJN extends JJET {
224
285
  /**
225
286
  * Creates a JJN instance from a Node reference.
@@ -376,15 +437,15 @@ var JJN = class _JJN extends JJET {
376
437
  }
377
438
  };
378
439
 
379
- // src/JJNx.ts
440
+ // src/wrappers/JJNx.ts
380
441
  var JJNx = class extends JJN {
381
442
  /**
382
443
  * Finds the first element matching a selector within this Element.
383
444
  *
384
445
  * @example
385
446
  * ```ts
386
- * const span = el.query('span') // Returns null if not found
387
- * const span = el.query('span', true) // Throws if not found
447
+ * const span = el.find('span') // Returns null if not found
448
+ * const span = el.find('span', true) // Throws if not found
388
449
  * ```
389
450
  *
390
451
  * @param selector - The CSS selector.
@@ -393,15 +454,13 @@ var JJNx = class extends JJN {
393
454
  * @throws {TypeError} If selector is not a string or element not found and required is true.
394
455
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector | Element.querySelector}
395
456
  */
396
- query(selector, required = false) {
457
+ find(selector, required = false) {
397
458
  const queryResult = this.ref.querySelector(selector);
398
459
  if (queryResult) {
399
460
  return JJN.wrap(queryResult);
400
461
  }
401
462
  if (required) {
402
- throw new TypeError(
403
- `Element with selector "${selector}" not found. Did you mean to call .query("${selector}", false) to return null instead? `
404
- );
463
+ throw new TypeError(`No element matched query "${selector}"`);
405
464
  }
406
465
  return null;
407
466
  }
@@ -410,7 +469,7 @@ var JJNx = class extends JJN {
410
469
  *
411
470
  * @example
412
471
  * ```ts
413
- * const items = el.queryAll('li')
472
+ * const items = el.findAll('li')
414
473
  * ```
415
474
  *
416
475
  * @param selector - The CSS selector.
@@ -418,7 +477,7 @@ var JJNx = class extends JJN {
418
477
  * @throws {TypeError} If selector is not a string.
419
478
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll | Element.querySelectorAll}
420
479
  */
421
- queryAll(selector) {
480
+ findAll(selector) {
422
481
  return JJN.wrapAll(this.ref.querySelectorAll(selector));
423
482
  }
424
483
  /**
@@ -426,7 +485,7 @@ var JJNx = class extends JJN {
426
485
  *
427
486
  * @example
428
487
  * ```ts
429
- * el.append(h('span', null, 'hello'))
488
+ * el.addChild(h('span', null, 'hello'))
430
489
  * ```
431
490
  *
432
491
  * @remarks
@@ -436,7 +495,7 @@ var JJNx = class extends JJN {
436
495
  * @returns This instance for chaining.
437
496
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/append | Element.append}
438
497
  */
439
- append(...children) {
498
+ addChild(...children) {
440
499
  const nodes = JJN.unwrapAll(children.filter(JJN.isWrapable));
441
500
  this.ref.append(...nodes);
442
501
  return this;
@@ -446,7 +505,7 @@ var JJNx = class extends JJN {
446
505
  *
447
506
  * @example
448
507
  * ```ts
449
- * el.prepend(h('span', null, 'first'))
508
+ * el.preChild(h('span', null, 'first'))
450
509
  * ```
451
510
  *
452
511
  * @remarks
@@ -456,7 +515,7 @@ var JJNx = class extends JJN {
456
515
  * @returns This instance for chaining.
457
516
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/prepend | Element.prepend}
458
517
  */
459
- prepend(...children) {
518
+ preChild(...children) {
460
519
  const nodes = JJN.unwrapAll(children.filter(JJN.isWrapable));
461
520
  this.ref.prepend(...nodes);
462
521
  return this;
@@ -466,7 +525,7 @@ var JJNx = class extends JJN {
466
525
  *
467
526
  * @example
468
527
  * ```ts
469
- * node.mapAppend(['a', 'b'], item => h('li', null, item))
528
+ * node.addChildMap(['a', 'b'], item => h('li', null, item))
470
529
  * ```
471
530
  *
472
531
  * @remarks
@@ -476,15 +535,15 @@ var JJNx = class extends JJN {
476
535
  * @param mapFn - The mapping function returning a Wrappable.
477
536
  * @returns This instance for chaining.
478
537
  */
479
- mapAppend(array, mapFn) {
480
- return this.append(...array.map(mapFn));
538
+ addChildMap(array, mapFn) {
539
+ return this.addChild(...array.map(mapFn));
481
540
  }
482
541
  /**
483
542
  * Maps an array to children and prepends them.
484
543
  *
485
544
  * @example
486
545
  * ```ts
487
- * node.mapPrepend(['a', 'b'], item => JJHE.fromTag('li').setText(item))
546
+ * node.preChildMap(['a', 'b'], item => JJHE.create('li').setText(item))
488
547
  * ```
489
548
  *
490
549
  * @remarks
@@ -494,8 +553,8 @@ var JJNx = class extends JJN {
494
553
  * @param mapFn - The mapping function.
495
554
  * @returns This instance for chaining.
496
555
  */
497
- mapPrepend(array, mapFn) {
498
- return this.prepend(...array.map(mapFn));
556
+ preChildMap(array, mapFn) {
557
+ return this.preChild(...array.map(mapFn));
499
558
  }
500
559
  /**
501
560
  * Replaces the existing children of an Element with a specified new set of children.
@@ -534,15 +593,7 @@ var JJNx = class extends JJN {
534
593
  }
535
594
  };
536
595
 
537
- // src/internal.ts
538
- function errMsg(varName, expected, received) {
539
- return `Expected '${varName}' to be ${expected}. Got ${received} (${typeof received})`;
540
- }
541
- function typeErr(varName, expected, received) {
542
- return new TypeError(errMsg(varName, expected, received));
543
- }
544
-
545
- // src/JJDF.ts
596
+ // src/wrappers/JJDF.ts
546
597
  var JJDF = class _JJDF extends JJNx {
547
598
  /**
548
599
  * Creates a JJDF instance from a DocumentFragment reference.
@@ -582,41 +633,13 @@ var JJDF = class _JJDF extends JJNx {
582
633
  */
583
634
  constructor(ref) {
584
635
  if (!isA(ref, DocumentFragment)) {
585
- throw new TypeError(`Expected a DocumentFragment. Got ${ref} (${typeof ref})`);
636
+ throw typeErr("ref", "a DocumentFragment", ref);
586
637
  }
587
638
  super(ref);
588
639
  }
589
- /**
590
- * Finds an element by ID within this DocumentFragment.
591
- *
592
- * @example
593
- * ```ts
594
- * const el = frag.byId('header') // Returns null if not found
595
- * const el = frag.byId('header', true) // Throws if not found
596
- * ```
597
- *
598
- * @param id - The ID to search for.
599
- * @param required - Whether to throw an error if not found. Defaults to false.
600
- * @returns The wrapped element, or null if not found and required is false.
601
- * @throws {TypeError} If id is not a string or element not found and required is true.
602
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment/getElementById | DocumentFragment.getElementById}
603
- */
604
- byId(id, required = false) {
605
- if (!isStr(id)) {
606
- throw typeErr("id", "a string", id);
607
- }
608
- const el = this.ref.getElementById(id);
609
- if (el) {
610
- return JJN.wrap(el);
611
- }
612
- if (required) {
613
- throw new TypeError(`Element with id ${id} not found`);
614
- }
615
- return null;
616
- }
617
640
  };
618
641
 
619
- // src/JJSR.ts
642
+ // src/wrappers/JJSR.ts
620
643
  var JJSR = class _JJSR extends JJDF {
621
644
  /**
622
645
  * Creates a JJSR instance from a ShadowRoot reference.
@@ -660,16 +683,21 @@ var JJSR = class _JJSR extends JJDF {
660
683
  *
661
684
  * @example
662
685
  * ```ts
663
- * shadow.setHTML('<p>Hello</p>', false)
686
+ * shadow.setHTML('<p>Hello</p>', true)
664
687
  * ```
665
688
  *
666
- * @param value - The HTML string.
667
- * @param unsafe - Reserved for future use (must be false).
689
+ * @param html - The HTML string to set, or null/undefined to clear.
690
+ * @param unsafe - explicit opt-in to set innerHTML. must be true if html is provided.
668
691
  * @returns This instance for chaining.
669
692
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML | Element.innerHTML}
670
693
  */
671
- setHTML(value, unsafe) {
672
- this.ref.innerHTML = value;
694
+ setHTML(html, unsafe) {
695
+ if (html && unsafe !== true) {
696
+ throw new Error(
697
+ `Setting innerHTML is unsafe. Pass true as the second argument to confirm you know what you are doing.`
698
+ );
699
+ }
700
+ this.ref.innerHTML = html ?? "";
673
701
  return this;
674
702
  }
675
703
  /**
@@ -692,7 +720,7 @@ var JJSR = class _JJSR extends JJDF {
692
720
  }
693
721
  };
694
722
 
695
- // src/JJE.ts
723
+ // src/wrappers/JJE.ts
696
724
  var JJE = class _JJE extends JJNx {
697
725
  /**
698
726
  * Creates a JJE instance from an Element reference.
@@ -974,6 +1002,33 @@ var JJE = class _JJE extends JJNx {
974
1002
  this.ref.classList.replace(oldClassName, newClassName);
975
1003
  return this;
976
1004
  }
1005
+ /**
1006
+ * Finds the closest ancestor (or self) that matches a CSS selector.
1007
+ *
1008
+ * @remarks
1009
+ * Returns `null` when no matching ancestor is found.
1010
+ *
1011
+ * @example
1012
+ * ```ts
1013
+ * const button = JJE.from(document.querySelector('button'))
1014
+ * const card = button.closest('.card')
1015
+ * if (card) {
1016
+ * card.addClass('has-action')
1017
+ * }
1018
+ * ```
1019
+ *
1020
+ * @param selector - The CSS selector to search for.
1021
+ * @returns A JJE wrapping the closest match, or null when none exists.
1022
+ * @throws {TypeError} If `selector` is not a string.
1023
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/closest | Element.closest}
1024
+ */
1025
+ closest(selector) {
1026
+ if (!isStr(selector)) {
1027
+ throw typeErr("selector", "a string", selector);
1028
+ }
1029
+ const match = this.ref.closest(selector);
1030
+ return match ? JJN.wrap(match) : null;
1031
+ }
977
1032
  /**
978
1033
 
979
1034
  * Hides the Element by setting the `hidden` attribute and `aria-hidden="true"`.
@@ -1031,10 +1086,16 @@ var JJE = class _JJE extends JJNx {
1031
1086
  * Pass an empty string, `null`, or `undefined` to clear the content.
1032
1087
  *
1033
1088
  * @param html - The HTML string to set, or null/undefined to clear.
1089
+ * @param unsafe - explicit opt-in to set innerHTML. must be true if html is provided.
1034
1090
  * @returns This instance for chaining.
1035
1091
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML | Element.innerHTML}
1036
1092
  */
1037
- setHTML(html) {
1093
+ setHTML(html, unsafe) {
1094
+ if (html && unsafe !== true) {
1095
+ throw new Error(
1096
+ `Setting innerHTML is unsafe. Pass true as the second argument to confirm you know what you are doing.`
1097
+ );
1098
+ }
1038
1099
  this.ref.innerHTML = html ?? "";
1039
1100
  return this;
1040
1101
  }
@@ -1058,7 +1119,11 @@ var JJE = class _JJE extends JJNx {
1058
1119
  if (isObj(config)) {
1059
1120
  const { template, styles } = config;
1060
1121
  if (template) {
1061
- shadowRoot.innerHTML = template;
1122
+ if (isStr(template)) {
1123
+ shadowRoot.innerHTML = template;
1124
+ } else {
1125
+ shadowRoot.appendChild(template);
1126
+ }
1062
1127
  }
1063
1128
  if (isArr(styles) && styles.length) {
1064
1129
  shadowRoot.adoptedStyleSheets.push(...styles);
@@ -1076,7 +1141,7 @@ var JJE = class _JJE extends JJNx {
1076
1141
  }
1077
1142
  };
1078
1143
 
1079
- // src/JJEx.ts
1144
+ // src/wrappers/JJEx.ts
1080
1145
  var JJEx = class extends JJE {
1081
1146
  /**
1082
1147
  * Gets a data attribute from the HTMLElement.
@@ -1155,7 +1220,7 @@ var JJEx = class extends JJE {
1155
1220
  }
1156
1221
  };
1157
1222
 
1158
- // src/JJHE.ts
1223
+ // src/wrappers/JJHE.ts
1159
1224
  var JJHE = class _JJHE extends JJEx {
1160
1225
  /**
1161
1226
  * Creates a JJHE instance from an HTMLElement reference.
@@ -1172,11 +1237,9 @@ var JJHE = class _JJHE extends JJEx {
1172
1237
  static from(ref) {
1173
1238
  return new _JJHE(ref);
1174
1239
  }
1175
- static fromTag(tagName, options) {
1240
+ static create(tagName, options) {
1176
1241
  if (!isStr(tagName)) {
1177
- throw new TypeError(
1178
- `JJHE.fromTag() expects tagName to be a string (e.g., 'div', 'button'). Got ${tagName} (${typeof tagName}). Did you mean to use a string literal like 'div'?`
1179
- );
1242
+ throw typeErr("tagName", "a string like 'div' or 'button'", tagName);
1180
1243
  }
1181
1244
  return new _JJHE(document.createElement(tagName, options));
1182
1245
  }
@@ -1188,9 +1251,7 @@ var JJHE = class _JJHE extends JJEx {
1188
1251
  */
1189
1252
  constructor(ref) {
1190
1253
  if (!isA(ref, HTMLElement)) {
1191
- throw new TypeError(
1192
- `JJHE expects an HTMLElement. Got ${ref} (${typeof ref}). If you have a DOM node, use JJHE.from(element). If creating a new element, use JJHE.fromTag('div').`
1193
- );
1254
+ throw typeErr("ref", "an HTMLElement", ref);
1194
1255
  }
1195
1256
  super(ref);
1196
1257
  }
@@ -1203,9 +1264,7 @@ var JJHE = class _JJHE extends JJEx {
1203
1264
  */
1204
1265
  getValue() {
1205
1266
  if (!hasProp(this.ref, "value")) {
1206
- throw new Error(
1207
- `Cannot get value from <${this.ref.tagName.toLowerCase()}>. The value property only exists on form elements (input, textarea, select). If you need text content, try .getText() instead.`
1208
- );
1267
+ throw new ReferenceError(`${this.ref.tagName} has no value property.`);
1209
1268
  }
1210
1269
  return this.ref.value;
1211
1270
  }
@@ -1225,9 +1284,7 @@ var JJHE = class _JJHE extends JJEx {
1225
1284
  */
1226
1285
  setValue(value) {
1227
1286
  if (!hasProp(this.ref, "value")) {
1228
- throw new Error(
1229
- `Cannot set value on <${this.ref.tagName.toLowerCase()}>. The value property only exists on form elements (input, textarea, select). If you need to set text content, try .setText() instead.`
1230
- );
1287
+ throw new ReferenceError(`${this.ref.tagName} has no value property.`);
1231
1288
  }
1232
1289
  this.ref.value = value;
1233
1290
  return this;
@@ -1282,7 +1339,7 @@ var JJHE = class _JJHE extends JJEx {
1282
1339
  }
1283
1340
  };
1284
1341
 
1285
- // src/JJT.ts
1342
+ // src/wrappers/JJT.ts
1286
1343
  var JJT = class _JJT extends JJN {
1287
1344
  /**
1288
1345
  * Creates a JJT instance from a Text node.
@@ -1388,7 +1445,7 @@ var JJT = class _JJT extends JJN {
1388
1445
  }
1389
1446
  };
1390
1447
 
1391
- // src/JJD.ts
1448
+ // src/wrappers/JJD.ts
1392
1449
  var JJD = class _JJD extends JJNx {
1393
1450
  /**
1394
1451
  * Creates a JJD instance from a Document reference.
@@ -1417,55 +1474,6 @@ var JJD = class _JJD extends JJNx {
1417
1474
  }
1418
1475
  super(ref);
1419
1476
  }
1420
- /**
1421
- * Finds an element by ID within this Document.
1422
- *
1423
- * @example
1424
- * ```ts
1425
- * const el = doc.byId('my-id') // Returns null if not found
1426
- * const el = doc.byId('my-id', true) // Throws if not found
1427
- * ```
1428
- *
1429
- * @param id - The ID to search for.
1430
- * @param required - Whether to throw an error if not found. Defaults to false.
1431
- * @returns The wrapped element, or null if not found and required is false.
1432
- * @throws {TypeError} If id is not a string or element not found and required is true.
1433
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById | Document.getElementById}
1434
- */
1435
- byId(id, required = false) {
1436
- if (!isStr(id)) {
1437
- throw typeErr("id", "a string", id);
1438
- }
1439
- const el = this.ref.getElementById(id);
1440
- if (el) {
1441
- return JJN.wrap(el);
1442
- }
1443
- if (required) {
1444
- throw new TypeError(
1445
- `Element with id "${id}" not found in the document. Did you mean to call .byId("${id}", false) to return null instead? `
1446
- );
1447
- }
1448
- return null;
1449
- }
1450
- /**
1451
- * Finds elements by class name in the Document.
1452
- *
1453
- * @example
1454
- * ```ts
1455
- * const items = byClass('list-item')
1456
- * ```
1457
- *
1458
- * @param className - The class name to search for.
1459
- * @returns An array of wrapped elements.
1460
- * @throws {TypeError} If className is not a string.
1461
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName | Document.getElementsByClassName}
1462
- */
1463
- byClass(className) {
1464
- if (!isStr(className)) {
1465
- throw typeErr("className", "a string", className);
1466
- }
1467
- return JJN.wrapAll(this.ref.getElementsByClassName(className));
1468
- }
1469
1477
  /**
1470
1478
  * Gets the `<head>` element of the document wrapped in a `JJHE` instance.
1471
1479
  *
@@ -1473,7 +1481,7 @@ var JJD = class _JJD extends JJNx {
1473
1481
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/head | Document.head}
1474
1482
  */
1475
1483
  get head() {
1476
- return JJN.wrap(this.ref.head);
1484
+ return JJHE.from(this.ref.head);
1477
1485
  }
1478
1486
  /**
1479
1487
  * Gets the `<body>` element of the document wrapped in a `JJHE` instance.
@@ -1482,11 +1490,11 @@ var JJD = class _JJD extends JJNx {
1482
1490
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/body | Document.body}
1483
1491
  */
1484
1492
  get body() {
1485
- return JJN.wrap(this.ref.body);
1493
+ return JJHE.from(this.ref.body);
1486
1494
  }
1487
1495
  };
1488
1496
 
1489
- // src/JJSE.ts
1497
+ // src/wrappers/JJSE.ts
1490
1498
  var SVG_NAMESPACE_URI = "http://www.w3.org/2000/svg";
1491
1499
  var JJSE = class _JJSE extends JJEx {
1492
1500
  /**
@@ -1512,7 +1520,7 @@ var JJSE = class _JJSE extends JJEx {
1512
1520
  *
1513
1521
  * @example
1514
1522
  * ```ts
1515
- * const circle = JJSE.fromTag('circle')
1523
+ * const circle = JJSE.create('circle')
1516
1524
  * ```
1517
1525
  *
1518
1526
  * @param tagName - The tag name.
@@ -1521,11 +1529,9 @@ var JJSE = class _JJSE extends JJEx {
1521
1529
  * @throws {TypeError} If `tagName` is not a string.
1522
1530
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS | document.createElementNS}
1523
1531
  */
1524
- static fromTag(tagName, options) {
1532
+ static create(tagName, options) {
1525
1533
  if (!isStr(tagName)) {
1526
- throw new TypeError(
1527
- `JJSE.fromTag() expects tagName to be a string (e.g., 'circle', 'path'). Got ${tagName} (${typeof tagName}). Did you mean to pass a string literal like 'circle'?`
1528
- );
1534
+ throw typeErr("tagName", 'a string like "circle" or "path"', tagName);
1529
1535
  }
1530
1536
  const element = document.createElementNS(SVG_NAMESPACE_URI, tagName, options);
1531
1537
  return new _JJSE(element);
@@ -1538,9 +1544,7 @@ var JJSE = class _JJSE extends JJEx {
1538
1544
  */
1539
1545
  constructor(ref) {
1540
1546
  if (!isA(ref, SVGElement)) {
1541
- throw new TypeError(
1542
- `JJSE expects an SVGElement. Got ${ref} (${typeof ref}). Use JJSE.from(element) with an SVG element, or JJSE.fromTag('circle') to create one.`
1543
- );
1547
+ throw typeErr("ref", "an SVGElement", ref);
1544
1548
  }
1545
1549
  super(ref);
1546
1550
  }
@@ -1584,21 +1588,6 @@ var JJSE = class _JJSE extends JJEx {
1584
1588
  this.ref.textContent = text ?? "";
1585
1589
  return this;
1586
1590
  }
1587
- /**
1588
- * Clears the text content of the SVGElement.
1589
- *
1590
- * @example
1591
- * ```ts
1592
- * svg.empty()
1593
- * ```
1594
- *
1595
- * @returns This instance for chaining.
1596
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent | Node.textContent}
1597
- */
1598
- empty() {
1599
- this.ref.textContent = "";
1600
- return this;
1601
- }
1602
1591
  /**
1603
1592
  * Sets the fill attribute.
1604
1593
  *
@@ -1694,13 +1683,13 @@ var JJSE = class _JJSE extends JJEx {
1694
1683
  }
1695
1684
  };
1696
1685
 
1697
- // src/JJN-wrap.ts
1686
+ // src/wrappers/JJN.ts
1698
1687
  JJN.wrap = function wrap(raw) {
1699
1688
  if (isStr(raw)) {
1700
1689
  return JJT.fromStr(raw);
1701
1690
  }
1702
1691
  if (!isObj(raw)) {
1703
- throw new TypeError(`Expected an object to wrap. Got ${raw} (${typeof raw})`);
1692
+ throw typeErr("raw", "an object", raw);
1704
1693
  }
1705
1694
  if (isA(raw, JJN)) {
1706
1695
  return raw;
@@ -1729,12 +1718,12 @@ JJN.wrap = function wrap(raw) {
1729
1718
  if (isA(raw, Node)) {
1730
1719
  return JJN.from(raw);
1731
1720
  }
1732
- throw new TypeError(`Expected a Node to wrap. Got ${raw} (${typeof raw})`);
1721
+ throw typeErr("raw", "a Node", raw);
1733
1722
  };
1734
1723
 
1735
1724
  // src/helpers.ts
1736
1725
  function h(tagName, attributes, ...children) {
1737
- const ret = JJHE.fromTag(tagName).append(...children);
1726
+ const ret = JJHE.create(tagName).addChild(...children);
1738
1727
  if (attributes) {
1739
1728
  ret.setAttr(attributes);
1740
1729
  }
@@ -1775,7 +1764,7 @@ function createLinkPre(href, rel, as) {
1775
1764
  if (!["fetch", "style", "script"].includes(as)) {
1776
1765
  throw new RangeError(errMsg("as", `'fetch', 'style', or 'script'`, as));
1777
1766
  }
1778
- return JJHE.fromTag("link").setAttr({
1767
+ return JJHE.create("link").setAttr({
1779
1768
  href,
1780
1769
  rel,
1781
1770
  as
@@ -1788,7 +1777,7 @@ function addLinkPre(...args) {
1788
1777
  }
1789
1778
  async function fetchText(url, mime = "text/*") {
1790
1779
  if (!isStr(mime)) {
1791
- throw new TypeError(`Expected a string mime like 'text/html' or 'text/css'. Got ${mime} (${typeof mime})`);
1780
+ throw typeErr("mime", "a string", mime);
1792
1781
  }
1793
1782
  const response = await fetch(url, { headers: { Accept: mime } });
1794
1783
  if (!response.ok) {
@@ -1807,8 +1796,35 @@ async function fetchStyle(url) {
1807
1796
  }
1808
1797
 
1809
1798
  // src/components.ts
1799
+ function attr2prop(instance, name, oldValue, newValue) {
1800
+ if (!isA(instance, HTMLElement)) {
1801
+ throw typeErr("instance", "an HTMLElement", instance);
1802
+ }
1803
+ if (oldValue !== newValue) {
1804
+ const propName = keb2cam(name);
1805
+ if (hasProp(instance, propName)) {
1806
+ instance[propName] = newValue;
1807
+ return true;
1808
+ }
1809
+ }
1810
+ return false;
1811
+ }
1812
+ async function registerComponent(name, constructor, options) {
1813
+ if (!isStr(name)) {
1814
+ throw typeErr("name", "a string", name);
1815
+ }
1816
+ if (!isFn(constructor)) {
1817
+ throw typeErr("constructor", "a function", constructor);
1818
+ }
1819
+ if (!customElements.get(name)) {
1820
+ customElements.define(name, constructor, options);
1821
+ await customElements.whenDefined(name);
1822
+ }
1823
+ }
1824
+
1825
+ // src/ShadowMaster.ts
1810
1826
  async function templatePromise(templateConfig) {
1811
- if (!isDef(templateConfig)) {
1827
+ if (templateConfig === void 0) {
1812
1828
  return void 0;
1813
1829
  }
1814
1830
  if (isFn(templateConfig)) {
@@ -1818,13 +1834,22 @@ async function templatePromise(templateConfig) {
1818
1834
  if (isStr(templateConfig)) {
1819
1835
  return templateConfig;
1820
1836
  }
1837
+ if (isA(templateConfig, JJDF)) {
1838
+ return templateConfig.ref.cloneNode(true);
1839
+ }
1840
+ if (isA(templateConfig, DocumentFragment)) {
1841
+ return templateConfig.cloneNode(true);
1842
+ }
1821
1843
  if (isA(templateConfig, JJHE)) {
1822
- return templateConfig.getHTML();
1844
+ if (templateConfig.ref instanceof HTMLTemplateElement) {
1845
+ return templateConfig.ref.content.cloneNode(true);
1846
+ }
1847
+ return templateConfig.ref.outerHTML;
1823
1848
  }
1824
1849
  if (isA(templateConfig, HTMLElement)) {
1825
- return templateConfig.outerHTML;
1850
+ return templateConfig instanceof HTMLTemplateElement ? templateConfig.content.cloneNode(true) : templateConfig.outerHTML;
1826
1851
  }
1827
- throw new TypeError(`Expected template to be a string, JJHE, or HTMLElement. Got ${typeof templateConfig}`);
1852
+ throw typeErr("template", "a string, JJHE, JJDF, HTMLElement, or DocumentFragment", templateConfig);
1828
1853
  }
1829
1854
  async function stylePromise(styleConfig) {
1830
1855
  if (isFn(styleConfig)) {
@@ -1837,7 +1862,7 @@ async function stylePromise(styleConfig) {
1837
1862
  if (isStr(styleConfig)) {
1838
1863
  return await cssToStyle(styleConfig);
1839
1864
  }
1840
- throw new TypeError(`Expected style to be a CSS string or CSSStyleSheet. Got ${typeof styleConfig}`);
1865
+ throw typeErr("style", "a CSS string or CSSStyleSheet", styleConfig);
1841
1866
  }
1842
1867
  function stylePromises(styleConfigs) {
1843
1868
  if (!isArr(styleConfigs)) {
@@ -1849,10 +1874,13 @@ async function resolveConfig(templateConfig, styleConfigs) {
1849
1874
  const [template, ...styles] = await Promise.all([templatePromise(templateConfig), ...stylePromises(styleConfigs)]);
1850
1875
  return { template, styles };
1851
1876
  }
1852
- var ShadowMaster = class _ShadowMaster {
1853
- #templateConfig = void 0;
1854
- #stylesConfig = [];
1855
- #normalizedConfig = void 0;
1877
+ var _templateConfig, _stylesConfig, _normalizedConfig;
1878
+ var _ShadowMaster = class _ShadowMaster {
1879
+ constructor() {
1880
+ __privateAdd(this, _templateConfig);
1881
+ __privateAdd(this, _stylesConfig, []);
1882
+ __privateAdd(this, _normalizedConfig);
1883
+ }
1856
1884
  /**
1857
1885
  * Creates a new instance of ShadowMaster.
1858
1886
  *
@@ -1861,8 +1889,6 @@ var ShadowMaster = class _ShadowMaster {
1861
1889
  static create() {
1862
1890
  return new _ShadowMaster();
1863
1891
  }
1864
- constructor() {
1865
- }
1866
1892
  /**
1867
1893
  * Sets the template configuration.
1868
1894
  *
@@ -1876,7 +1902,7 @@ var ShadowMaster = class _ShadowMaster {
1876
1902
  * ```
1877
1903
  */
1878
1904
  setTemplate(templateConfig) {
1879
- this.#templateConfig = templateConfig;
1905
+ __privateSet(this, _templateConfig, templateConfig);
1880
1906
  return this;
1881
1907
  }
1882
1908
  /**
@@ -1895,7 +1921,7 @@ var ShadowMaster = class _ShadowMaster {
1895
1921
  * ```
1896
1922
  */
1897
1923
  addStyles(...stylesConfig) {
1898
- this.#stylesConfig.push(...stylesConfig);
1924
+ __privateGet(this, _stylesConfig).push(...stylesConfig);
1899
1925
  return this;
1900
1926
  }
1901
1927
  /**
@@ -1908,43 +1934,19 @@ var ShadowMaster = class _ShadowMaster {
1908
1934
  * @returns A promise resolving to the ShadowConfig.
1909
1935
  */
1910
1936
  async getResolved() {
1911
- if (!this.#normalizedConfig) {
1912
- this.#normalizedConfig = resolveConfig(this.#templateConfig, this.#stylesConfig);
1937
+ if (!__privateGet(this, _normalizedConfig)) {
1938
+ __privateSet(this, _normalizedConfig, resolveConfig(__privateGet(this, _templateConfig), __privateGet(this, _stylesConfig)));
1913
1939
  }
1914
- return await this.#normalizedConfig;
1940
+ return await __privateGet(this, _normalizedConfig);
1915
1941
  }
1916
1942
  };
1917
- function attr2prop(instance, name, oldValue, newValue) {
1918
- if (!isA(instance, HTMLElement)) {
1919
- throw new TypeError(
1920
- `Expected an HTMLElement or a custom element instance. Got ${instance} (${typeof instance})`
1921
- );
1922
- }
1923
- if (oldValue !== newValue) {
1924
- const propName = keb2cam(name);
1925
- if (hasProp(instance, propName)) {
1926
- instance[propName] = newValue;
1927
- return true;
1928
- }
1929
- }
1930
- return false;
1931
- }
1932
- async function registerComponent(name, constructor, options) {
1933
- if (!isStr(name)) {
1934
- throw typeErr("name", "a string", name);
1935
- }
1936
- if (!isFn(constructor)) {
1937
- throw typeErr("constructor", "a function", constructor);
1938
- }
1939
- if (!customElements.get(name)) {
1940
- customElements.define(name, constructor, options);
1941
- await customElements.whenDefined(name);
1942
- }
1943
- }
1943
+ _templateConfig = new WeakMap();
1944
+ _stylesConfig = new WeakMap();
1945
+ _normalizedConfig = new WeakMap();
1946
+ var ShadowMaster = _ShadowMaster;
1944
1947
 
1945
1948
  // src/index.ts
1946
1949
  var doc = JJD.from(document);
1947
- var index_default = doc;
1948
1950
  export {
1949
1951
  JJD,
1950
1952
  JJDF,
@@ -1960,7 +1962,7 @@ export {
1960
1962
  attr2prop,
1961
1963
  createLinkPre,
1962
1964
  cssToStyle,
1963
- index_default as default,
1965
+ doc,
1964
1966
  fetchCss,
1965
1967
  fetchHtml,
1966
1968
  fetchStyle,
@@ -1974,4 +1976,4 @@ export {
1974
1976
  registerComponent,
1975
1977
  sleep
1976
1978
  };
1977
- //# sourceMappingURL=bundle.js.map
1979
+ //# sourceMappingURL=bundle.js.map