bruh 1.11.0 → 1.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,6 +16,12 @@
16
16
  src="https://img.shields.io/npm/v/bruh"
17
17
  >
18
18
  </a>
19
+ <a href="https://www.npmjs.com/package/bruh">
20
+ <img
21
+ alt="Distributed download size for the entire library"
22
+ src="https://img.shields.io/bundlephobia/minzip/bruh"
23
+ >
24
+ </a>
19
25
  <a href="https://github.com/Technical-Source/bruh/discussions">
20
26
  <img
21
27
  alt="Github Discussions"
@@ -34,9 +40,6 @@ It packs flexible SSR (Server-Side HTML Rendering),
34
40
  an awesome DOM interface,
35
41
  and elegant functional reactivity in a tiny code size.
36
42
 
37
- _As of version 1.10.2, its [browser-specific code](https://unpkg.com/bruh@1.10.2/dist/bruh.umd.js)
38
- is ~2.6kb minified+brotli with everything included and transpiled._
39
-
40
43
  Along with modern build tooling integration ([vite](https://vitejs.dev)), you're one step away from:
41
44
  - JSX and MDX (markdown with JSX instead of HTML) for both HTML rendering and DOM element creation
42
45
  - Instant HMR (Hot Module Reloading) for both server rendered HTML and client CSS/JS/TS
@@ -54,7 +57,7 @@ Along with modern build tooling integration ([vite](https://vitejs.dev)), you're
54
57
  src="https://img.shields.io/badge/Open_in_CodePen-blue?logo=codepen"
55
58
  >
56
59
  </a>
57
- </p>
60
+ </p><br>
58
61
 
59
62
  ```jsx
60
63
  const Counter = () => {
@@ -94,7 +97,7 @@ document.body.append(
94
97
  src="https://img.shields.io/badge/Preview_the_template_in_CodeSandbox-blue?logo=codesandbox"
95
98
  >
96
99
  </a>
97
- </p>
100
+ </p><br>
98
101
 
99
102
  # Where is the documentation?
100
103
 
package/dist/bruh.es.js CHANGED
@@ -1,369 +1,226 @@
1
- var __defProp = Object.defineProperty;
2
- var __defProps = Object.defineProperties;
3
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
- var __spreadValues = (a, b) => {
9
- for (var prop in b || (b = {}))
10
- if (__hasOwnProp.call(b, prop))
11
- __defNormalProp(a, prop, b[prop]);
12
- if (__getOwnPropSymbols)
13
- for (var prop of __getOwnPropSymbols(b)) {
14
- if (__propIsEnum.call(b, prop))
15
- __defNormalProp(a, prop, b[prop]);
16
- }
17
- return a;
18
- };
19
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- var __publicField = (obj, key, value) => {
21
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
22
- return value;
23
- };
24
- var __accessCheck = (obj, member, msg) => {
25
- if (!member.has(obj))
26
- throw TypeError("Cannot " + msg);
27
- };
28
- var __privateGet = (obj, member, getter) => {
29
- __accessCheck(obj, member, "read from private field");
30
- return getter ? getter.call(obj) : member.get(obj);
31
- };
32
- var __privateAdd = (obj, member, value) => {
33
- if (member.has(obj))
1
+ var q = Object.defineProperty;
2
+ var D = (t, e, r) => e in t ? q(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
3
+ var w = (t, e, r) => (D(t, typeof e != "symbol" ? e + "" : e, r), r), C = (t, e, r) => {
4
+ if (!e.has(t))
5
+ throw TypeError("Cannot " + r);
6
+ };
7
+ var n = (t, e, r) => (C(t, e, "read from private field"), r ? r.call(t) : e.get(t)), c = (t, e, r) => {
8
+ if (e.has(t))
34
9
  throw TypeError("Cannot add the same private member more than once");
35
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
36
- };
37
- var __privateSet = (obj, member, value, setter) => {
38
- __accessCheck(obj, member, "write to private field");
39
- setter ? setter.call(obj, value) : member.set(obj, value);
40
- return value;
41
- };
42
- var __privateMethod = (obj, member, method) => {
43
- __accessCheck(obj, member, "access private method");
44
- return method;
45
- };
46
- var _a, _value, _reactions, _b, _value2, _reactions2, _f, _depth, _derivatives, _settersQueue, _derivativesQueue, _reactionsQueue, _applyUpdate, applyUpdate_fn;
47
- class LiveFragment {
48
- constructor() {
49
- __publicField(this, "startMarker", document.createTextNode(""));
50
- __publicField(this, "endMarker", document.createTextNode(""));
51
- }
52
- static from(firstNode, lastNode) {
53
- const liveFragment2 = new this();
54
- firstNode.before(liveFragment2.startMarker);
55
- lastNode.after(liveFragment2.endMarker);
56
- return liveFragment2;
57
- }
58
- before(...xs) {
59
- this.startMarker.before(...xs);
60
- }
61
- prepend(...xs) {
62
- this.startMarker.after(...xs);
63
- }
64
- append(...xs) {
65
- this.endMarker.before(...xs);
66
- }
67
- after(...xs) {
68
- this.endMarker.after(...xs);
69
- }
70
- remove() {
71
- const range = document.createRange();
72
- range.setStartBefore(this.startMarker);
73
- range.setEndAfter(this.endMarker);
74
- range.deleteContents();
75
- }
76
- replaceChildren(...xs) {
77
- const range = document.createRange();
78
- range.setStartAfter(this.startMarker);
79
- range.setEndBefore(this.endMarker);
80
- range.deleteContents();
81
- this.startMarker.after(...xs);
82
- }
83
- replaceWith(...xs) {
84
- this.endMarker.after(...xs);
85
- this.remove();
86
- }
87
- get childNodes() {
88
- const childNodes = [];
89
- for (let currentNode = this.startMarker.nextSibling; currentNode != this.endMarker && currentNode; currentNode = currentNode.nextSibling)
90
- childNodes.push(currentNode);
91
- return childNodes;
92
- }
93
- get children() {
94
- return this.childNodes.filter((node) => node instanceof HTMLElement);
95
- }
96
- }
97
- var liveFragment = /* @__PURE__ */ Object.freeze({
98
- __proto__: null,
99
- [Symbol.toStringTag]: "Module",
100
- LiveFragment
101
- });
102
- const isReactive = Symbol.for("bruh reactive");
103
- class SimpleReactive {
104
- constructor(value) {
105
- __publicField(this, _a, true);
106
- __privateAdd(this, _value, void 0);
107
- __privateAdd(this, _reactions, new Set());
108
- __privateSet(this, _value, value);
10
+ e instanceof WeakSet ? e.add(t) : e.set(t, r);
11
+ }, f = (t, e, r, o) => (C(t, e, "write to private field"), o ? o.call(t, r) : e.set(t, r), r);
12
+ var M = (t, e, r) => (C(t, e, "access private method"), r);
13
+ const d = Symbol.for("bruh reactive");
14
+ var _, h, b;
15
+ class L {
16
+ constructor(e) {
17
+ w(this, _, !0);
18
+ c(this, h, void 0);
19
+ c(this, b, /* @__PURE__ */ new Set());
20
+ f(this, h, e);
109
21
  }
110
22
  get value() {
111
- return __privateGet(this, _value);
23
+ return n(this, h);
112
24
  }
113
- set value(newValue) {
114
- if (newValue === __privateGet(this, _value))
115
- return;
116
- __privateSet(this, _value, newValue);
117
- for (const reaction of __privateGet(this, _reactions))
118
- reaction();
25
+ set value(e) {
26
+ if (e !== n(this, h)) {
27
+ f(this, h, e);
28
+ for (const r of n(this, b))
29
+ r();
30
+ }
119
31
  }
120
- addReaction(reaction) {
121
- __privateGet(this, _reactions).add(reaction);
122
- return () => __privateGet(this, _reactions).delete(reaction);
32
+ addReaction(e) {
33
+ return n(this, b).add(e), () => n(this, b).delete(e);
123
34
  }
124
35
  }
125
- _a = isReactive;
126
- _value = new WeakMap();
127
- _reactions = new WeakMap();
128
- const _FunctionalReactive = class {
129
- constructor(x, f) {
130
- __privateAdd(this, _applyUpdate);
131
- __publicField(this, _b, true);
132
- __privateAdd(this, _value2, void 0);
133
- __privateAdd(this, _reactions2, new Set());
134
- __privateAdd(this, _f, void 0);
135
- __privateAdd(this, _depth, 0);
136
- __privateAdd(this, _derivatives, new Set());
137
- if (!f) {
138
- __privateSet(this, _value2, x);
36
+ _ = d, h = new WeakMap(), b = new WeakMap();
37
+ var F, p, v, A, y, T, u, g, N, E, P;
38
+ const a = class {
39
+ constructor(e, r) {
40
+ c(this, E);
41
+ w(this, F, !0);
42
+ c(this, p, void 0);
43
+ c(this, v, /* @__PURE__ */ new Set());
44
+ c(this, A, void 0);
45
+ c(this, y, 0);
46
+ c(this, T, /* @__PURE__ */ new Set());
47
+ if (!r) {
48
+ f(this, p, e);
139
49
  return;
140
50
  }
141
- __privateSet(this, _value2, f());
142
- __privateSet(this, _f, f);
143
- __privateSet(this, _depth, Math.max(...x.map((d) => __privateGet(d, _depth))) + 1);
144
- x.forEach((d) => __privateGet(d, _derivatives).add(this));
51
+ f(this, p, r()), f(this, A, r), f(this, y, Math.max(...e.map((o) => n(o, y))) + 1), e.forEach((o) => n(o, T).add(this));
145
52
  }
146
53
  get value() {
147
- if (__privateGet(_FunctionalReactive, _settersQueue).size) {
148
- if (__privateGet(this, _depth) !== 0)
149
- _FunctionalReactive.applyUpdates();
150
- else if (__privateGet(_FunctionalReactive, _settersQueue).has(this))
151
- return __privateGet(_FunctionalReactive, _settersQueue).get(this);
54
+ if (n(a, u).size) {
55
+ if (n(this, y) !== 0)
56
+ a.applyUpdates();
57
+ else if (n(a, u).has(this))
58
+ return n(a, u).get(this);
152
59
  }
153
- return __privateGet(this, _value2);
60
+ return n(this, p);
154
61
  }
155
- set value(newValue) {
156
- if (__privateGet(this, _depth) !== 0)
157
- return;
158
- if (!__privateGet(_FunctionalReactive, _settersQueue).size)
159
- queueMicrotask(_FunctionalReactive.applyUpdates);
160
- __privateGet(_FunctionalReactive, _settersQueue).set(this, newValue);
62
+ set value(e) {
63
+ n(this, y) === 0 && (n(a, u).size || queueMicrotask(a.applyUpdates), n(a, u).set(this, e));
161
64
  }
162
- addReaction(reaction) {
163
- __privateGet(this, _reactions2).add(reaction);
164
- return () => __privateGet(this, _reactions2).delete(reaction);
65
+ addReaction(e) {
66
+ return n(this, v).add(e), () => n(this, v).delete(e);
165
67
  }
166
68
  static applyUpdates() {
167
- var _a2, _b2, _c;
168
- if (!__privateGet(_FunctionalReactive, _settersQueue).size)
169
- return;
170
- for (const [sourceNode, newValue] of __privateGet(_FunctionalReactive, _settersQueue).entries())
171
- __privateMethod(_a2 = sourceNode, _applyUpdate, applyUpdate_fn).call(_a2, newValue);
172
- __privateGet(_FunctionalReactive, _settersQueue).clear();
173
- for (const depthSet of __privateGet(_FunctionalReactive, _derivativesQueue))
174
- if (depthSet)
175
- for (const derivative of depthSet)
176
- __privateMethod(_c = derivative, _applyUpdate, applyUpdate_fn).call(_c, __privateGet(_b2 = derivative, _f).call(_b2));
177
- __privateGet(_FunctionalReactive, _derivativesQueue).length = 0;
178
- for (const reaction of __privateGet(_FunctionalReactive, _reactionsQueue))
179
- reaction();
180
- __privateGet(_FunctionalReactive, _reactionsQueue).length = 0;
69
+ var e, r, o;
70
+ if (!!n(a, u).size) {
71
+ for (const [s, i] of n(a, u).entries())
72
+ M(e = s, E, P).call(e, i);
73
+ n(a, u).clear();
74
+ for (const s of n(a, g))
75
+ if (s)
76
+ for (const i of s)
77
+ M(o = i, E, P).call(o, n(r = i, A).call(r));
78
+ n(a, g).length = 0;
79
+ for (const s of n(a, N))
80
+ s();
81
+ n(a, N).length = 0;
82
+ }
181
83
  }
182
84
  };
183
- let FunctionalReactive = _FunctionalReactive;
184
- _b = isReactive;
185
- _value2 = new WeakMap();
186
- _reactions2 = new WeakMap();
187
- _f = new WeakMap();
188
- _depth = new WeakMap();
189
- _derivatives = new WeakMap();
190
- _settersQueue = new WeakMap();
191
- _derivativesQueue = new WeakMap();
192
- _reactionsQueue = new WeakMap();
193
- _applyUpdate = new WeakSet();
194
- applyUpdate_fn = function(newValue) {
195
- if (newValue === __privateGet(this, _value2))
85
+ let m = a;
86
+ F = d, p = new WeakMap(), v = new WeakMap(), A = new WeakMap(), y = new WeakMap(), T = new WeakMap(), u = new WeakMap(), g = new WeakMap(), N = new WeakMap(), E = new WeakSet(), P = function(e) {
87
+ if (e === n(this, p))
196
88
  return;
197
- __privateSet(this, _value2, newValue);
198
- __privateGet(_FunctionalReactive, _reactionsQueue).push(...__privateGet(this, _reactions2));
199
- const queue = __privateGet(_FunctionalReactive, _derivativesQueue);
200
- for (const derivative of __privateGet(this, _derivatives)) {
201
- const depth = __privateGet(derivative, _depth);
202
- if (!queue[depth])
203
- queue[depth] = new Set();
204
- queue[depth].add(derivative);
205
- }
206
- };
207
- __privateAdd(FunctionalReactive, _settersQueue, new Map());
208
- __privateAdd(FunctionalReactive, _derivativesQueue, []);
209
- __privateAdd(FunctionalReactive, _reactionsQueue, []);
210
- const r = (x, f) => new FunctionalReactive(x, f);
211
- const reactiveDo = (x, f) => {
212
- if (x == null ? void 0 : x[isReactive]) {
213
- f(x.value);
214
- return x.addReaction(() => f(x.value));
215
- }
216
- f(x);
217
- };
218
- var index$1 = /* @__PURE__ */ Object.freeze({
89
+ f(this, p, e), n(a, N).push(...n(this, v));
90
+ const r = n(a, g);
91
+ for (const o of n(this, T)) {
92
+ const s = n(o, y);
93
+ r[s] || (r[s] = /* @__PURE__ */ new Set()), r[s].add(o);
94
+ }
95
+ }, c(m, u, /* @__PURE__ */ new Map()), c(m, g, []), c(m, N, []);
96
+ const I = (t, e) => new m(t, e), j = (t, e) => {
97
+ if (t != null && t[d])
98
+ return e(t.value), t.addReaction(() => e(t.value));
99
+ e(t);
100
+ }, ee = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
219
101
  __proto__: null,
220
- [Symbol.toStringTag]: "Module",
221
- isReactive,
222
- SimpleReactive,
223
- FunctionalReactive,
224
- r,
225
- reactiveDo
226
- });
227
- const isBruhChild = (x) => (x == null ? void 0 : x[isReactive]) || x instanceof Node || Array.isArray(x) || x == null || !(typeof x === "function" || typeof x === "object");
228
- const toNode = (x) => x instanceof Node ? x : document.createTextNode(x);
229
- const bruhChildrenToNodes = (...children) => children.flat(Infinity).flatMap((child) => {
230
- if (!child[isReactive])
231
- return [toNode(child)];
232
- if (Array.isArray(child.value)) {
233
- const liveFragment2 = new LiveFragment();
234
- child.addReaction(() => {
235
- liveFragment2.replaceChildren(...bruhChildrenToNodes(...child.value));
236
- });
237
- return [liveFragment2.startMarker, ...bruhChildrenToNodes(...child.value), liveFragment2.endMarker];
238
- }
239
- let node = toNode(child.value);
240
- child.addReaction(() => {
241
- const oldNode = node;
242
- node = toNode(child.value);
243
- oldNode.replaceWith(node);
102
+ isReactive: d,
103
+ SimpleReactive: L,
104
+ FunctionalReactive: m,
105
+ r: I,
106
+ reactiveDo: j
107
+ }, Symbol.toStringTag, { value: "Module" })), J = (t) => (t == null ? void 0 : t[d]) || t instanceof Node || Array.isArray(t) || t == null || !(typeof t == "function" || typeof t == "object"), R = (t) => t instanceof Node ? t : typeof t == "boolean" || t === void 0 || t === null ? document.createComment(t) : document.createTextNode(t), O = (t) => {
108
+ let e = R(t.value);
109
+ const r = t.addReaction(() => {
110
+ if (!e.parentNode) {
111
+ r();
112
+ return;
113
+ }
114
+ if (Array.isArray(t.value))
115
+ r(), e.replaceWith(...W(t));
116
+ else {
117
+ const o = e;
118
+ e = R(t.value), o.replaceWith(e);
119
+ }
120
+ });
121
+ return e;
122
+ }, W = (t) => {
123
+ const e = document.createComment("["), r = document.createComment("]"), o = t.addReaction(() => {
124
+ if (!e.parentNode) {
125
+ o();
126
+ return;
127
+ }
128
+ const s = document.createRange();
129
+ s.setStartAfter(e), Array.isArray(t.value) ? (s.setEndBefore(r), s.deleteContents(), e.after(...S(t.value))) : (o(), s.setEndAfter(r), s.deleteContents(), e.replaceWith(O(t)));
244
130
  });
245
- return [node];
246
- });
247
- const applyStyles = (element, styles) => {
248
- for (const property in styles)
249
- reactiveDo(styles[property], (value) => {
250
- if (value !== void 0)
251
- element.style.setProperty(property, value);
252
- else
253
- element.style.removeProperty(property);
131
+ return [
132
+ e,
133
+ ...S(t.value),
134
+ r
135
+ ];
136
+ }, S = (t) => t.flat(1 / 0).flatMap((e) => e != null && e[d] ? Array.isArray(e.value) ? W(e) : [O(e)] : [R(e)]), U = (t, e) => {
137
+ for (const r in e)
138
+ j(e[r], (o) => {
139
+ o !== void 0 ? t.style.setProperty(r, o) : t.style.removeProperty(r);
254
140
  });
255
- };
256
- const applyClasses = (element, classes) => {
257
- for (const name in classes)
258
- reactiveDo(classes[name], (value) => {
259
- element.classList.toggle(name, value);
141
+ }, B = (t, e) => {
142
+ for (const r in e)
143
+ j(e[r], (o) => {
144
+ t.classList.toggle(r, o);
260
145
  });
261
- };
262
- const applyAttributes = (element, attributes) => {
263
- for (const name in attributes)
264
- reactiveDo(attributes[name], (value) => {
265
- if (value !== void 0)
266
- element.setAttribute(name, value);
267
- else
268
- element.removeAttribute(name);
146
+ }, Q = (t, e) => {
147
+ for (const r in e)
148
+ j(e[r], (o) => {
149
+ o !== void 0 ? t.setAttribute(r, o) : t.removeAttribute(r);
269
150
  });
270
- };
271
- const t = (textContent) => {
272
- if (!textContent[isReactive])
273
- return document.createTextNode(textContent);
274
- const node = document.createTextNode(textContent.value);
275
- textContent.addReaction(() => {
276
- node.textContent = textContent.value;
277
- });
278
- return node;
279
- };
280
- const e = (name) => (...variadic) => {
281
- var _a2;
282
- if (isBruhChild(variadic[0])) {
283
- const element2 = document.createElement(name);
284
- element2.append(...bruhChildrenToNodes(...variadic));
285
- return element2;
286
- }
287
- const [props, ...children] = variadic;
288
- const { namespace } = (_a2 = props.bruh) != null ? _a2 : {};
289
- delete props.bruh;
290
- const element = namespace ? document.createElementNS(namespace, name) : document.createElement(name);
291
- if (typeof props.style === "object" && !props.style[isReactive]) {
292
- applyStyles(element, props.style);
293
- delete props.style;
294
- }
295
- if (typeof props.class === "object" && !props.style[isReactive]) {
296
- applyClasses(element, props.class);
297
- delete props.class;
298
- }
299
- for (const name2 in props) {
300
- if (name2.startsWith("on") && typeof props[name2] === "function") {
301
- element.addEventListener(name2.slice(2), props[name2]);
302
- delete props[name2];
303
- }
304
- }
305
- applyAttributes(element, props);
306
- element.append(...bruhChildrenToNodes(...children));
307
- return element;
308
- };
309
- const h = (nameOrComponent, props, ...children) => {
310
- if (typeof nameOrComponent === "string") {
311
- const makeElement = e(nameOrComponent);
312
- return props ? makeElement(props, ...children) : makeElement(...children);
313
- }
314
- return nameOrComponent(__spreadProps(__spreadValues({}, props), { children }));
315
- };
316
- const JSXFragment = ({ children }) => children;
317
- const hydrateTextNodes = () => {
318
- const tagged = {};
319
- const bruhTextNodes = document.getElementsByTagName("bruh-textnode");
320
- for (const bruhTextNode of bruhTextNodes) {
321
- const textNode = document.createTextNode(bruhTextNode.textContent);
322
- const tag = bruhTextNode.getAttribute("tag");
323
- if (tag)
324
- tagged[tag] = textNode;
325
- bruhTextNode.replaceWith(textNode);
326
- }
327
- return tagged;
328
- };
329
- var index_browser = /* @__PURE__ */ Object.freeze({
151
+ }, X = (t) => {
152
+ if (!t[d])
153
+ return document.createTextNode(t);
154
+ const e = document.createTextNode(t.value);
155
+ return t.addReaction(() => {
156
+ e.textContent = t.value;
157
+ }), e;
158
+ }, k = (t) => (...e) => {
159
+ var z;
160
+ if (e.length === 0)
161
+ return document.createElement(t);
162
+ if (J(e[0])) {
163
+ const l = document.createElement(t);
164
+ return l.append(...S(e)), l;
165
+ }
166
+ const [r, ...o] = e, { namespace: s } = (z = r.bruh) != null ? z : {};
167
+ delete r.bruh;
168
+ const i = s ? document.createElementNS(s, t) : document.createElement(t);
169
+ typeof r.style == "object" && !r.style[d] && (U(i, r.style), delete r.style), typeof r.class == "object" && !r.class[d] && (B(i, r.class), delete r.class);
170
+ for (const l in r)
171
+ l.startsWith("on") && typeof r[l] == "function" && (i.addEventListener(l.slice(2), r[l]), delete r[l]);
172
+ return Q(i, r), i.append(...S(o)), i;
173
+ }, $ = (t, e, ...r) => {
174
+ if (typeof t == "string") {
175
+ const o = k(t);
176
+ return e ? o(e, ...r) : o(...r);
177
+ }
178
+ return t({ ...e, children: r });
179
+ }, G = ({ children: t }) => t, H = () => {
180
+ const t = {}, e = document.getElementsByTagName("bruh-textnode");
181
+ for (const r of e) {
182
+ const o = document.createTextNode(r.textContent), s = r.getAttribute("tag");
183
+ s && (t[s] = o), r.replaceWith(o);
184
+ }
185
+ return t;
186
+ }, te = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
330
187
  __proto__: null,
331
- [Symbol.toStringTag]: "Module",
332
- bruhChildrenToNodes,
333
- applyStyles,
334
- applyClasses,
335
- applyAttributes,
336
- t,
337
- e,
338
- h,
339
- JSXFragment,
340
- hydrateTextNodes
341
- });
342
- const pipe = (x, ...fs) => fs.reduce((y, f) => f(y), x);
343
- const dispatch = (target, type, options) => target.dispatchEvent(new CustomEvent(type, __spreadValues({
344
- bubbles: true,
345
- cancelable: true,
346
- composed: true
347
- }, options)));
348
- const createDestructable = (object, iterable) => {
349
- const destructable = __spreadProps(__spreadValues({}, object), {
350
- [Symbol.iterator]: () => iterable[Symbol.iterator]()
351
- });
352
- Object.defineProperty(destructable, Symbol.iterator, {
353
- enumerable: false
354
- });
355
- return destructable;
356
- };
357
- const functionAsObject = (f) => new Proxy({}, {
358
- get: (_, property) => f(property)
359
- });
360
- var index = /* @__PURE__ */ Object.freeze({
188
+ bruhChildrenToNodes: S,
189
+ applyStyles: U,
190
+ applyClasses: B,
191
+ applyAttributes: Q,
192
+ t: X,
193
+ e: k,
194
+ h: $,
195
+ JSXFragment: G,
196
+ hydrateTextNodes: H
197
+ }, Symbol.toStringTag, { value: "Module" })), K = (t, ...e) => e.reduce((r, o) => o(r), t), Y = (t, e, r) => t.dispatchEvent(
198
+ new CustomEvent(e, {
199
+ bubbles: !0,
200
+ cancelable: !0,
201
+ composed: !0,
202
+ ...r
203
+ })
204
+ ), Z = (t, e) => {
205
+ const r = {
206
+ ...t,
207
+ [Symbol.iterator]: () => e[Symbol.iterator]()
208
+ };
209
+ return Object.defineProperty(r, Symbol.iterator, {
210
+ enumerable: !1
211
+ }), r;
212
+ }, V = (t) => new Proxy({}, {
213
+ get: (e, r) => t(r)
214
+ }), re = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
361
215
  __proto__: null,
362
- [Symbol.toStringTag]: "Module",
363
- pipe,
364
- dispatch,
365
- createDestructable,
366
- functionAsObject
367
- });
368
- export { index_browser as dom, liveFragment, index$1 as reactive, index as util };
216
+ pipe: K,
217
+ dispatch: Y,
218
+ createDestructable: Z,
219
+ functionAsObject: V
220
+ }, Symbol.toStringTag, { value: "Module" }));
221
+ export {
222
+ te as dom,
223
+ ee as reactive,
224
+ re as util
225
+ };
369
226
  //# sourceMappingURL=bruh.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bruh.es.js","sources":["../src/dom/live-fragment.mjs","../src/reactive/index.mjs","../src/dom/index.browser.mjs","../src/util/index.mjs"],"sourcesContent":["// Lightweight and performant DOM fragment that keeps its place,\n// useful for grouping siblings without making a parent element.\n// Not a true analog of the DocumentFragment, because the implementation\n// would be infeasible with that scope, adding a performance penalty as well.\n// Works as long as the start & end placeholders are siblings in that order\n// and they do not overlap other LiveFragment's:\n// Works: (start A)(start B)(end B)(end A)\n// Fails: (start A)(start B)(end A)(end B)\n// Also, make sure not to call .normalize() on the parent element,\n// because that would ruin the placeholders.\nexport class LiveFragment {\n startMarker = document.createTextNode(\"\")\n endMarker = document.createTextNode(\"\")\n\n static from(firstNode, lastNode) {\n const liveFragment = new this()\n firstNode.before(liveFragment.startMarker)\n lastNode.after(liveFragment.endMarker)\n return liveFragment\n }\n\n before(...xs) {\n this.startMarker.before(...xs)\n }\n\n prepend(...xs) {\n this.startMarker.after(...xs)\n }\n\n append(...xs) {\n this.endMarker.before(...xs)\n }\n\n after(...xs) {\n this.endMarker.after(...xs)\n }\n\n remove() {\n const range = document.createRange()\n range.setStartBefore(this.startMarker)\n range.setEndAfter(this.endMarker)\n range.deleteContents()\n }\n\n replaceChildren(...xs) {\n const range = document.createRange()\n range.setStartAfter(this.startMarker)\n range.setEndBefore(this.endMarker)\n range.deleteContents()\n this.startMarker.after(...xs)\n }\n\n replaceWith(...xs) {\n this.endMarker.after(...xs)\n this.remove()\n }\n\n get childNodes() {\n const childNodes = []\n\n for (\n let currentNode = this.startMarker.nextSibling;\n currentNode != this.endMarker && currentNode;\n currentNode = currentNode.nextSibling\n )\n childNodes.push(currentNode)\n\n return childNodes\n }\n\n get children() {\n return this.childNodes\n .filter(node => node instanceof HTMLElement)\n }\n}\n","export const isReactive = Symbol.for(\"bruh reactive\")\n\n// A super simple and performant reactive value implementation\nexport class SimpleReactive {\n [isReactive] = true\n\n #value\n #reactions = new Set()\n\n constructor(value) {\n this.#value = value\n }\n\n get value() {\n return this.#value\n }\n\n set value(newValue) {\n if (newValue === this.#value)\n return\n\n this.#value = newValue\n for (const reaction of this.#reactions)\n reaction()\n }\n\n addReaction(reaction) {\n this.#reactions.add(reaction)\n\n return () =>\n this.#reactions.delete(reaction)\n }\n}\n\n// A reactive implementation for building functional reactive graphs\n// Ensures state consistency, minimal node updates, and transparent update batching\nexport class FunctionalReactive {\n [isReactive] = true\n\n #value\n #reactions = new Set()\n\n // For derived nodes, f is the derivation function\n #f\n // Source nodes are 0 deep in the derivation graph\n // This is for topological sort\n #depth = 0\n // All nodes have a set of derivatives that update when the node changes\n #derivatives = new Set()\n\n // Keep track of all the pending changes from the value setter\n static #settersQueue = new Map()\n // A queue of derivatives to potentially update, sorted into sets by depth\n // This starts with depth 1 and can potentially have holes\n static #derivativesQueue = []\n // A queue of reactions to run after the graph is fully updated\n static #reactionsQueue = []\n\n constructor(x, f) {\n if (!f) {\n this.#value = x\n return\n }\n\n this.#value = f()\n this.#f = f\n this.#depth = Math.max(...x.map(d => d.#depth)) + 1\n\n x.forEach(d => d.#derivatives.add(this))\n }\n\n get value() {\n // If there are any pending updates\n if (FunctionalReactive.#settersQueue.size) {\n // Heuristic quick invalidation for derived nodes\n // Apply updates now, it's ok that there's already a microtask queued for this\n if (this.#depth !== 0)\n FunctionalReactive.applyUpdates()\n // If this is a source node that was updated, just return that\n // new value without actually updating any derived nodes yet\n else if (FunctionalReactive.#settersQueue.has(this))\n return FunctionalReactive.#settersQueue.get(this)\n }\n\n return this.#value\n }\n\n set value(newValue) {\n // Only allow source nodes to be directly updated\n if (this.#depth !== 0)\n return\n\n // Unless asked for earlier, these updates are just queued up until the microtasks run\n if (!FunctionalReactive.#settersQueue.size)\n queueMicrotask(FunctionalReactive.applyUpdates)\n\n FunctionalReactive.#settersQueue.set(this, newValue)\n }\n\n addReaction(reaction) {\n this.#reactions.add(reaction)\n\n return () =>\n this.#reactions.delete(reaction)\n }\n\n // Apply an update for a node and queue its derivatives if it actually changed\n #applyUpdate(newValue) {\n if (newValue === this.#value)\n return\n\n this.#value = newValue\n FunctionalReactive.#reactionsQueue.push(...this.#reactions)\n\n const queue = FunctionalReactive.#derivativesQueue\n for (const derivative of this.#derivatives) {\n const depth = derivative.#depth\n if (!queue[depth])\n queue[depth] = new Set()\n\n queue[depth].add(derivative)\n }\n }\n\n // Apply pending updates from actually changed source nodes\n static applyUpdates() {\n if (!FunctionalReactive.#settersQueue.size)\n return\n\n // Bootstrap by applying the updates from the pending setters\n for (const [sourceNode, newValue] of FunctionalReactive.#settersQueue.entries())\n sourceNode.#applyUpdate(newValue)\n FunctionalReactive.#settersQueue.clear()\n\n // Iterate down the depths, ignoring holes\n // Note that both the queue (Array) and each depth Set iterators update as items are added\n for (const depthSet of FunctionalReactive.#derivativesQueue) if (depthSet)\n for (const derivative of depthSet)\n derivative.#applyUpdate(derivative.#f())\n FunctionalReactive.#derivativesQueue.length = 0\n\n // Call all reactions now that the graph has a fully consistent state\n for (const reaction of FunctionalReactive.#reactionsQueue)\n reaction()\n FunctionalReactive.#reactionsQueue.length = 0\n }\n}\n\n// A little convenience function\nexport const r = (x, f) => new FunctionalReactive(x, f)\n\n// Do something with a value, updating if it is reactive\nexport const reactiveDo = (x, f) => {\n if (x?.[isReactive]) {\n f(x.value)\n return x.addReaction(() => f(x.value))\n }\n\n f(x)\n}\n","import { LiveFragment } from \"./live-fragment.mjs\"\nimport { isReactive, reactiveDo } from \"../reactive/index.mjs\"\n\n//#region Bruh child functions e.g. bruhChildrenToNodes()\n\n// A basic check for if a value is allowed as a child in bruh\n// It's responsible for quickly checking the type, not deep validation\nconst isBruhChild = x =>\n // Reactives and DOM nodes\n x?.[isReactive] ||\n x instanceof Node ||\n // Any array, just assume it contains valid children\n Array.isArray(x) ||\n // Allow nullish\n x == null ||\n // Disallow functions and objects\n !(typeof x === \"function\" || typeof x === \"object\")\n // Everything else can be a child when stringified\n\n// Coerces input into a DOM node, if it isn't already one\nconst toNode = x =>\n x instanceof Node\n ? x\n : document.createTextNode(x)\n\n// Processes bruh children into an array of DOM nodes\n// Reactive values are automatically replaced, so the output must be placed into a parent node\n// before any top level (after flattening arrays) reactions run\nexport const bruhChildrenToNodes = (...children) =>\n children\n .flat(Infinity)\n .flatMap(child => {\n // Non-reactive values are untouched\n if (!child[isReactive])\n return [toNode(child)]\n\n // Reactive arrays become live fragments with auto-swapped children\n if (Array.isArray(child.value)) {\n const liveFragment = new LiveFragment()\n child.addReaction(() => {\n liveFragment.replaceChildren(...bruhChildrenToNodes(...child.value))\n })\n return [liveFragment.startMarker, ...bruhChildrenToNodes(...child.value), liveFragment.endMarker]\n }\n\n // Reactive values become auto-swapped DOM nodes\n let node = toNode(child.value)\n child.addReaction(() => {\n const oldNode = node\n node = toNode(child.value)\n oldNode.replaceWith(node)\n })\n return [node]\n })\n\n//#endregion\n\n//#region Reactive-aware element helper functions e.g. applyAttributes()\n\n// Style attribute rules from an object with\n// potentially reactive and/or undefined values\nexport const applyStyles = (element, styles) => {\n for (const property in styles)\n reactiveDo(styles[property], value => {\n if (value !== undefined)\n element.style.setProperty (property, value)\n else\n element.style.removeProperty(property)\n })\n}\n\n// Class list from an object mapping from\n// class names to potentially reactive booleans\nexport const applyClasses = (element, classes) => {\n for (const name in classes)\n reactiveDo(classes[name], value => {\n element.classList.toggle(name, value)\n })\n}\n\n// Attributes from an object with\n// potentially reactive and/or undefined values\nexport const applyAttributes = (element, attributes) => {\n for (const name in attributes)\n reactiveDo(attributes[name], value => {\n if (value !== undefined)\n element.setAttribute (name, value)\n else\n element.removeAttribute(name)\n })\n}\n\n//#endregion\n\n//#region t() for text nodes and e() for element nodes\n\n// Text nodes\nexport const t = textContent => {\n // Non-reactive values are just text nodes\n if (!textContent[isReactive])\n return document.createTextNode(textContent)\n\n // Reactive values auto-update the node's text content\n const node = document.createTextNode(textContent.value)\n textContent.addReaction(() => {\n node.textContent = textContent.value\n })\n return node\n}\n\n// Elements\nexport const e = name => (...variadic) => {\n // If there are no props\n if (isBruhChild(variadic[0])) {\n const element = document.createElement(name)\n element.append(...bruhChildrenToNodes(...variadic))\n return element\n }\n\n // If props exist as the first variadic argument\n const [props, ...children] = variadic\n\n // Extract explicit options from the bruh prop\n const { namespace } = props.bruh ?? {}\n delete props.bruh\n\n // Make an element with optional namespace\n const element =\n namespace\n ? document.createElementNS(namespace, name)\n : document.createElement ( name)\n\n // Apply overloaded props, if possible\n\n // Inline style object\n if (typeof props.style === \"object\" && !props.style[isReactive]) {\n applyStyles(element, props.style)\n delete props.style\n }\n // Classes object\n if (typeof props.class === \"object\" && !props.style[isReactive]) {\n applyClasses(element, props.class)\n delete props.class\n }\n for (const name in props) {\n // Event listener functions\n if (name.startsWith(\"on\") && typeof props[name] === \"function\") {\n element.addEventListener(name.slice(2), props[name])\n delete props[name]\n }\n }\n\n // The rest of the props are attributes\n applyAttributes(element, props)\n\n // Add the children to the element\n element.append(...bruhChildrenToNodes(...children))\n return element\n}\n\n//#endregion\n\n//#region JSX integration\n\n// The function that jsx tags (except fragments) compile to\nexport const h = (nameOrComponent, props, ...children) => {\n // If we are making an element, this is just a wrapper of e()\n // This is likely when the JSX tag name begins with a lowercase character\n if (typeof nameOrComponent === \"string\") {\n const makeElement = e(nameOrComponent)\n return props\n ? makeElement(props, ...children)\n : makeElement(...children)\n }\n\n // It must be a component, then, as bruh components are just functions\n // Due to JSX, this would mean a function with only one parameter - props\n // This object includes the all of the normal props and a \"children\" key\n return nameOrComponent({ ...props, children })\n}\n\n// The JSX fragment is made into a bruh fragment (just an array)\nexport const JSXFragment = ({ children }) => children\n\n//#endregion\n\n\n\n// Hydration of all bruh-textnode's from prerendered html\nexport const hydrateTextNodes = () => {\n const tagged = {}\n const bruhTextNodes = document.getElementsByTagName(\"bruh-textnode\")\n\n for (const bruhTextNode of bruhTextNodes) {\n const textNode = document.createTextNode(bruhTextNode.textContent)\n\n const tag = bruhTextNode.getAttribute(\"tag\")\n if (tag)\n tagged[tag] = textNode\n\n bruhTextNode.replaceWith(textNode)\n }\n\n return tagged\n}\n","// Create a pipeline with an initial value and a series of functions\nexport const pipe = (x, ...fs) =>\n fs.reduce((y, f) => f(y), x)\n\n// Dispatch a custom event to (capturing) and from (bubbling) a target (usually a DOM node)\n// Returns false if the event was cancelled (preventDefault()) and true otherwise\nexport const dispatch = (target, type, options) =>\n target.dispatchEvent(\n // Default to behave like most DOM events\n new CustomEvent(type, {\n bubbles: true,\n cancelable: true,\n composed: true,\n ...options\n })\n )\n\n// Inspired by https://antfu.me/posts/destructuring-with-object-or-array#take-away\n// Creates an object that is both destructable with {...} and [...]\n// Useful for writing library functions à la react-use & vueuse\nexport const createDestructable = (object, iterable) => {\n const destructable = {\n ...object,\n [Symbol.iterator]: () => iterable[Symbol.iterator]()\n }\n\n Object.defineProperty(destructable, Symbol.iterator, {\n enumerable: false\n })\n\n return destructable\n}\n\n// Creates an object (as a Proxy) that acts as a function\n// So functionAsObject(f).property is equivalent to f(\"property\")\n// This is can be useful when combined with destructuring syntax, e.g.:\n// const { html, head, title, body, main, h1, p } = functionAsObject(e)\nexport const functionAsObject = f =>\n new Proxy({}, {\n get: (_, property) => f(property)\n })\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bruh.es.js","sources":["../src/reactive/index.mjs","../src/dom/index.browser.mjs","../src/util/index.mjs"],"sourcesContent":["export const isReactive = Symbol.for(\"bruh reactive\")\n\n// A super simple and performant reactive value implementation\nexport class SimpleReactive {\n [isReactive] = true\n\n #value\n #reactions = new Set()\n\n constructor(value) {\n this.#value = value\n }\n\n get value() {\n return this.#value\n }\n\n set value(newValue) {\n if (newValue === this.#value)\n return\n\n this.#value = newValue\n for (const reaction of this.#reactions)\n reaction()\n }\n\n addReaction(reaction) {\n this.#reactions.add(reaction)\n\n return () =>\n this.#reactions.delete(reaction)\n }\n}\n\n// A reactive implementation for building functional reactive graphs\n// Ensures state consistency, minimal node updates, and transparent update batching\nexport class FunctionalReactive {\n [isReactive] = true\n\n #value\n #reactions = new Set()\n\n // For derived nodes, f is the derivation function\n #f\n // Source nodes are 0 deep in the derivation graph\n // This is for topological sort\n #depth = 0\n // All nodes have a set of derivatives that update when the node changes\n #derivatives = new Set()\n\n // Keep track of all the pending changes from the value setter\n static #settersQueue = new Map()\n // A queue of derivatives to potentially update, sorted into sets by depth\n // This starts with depth 1 and can potentially have holes\n static #derivativesQueue = []\n // A queue of reactions to run after the graph is fully updated\n static #reactionsQueue = []\n\n constructor(x, f) {\n if (!f) {\n this.#value = x\n return\n }\n\n this.#value = f()\n this.#f = f\n this.#depth = Math.max(...x.map(d => d.#depth)) + 1\n\n x.forEach(d => d.#derivatives.add(this))\n }\n\n get value() {\n // If there are any pending updates\n if (FunctionalReactive.#settersQueue.size) {\n // Heuristic quick invalidation for derived nodes\n // Apply updates now, it's ok that there's already a microtask queued for this\n if (this.#depth !== 0)\n FunctionalReactive.applyUpdates()\n // If this is a source node that was updated, just return that\n // new value without actually updating any derived nodes yet\n else if (FunctionalReactive.#settersQueue.has(this))\n return FunctionalReactive.#settersQueue.get(this)\n }\n\n return this.#value\n }\n\n set value(newValue) {\n // Only allow source nodes to be directly updated\n if (this.#depth !== 0)\n return\n\n // Unless asked for earlier, these updates are just queued up until the microtasks run\n if (!FunctionalReactive.#settersQueue.size)\n queueMicrotask(FunctionalReactive.applyUpdates)\n\n FunctionalReactive.#settersQueue.set(this, newValue)\n }\n\n addReaction(reaction) {\n this.#reactions.add(reaction)\n\n return () =>\n this.#reactions.delete(reaction)\n }\n\n // Apply an update for a node and queue its derivatives if it actually changed\n #applyUpdate(newValue) {\n if (newValue === this.#value)\n return\n\n this.#value = newValue\n FunctionalReactive.#reactionsQueue.push(...this.#reactions)\n\n const queue = FunctionalReactive.#derivativesQueue\n for (const derivative of this.#derivatives) {\n const depth = derivative.#depth\n if (!queue[depth])\n queue[depth] = new Set()\n\n queue[depth].add(derivative)\n }\n }\n\n // Apply pending updates from actually changed source nodes\n static applyUpdates() {\n if (!FunctionalReactive.#settersQueue.size)\n return\n\n // Bootstrap by applying the updates from the pending setters\n for (const [sourceNode, newValue] of FunctionalReactive.#settersQueue.entries())\n sourceNode.#applyUpdate(newValue)\n FunctionalReactive.#settersQueue.clear()\n\n // Iterate down the depths, ignoring holes\n // Note that both the queue (Array) and each depth Set iterators update as items are added\n for (const depthSet of FunctionalReactive.#derivativesQueue) if (depthSet)\n for (const derivative of depthSet)\n derivative.#applyUpdate(derivative.#f())\n FunctionalReactive.#derivativesQueue.length = 0\n\n // Call all reactions now that the graph has a fully consistent state\n for (const reaction of FunctionalReactive.#reactionsQueue)\n reaction()\n FunctionalReactive.#reactionsQueue.length = 0\n }\n}\n\n// A little convenience function\nexport const r = (x, f) => new FunctionalReactive(x, f)\n\n// Do something with a value, updating if it is reactive\nexport const reactiveDo = (x, f) => {\n if (x?.[isReactive]) {\n f(x.value)\n return x.addReaction(() => f(x.value))\n }\n\n f(x)\n}\n","import { isReactive, reactiveDo } from \"../reactive/index.mjs\"\n\n//#region Bruh child functions e.g. bruhChildrenToNodes()\n\n// A basic check for if a value is allowed as a child in bruh\n// It's responsible for quickly checking the type, not deep validation\nconst isBruhChild = x =>\n // Reactives and DOM nodes\n x?.[isReactive] ||\n x instanceof Node ||\n // Any array, just assume it contains valid children\n Array.isArray(x) ||\n // Allow nullish\n x == null ||\n // Disallow functions and objects\n !(typeof x === \"function\" || typeof x === \"object\")\n // Everything else can be a child when stringified\n\n// Coerces input into a DOM node, if it isn't already one\nconst unreactiveChildToNode = x => {\n // Existing DOM nodes are untouched\n if (x instanceof Node)\n return x\n // booleans and nullish are ignored\n else if (typeof x === \"boolean\" || x === undefined || x === null)\n return document.createComment(x)\n // Anything else is treated as text\n else\n return document.createTextNode(x)\n}\n\n// Auto-swapping single reactive node\nconst reactiveChildToNode = child => {\n let node = unreactiveChildToNode(child.value)\n\n const stopReacting = child.addReaction(() => {\n // Stop swapping if no longer possible\n if (!node.parentNode) {\n stopReacting()\n return\n }\n\n // Normal swap\n if (!Array.isArray(child.value)) {\n const oldNode = node\n node = unreactiveChildToNode(child.value)\n oldNode.replaceWith(node)\n }\n // If an array now, stop swapping, then switch to reactive array swapping\n else {\n stopReacting()\n node.replaceWith(...reactiveArrayChildToNodes(child))\n }\n })\n\n return node\n}\n\n// Auto-swapping reactive array of nodes\nconst reactiveArrayChildToNodes = child => {\n // Markers owned by the swapper here itself, so that\n // the values in the array can be swapped separately\n const first = document.createComment(\"[\")\n const last = document.createComment(\"]\")\n\n const stopReacting = child.addReaction(() => {\n // Stop swapping if there is no parent to swap within\n if (!first.parentNode) {\n stopReacting()\n return\n }\n\n // Make a range starting after the first marker\n const range = document.createRange()\n range.setStartAfter(first)\n\n // Normal swap, replacing content between the first and last markers\n if (Array.isArray(child.value)) {\n range.setEndBefore(last)\n range.deleteContents()\n first.after(...bruhChildrenToNodes(child.value))\n }\n // Switch to single swapping node by replacing everything\n else {\n stopReacting()\n range.setEndAfter(last)\n range.deleteContents()\n first.replaceWith(reactiveChildToNode(child))\n }\n })\n\n return [\n first,\n ...bruhChildrenToNodes(child.value),\n last\n ]\n}\n\n// Processes bruh children into an array of DOM nodes\n// Reactive values are automatically replaced, so the output must be placed into a parent node\n// before any top level (after flattening arrays) reactions run\nexport const bruhChildrenToNodes = children =>\n children\n .flat(Infinity)\n .flatMap(child => {\n // Non-reactive child\n if (!child?.[isReactive])\n return [unreactiveChildToNode(child)]\n\n // Single reactive value\n if (!Array.isArray(child.value))\n return [reactiveChildToNode(child)]\n\n // Reactive array\n return reactiveArrayChildToNodes(child)\n })\n\n//#endregion\n\n//#region Reactive-aware element helper functions e.g. applyAttributes()\n\n// Style attribute rules from an object with\n// potentially reactive and/or undefined values\nexport const applyStyles = (element, styles) => {\n for (const property in styles)\n reactiveDo(styles[property], value => {\n if (value !== undefined)\n element.style.setProperty (property, value)\n else\n element.style.removeProperty(property)\n })\n}\n\n// Class list from an object mapping from\n// class names to potentially reactive booleans\nexport const applyClasses = (element, classes) => {\n for (const name in classes)\n reactiveDo(classes[name], value => {\n element.classList.toggle(name, value)\n })\n}\n\n// Attributes from an object with\n// potentially reactive and/or undefined values\nexport const applyAttributes = (element, attributes) => {\n for (const name in attributes)\n reactiveDo(attributes[name], value => {\n if (value !== undefined)\n element.setAttribute (name, value)\n else\n element.removeAttribute(name)\n })\n}\n\n//#endregion\n\n//#region t() for text nodes and e() for element nodes\n\n// Text nodes\nexport const t = textContent => {\n // Non-reactive values are just text nodes\n if (!textContent[isReactive])\n return document.createTextNode(textContent)\n\n // Reactive values auto-update the node's text content\n const node = document.createTextNode(textContent.value)\n textContent.addReaction(() => {\n node.textContent = textContent.value\n })\n return node\n}\n\n// Elements\nexport const e = name => (...variadic) => {\n if (variadic.length === 0)\n return document.createElement(name)\n\n // If there are no props\n if (isBruhChild(variadic[0])) {\n const element = document.createElement(name)\n element.append(...bruhChildrenToNodes(variadic))\n return element\n }\n\n // If props exist as the first variadic argument\n const [props, ...children] = variadic\n\n // Extract explicit options from the bruh prop\n const { namespace } = props.bruh ?? {}\n delete props.bruh\n\n // Make an element with optional namespace\n const element =\n namespace\n ? document.createElementNS(namespace, name)\n : document.createElement ( name)\n\n // Apply overloaded props, if possible\n\n // Inline style object\n if (typeof props.style === \"object\" && !props.style[isReactive]) {\n applyStyles(element, props.style)\n delete props.style\n }\n // Classes object\n if (typeof props.class === \"object\" && !props.class[isReactive]) {\n applyClasses(element, props.class)\n delete props.class\n }\n for (const name in props) {\n // Event listener functions\n if (name.startsWith(\"on\") && typeof props[name] === \"function\") {\n element.addEventListener(name.slice(2), props[name])\n delete props[name]\n }\n }\n\n // The rest of the props are attributes\n applyAttributes(element, props)\n\n // Add the children to the element\n element.append(...bruhChildrenToNodes(children))\n return element\n}\n\n//#endregion\n\n//#region JSX integration\n\n// The function that jsx tags (except fragments) compile to\nexport const h = (nameOrComponent, props, ...children) => {\n // If we are making an element, this is just a wrapper of e()\n // This is likely when the JSX tag name begins with a lowercase character\n if (typeof nameOrComponent === \"string\") {\n const makeElement = e(nameOrComponent)\n return props\n ? makeElement(props, ...children)\n : makeElement(...children)\n }\n\n // It must be a component, then, as bruh components are just functions\n // Due to JSX, this would mean a function with only one parameter - props\n // This object includes the all of the normal props and a \"children\" key\n return nameOrComponent({ ...props, children })\n}\n\n// The JSX fragment is made into a bruh fragment (just an array)\nexport const JSXFragment = ({ children }) => children\n\n//#endregion\n\n\n\n// Hydration of all bruh-textnode's from prerendered html\nexport const hydrateTextNodes = () => {\n const tagged = {}\n const bruhTextNodes = document.getElementsByTagName(\"bruh-textnode\")\n\n for (const bruhTextNode of bruhTextNodes) {\n const textNode = document.createTextNode(bruhTextNode.textContent)\n\n const tag = bruhTextNode.getAttribute(\"tag\")\n if (tag)\n tagged[tag] = textNode\n\n bruhTextNode.replaceWith(textNode)\n }\n\n return tagged\n}\n","// Create a pipeline with an initial value and a series of functions\nexport const pipe = (x, ...fs) =>\n fs.reduce((y, f) => f(y), x)\n\n// Dispatch a custom event to (capturing) and from (bubbling) a target (usually a DOM node)\n// Returns false if the event was cancelled (preventDefault()) and true otherwise\n// Note that this is synchronous\nexport const dispatch = (target, type, options) =>\n target.dispatchEvent(\n // Default to behave like most DOM events\n new CustomEvent(type, {\n bubbles: true,\n cancelable: true,\n composed: true,\n ...options\n })\n )\n\n// Inspired by https://antfu.me/posts/destructuring-with-object-or-array#take-away\n// Creates an object that is both destructable with {...} and [...]\n// Useful for writing library functions à la react-use & vueuse\nexport const createDestructable = (object, iterable) => {\n const destructable = {\n ...object,\n [Symbol.iterator]: () => iterable[Symbol.iterator]()\n }\n\n Object.defineProperty(destructable, Symbol.iterator, {\n enumerable: false\n })\n\n return destructable\n}\n\n// Creates an object (as a Proxy) that acts as a function\n// So functionAsObject(f).property is equivalent to f(\"property\")\n// This is can be useful when combined with destructuring syntax, e.g.:\n// const { html, head, title, body, main, h1, p } = functionAsObject(e)\nexport const functionAsObject = f =>\n new Proxy({}, {\n get: (_, property) => f(property)\n })\n"],"names":["isReactive","_a","_value","_reactions","SimpleReactive","value","__publicField","__privateAdd","__privateSet","__privateGet","newValue","reaction","_f","_depth","_derivatives","_settersQueue","_derivativesQueue","_reactionsQueue","_applyUpdate","applyUpdate_fn","_FunctionalReactive","x","f","d","_b","_c","sourceNode","__privateMethod","depthSet","derivative","FunctionalReactive","queue","depth","r","reactiveDo","isBruhChild","unreactiveChildToNode","reactiveChildToNode","child","node","stopReacting","reactiveArrayChildToNodes","oldNode","first","last","range","bruhChildrenToNodes","children","applyStyles","element","styles","property","applyClasses","classes","name","applyAttributes","attributes","t","textContent","e","variadic","props","namespace","h","nameOrComponent","makeElement","JSXFragment","hydrateTextNodes","tagged","bruhTextNodes","bruhTextNode","textNode","tag","pipe","fs","y","dispatch","target","type","options","createDestructable","object","iterable","destructable","functionAsObject","_"],"mappings":"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"}
package/dist/bruh.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- var ne=Object.defineProperty,se=Object.defineProperties;var oe=Object.getOwnPropertyDescriptors;var Q=Object.getOwnPropertySymbols;var ae=Object.prototype.hasOwnProperty,ie=Object.prototype.propertyIsEnumerable;var F=(n,s,i)=>s in n?ne(n,s,{enumerable:!0,configurable:!0,writable:!0,value:i}):n[s]=i,z=(n,s)=>{for(var i in s||(s={}))ae.call(s,i)&&F(n,i,s[i]);if(Q)for(var i of Q(s))ie.call(s,i)&&F(n,i,s[i]);return n},O=(n,s)=>se(n,oe(s));var w=(n,s,i)=>(F(n,typeof s!="symbol"?s+"":s,i),i),L=(n,s,i)=>{if(!s.has(n))throw TypeError("Cannot "+i)};var a=(n,s,i)=>(L(n,s,"read from private field"),i?i.call(n):s.get(n)),l=(n,s,i)=>{if(s.has(n))throw TypeError("Cannot add the same private member more than once");s instanceof WeakSet?s.add(n):s.set(n,i)},y=(n,s,i,u)=>(L(n,s,"write to private field"),u?u.call(n,i):s.set(n,i),i);var P=(n,s,i)=>(L(n,s,"access private method"),i);(function(n,s){typeof exports=="object"&&typeof module!="undefined"?s(exports):typeof define=="function"&&define.amd?define(["exports"],s):(n=typeof globalThis!="undefined"?globalThis:n||self,s(n.bruh={}))})(this,function(n){var ce,v,S,de,p,M,A,m,j,f,N,T,E,q;"use strict";class s{constructor(){w(this,"startMarker",document.createTextNode(""));w(this,"endMarker",document.createTextNode(""))}static from(e,t){const o=new this;return e.before(o.startMarker),t.after(o.endMarker),o}before(...e){this.startMarker.before(...e)}prepend(...e){this.startMarker.after(...e)}append(...e){this.endMarker.before(...e)}after(...e){this.endMarker.after(...e)}remove(){const e=document.createRange();e.setStartBefore(this.startMarker),e.setEndAfter(this.endMarker),e.deleteContents()}replaceChildren(...e){const t=document.createRange();t.setStartAfter(this.startMarker),t.setEndBefore(this.endMarker),t.deleteContents(),this.startMarker.after(...e)}replaceWith(...e){this.endMarker.after(...e),this.remove()}get childNodes(){const e=[];for(let t=this.startMarker.nextSibling;t!=this.endMarker&&t;t=t.nextSibling)e.push(t);return e}get children(){return this.childNodes.filter(e=>e instanceof HTMLElement)}}var i=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",LiveFragment:s});const u=Symbol.for("bruh reactive");class J{constructor(e){w(this,ce,!0);l(this,v,void 0);l(this,S,new Set);y(this,v,e)}get value(){return a(this,v)}set value(e){if(e!==a(this,v)){y(this,v,e);for(const t of a(this,S))t()}}addReaction(e){return a(this,S).add(e),()=>a(this,S).delete(e)}}ce=u,v=new WeakMap,S=new WeakMap;const c=class{constructor(e,t){l(this,E);w(this,de,!0);l(this,p,void 0);l(this,M,new Set);l(this,A,void 0);l(this,m,0);l(this,j,new Set);if(!t){y(this,p,e);return}y(this,p,t()),y(this,A,t),y(this,m,Math.max(...e.map(o=>a(o,m)))+1),e.forEach(o=>a(o,j).add(this))}get value(){if(a(c,f).size){if(a(this,m)!==0)c.applyUpdates();else if(a(c,f).has(this))return a(c,f).get(this)}return a(this,p)}set value(e){a(this,m)===0&&(a(c,f).size||queueMicrotask(c.applyUpdates),a(c,f).set(this,e))}addReaction(e){return a(this,M).add(e),()=>a(this,M).delete(e)}static applyUpdates(){var e,t,o;if(!!a(c,f).size){for(const[d,h]of a(c,f).entries())P(e=d,E,q).call(e,h);a(c,f).clear();for(const d of a(c,N))if(d)for(const h of d)P(o=h,E,q).call(o,a(t=h,A).call(t));a(c,N).length=0;for(const d of a(c,T))d();a(c,T).length=0}}};let g=c;de=u,p=new WeakMap,M=new WeakMap,A=new WeakMap,m=new WeakMap,j=new WeakMap,f=new WeakMap,N=new WeakMap,T=new WeakMap,E=new WeakSet,q=function(e){if(e===a(this,p))return;y(this,p,e),a(c,T).push(...a(this,M));const t=a(c,N);for(const o of a(this,j)){const d=a(o,m);t[d]||(t[d]=new Set),t[d].add(o)}},l(g,f,new Map),l(g,N,[]),l(g,T,[]);const X=(r,e)=>new g(r,e),R=(r,e)=>{if(r==null?void 0:r[u])return e(r.value),r.addReaction(()=>e(r.value));e(r)};var H=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",isReactive:u,SimpleReactive:J,FunctionalReactive:g,r:X,reactiveDo:R});const I=r=>(r==null?void 0:r[u])||r instanceof Node||Array.isArray(r)||r==null||!(typeof r=="function"||typeof r=="object"),C=r=>r instanceof Node?r:document.createTextNode(r),k=(...r)=>r.flat(1/0).flatMap(e=>{if(!e[u])return[C(e)];if(Array.isArray(e.value)){const o=new s;return e.addReaction(()=>{o.replaceChildren(...k(...e.value))}),[o.startMarker,...k(...e.value),o.endMarker]}let t=C(e.value);return e.addReaction(()=>{const o=t;t=C(e.value),o.replaceWith(t)}),[t]}),B=(r,e)=>{for(const t in e)R(e[t],o=>{o!==void 0?r.style.setProperty(t,o):r.style.removeProperty(t)})},D=(r,e)=>{for(const t in e)R(e[t],o=>{r.classList.toggle(t,o)})},U=(r,e)=>{for(const t in e)R(e[t],o=>{o!==void 0?r.setAttribute(t,o):r.removeAttribute(t)})},$=r=>{if(!r[u])return document.createTextNode(r);const e=document.createTextNode(r.value);return r.addReaction(()=>{e.textContent=r.value}),e},W=r=>(...e)=>{var _;if(I(e[0])){const b=document.createElement(r);return b.append(...k(...e)),b}const[t,...o]=e,{namespace:d}=(_=t.bruh)!=null?_:{};delete t.bruh;const h=d?document.createElementNS(d,r):document.createElement(r);typeof t.style=="object"&&!t.style[u]&&(B(h,t.style),delete t.style),typeof t.class=="object"&&!t.style[u]&&(D(h,t.class),delete t.class);for(const b in t)b.startsWith("on")&&typeof t[b]=="function"&&(h.addEventListener(b.slice(2),t[b]),delete t[b]);return U(h,t),h.append(...k(...o)),h},G=(r,e,...t)=>{if(typeof r=="string"){const o=W(r);return e?o(e,...t):o(...t)}return r(O(z({},e),{children:t}))},K=({children:r})=>r,Y=()=>{const r={},e=document.getElementsByTagName("bruh-textnode");for(const t of e){const o=document.createTextNode(t.textContent),d=t.getAttribute("tag");d&&(r[d]=o),t.replaceWith(o)}return r};var Z=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",bruhChildrenToNodes:k,applyStyles:B,applyClasses:D,applyAttributes:U,t:$,e:W,h:G,JSXFragment:K,hydrateTextNodes:Y});const V=(r,...e)=>e.reduce((t,o)=>o(t),r),x=(r,e,t)=>r.dispatchEvent(new CustomEvent(e,z({bubbles:!0,cancelable:!0,composed:!0},t))),ee=(r,e)=>{const t=O(z({},r),{[Symbol.iterator]:()=>e[Symbol.iterator]()});return Object.defineProperty(t,Symbol.iterator,{enumerable:!1}),t},te=r=>new Proxy({},{get:(e,t)=>r(t)});var re=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",pipe:V,dispatch:x,createDestructable:ee,functionAsObject:te});n.dom=Z,n.liveFragment=i,n.reactive=H,n.util=re,Object.defineProperty(n,"__esModule",{value:!0}),n[Symbol.toStringTag]="Module"});
1
+ var Y=Object.defineProperty;var Z=(a,o,c)=>o in a?Y(a,o,{enumerable:!0,configurable:!0,writable:!0,value:c}):a[o]=c;var O=(a,o,c)=>(Z(a,typeof o!="symbol"?o+"":o,c),c),P=(a,o,c)=>{if(!o.has(a))throw TypeError("Cannot "+c)};var s=(a,o,c)=>(P(a,o,"read from private field"),c?c.call(a):o.get(a)),d=(a,o,c)=>{if(o.has(a))throw TypeError("Cannot add the same private member more than once");o instanceof WeakSet?o.add(a):o.set(a,c)},b=(a,o,c,p)=>(P(a,o,"write to private field"),p?p.call(a,c):o.set(a,c),c);var R=(a,o,c)=>(P(a,o,"access private method"),c);(function(a,o){typeof exports=="object"&&typeof module<"u"?o(exports):typeof define=="function"&&define.amd?define(["exports"],o):(a=typeof globalThis<"u"?globalThis:a||self,o(a.bruh={}))})(this,function(a){var H,v,g,K,y,S,j,h,E,l,N,T,M,z;"use strict";const o=Symbol.for("bruh reactive");class c{constructor(e){O(this,H,!0);d(this,v,void 0);d(this,g,new Set);b(this,v,e)}get value(){return s(this,v)}set value(e){if(e!==s(this,v)){b(this,v,e);for(const r of s(this,g))r()}}addReaction(e){return s(this,g).add(e),()=>s(this,g).delete(e)}}H=o,v=new WeakMap,g=new WeakMap;const u=class{constructor(e,r){d(this,M);O(this,K,!0);d(this,y,void 0);d(this,S,new Set);d(this,j,void 0);d(this,h,0);d(this,E,new Set);if(!r){b(this,y,e);return}b(this,y,r()),b(this,j,r),b(this,h,Math.max(...e.map(n=>s(n,h)))+1),e.forEach(n=>s(n,E).add(this))}get value(){if(s(u,l).size){if(s(this,h)!==0)u.applyUpdates();else if(s(u,l).has(this))return s(u,l).get(this)}return s(this,y)}set value(e){s(this,h)===0&&(s(u,l).size||queueMicrotask(u.applyUpdates),s(u,l).set(this,e))}addReaction(e){return s(this,S).add(e),()=>s(this,S).delete(e)}static applyUpdates(){var e,r,n;if(!!s(u,l).size){for(const[i,f]of s(u,l).entries())R(e=i,M,z).call(e,f);s(u,l).clear();for(const i of s(u,N))if(i)for(const f of i)R(n=f,M,z).call(n,s(r=f,j).call(r));s(u,N).length=0;for(const i of s(u,T))i();s(u,T).length=0}}};let p=u;K=o,y=new WeakMap,S=new WeakMap,j=new WeakMap,h=new WeakMap,E=new WeakMap,l=new WeakMap,N=new WeakMap,T=new WeakMap,M=new WeakSet,z=function(e){if(e===s(this,y))return;b(this,y,e),s(u,T).push(...s(this,S));const r=s(u,N);for(const n of s(this,E)){const i=s(n,h);r[i]||(r[i]=new Set),r[i].add(n)}},d(p,l,new Map),d(p,N,[]),d(p,T,[]);const J=(t,e)=>new p(t,e),w=(t,e)=>{if(t!=null&&t[o])return e(t.value),t.addReaction(()=>e(t.value));e(t)},L=Object.freeze(Object.defineProperty({__proto__:null,isReactive:o,SimpleReactive:c,FunctionalReactive:p,r:J,reactiveDo:w},Symbol.toStringTag,{value:"Module"})),X=t=>(t==null?void 0:t[o])||t instanceof Node||Array.isArray(t)||t==null||!(typeof t=="function"||typeof t=="object"),C=t=>t instanceof Node?t:typeof t=="boolean"||t===void 0||t===null?document.createComment(t):document.createTextNode(t),W=t=>{let e=C(t.value);const r=t.addReaction(()=>{if(!e.parentNode){r();return}if(Array.isArray(t.value))r(),e.replaceWith(...U(t));else{const n=e;e=C(t.value),n.replaceWith(e)}});return e},U=t=>{const e=document.createComment("["),r=document.createComment("]"),n=t.addReaction(()=>{if(!e.parentNode){n();return}const i=document.createRange();i.setStartAfter(e),Array.isArray(t.value)?(i.setEndBefore(r),i.deleteContents(),e.after(...A(t.value))):(n(),i.setEndAfter(r),i.deleteContents(),e.replaceWith(W(t)))});return[e,...A(t.value),r]},A=t=>t.flat(1/0).flatMap(e=>e!=null&&e[o]?Array.isArray(e.value)?U(e):[W(e)]:[C(e)]),B=(t,e)=>{for(const r in e)w(e[r],n=>{n!==void 0?t.style.setProperty(r,n):t.style.removeProperty(r)})},D=(t,e)=>{for(const r in e)w(e[r],n=>{t.classList.toggle(r,n)})},Q=(t,e)=>{for(const r in e)w(e[r],n=>{n!==void 0?t.setAttribute(r,n):t.removeAttribute(r)})},I=t=>{if(!t[o])return document.createTextNode(t);const e=document.createTextNode(t.value);return t.addReaction(()=>{e.textContent=t.value}),e},k=t=>(...e)=>{var q;if(e.length===0)return document.createElement(t);if(X(e[0])){const m=document.createElement(t);return m.append(...A(e)),m}const[r,...n]=e,{namespace:i}=(q=r.bruh)!=null?q:{};delete r.bruh;const f=i?document.createElementNS(i,t):document.createElement(t);typeof r.style=="object"&&!r.style[o]&&(B(f,r.style),delete r.style),typeof r.class=="object"&&!r.class[o]&&(D(f,r.class),delete r.class);for(const m in r)m.startsWith("on")&&typeof r[m]=="function"&&(f.addEventListener(m.slice(2),r[m]),delete r[m]);return Q(f,r),f.append(...A(n)),f},$=Object.freeze(Object.defineProperty({__proto__:null,bruhChildrenToNodes:A,applyStyles:B,applyClasses:D,applyAttributes:Q,t:I,e:k,h:(t,e,...r)=>{if(typeof t=="string"){const n=k(t);return e?n(e,...r):n(...r)}return t({...e,children:r})},JSXFragment:({children:t})=>t,hydrateTextNodes:()=>{const t={},e=document.getElementsByTagName("bruh-textnode");for(const r of e){const n=document.createTextNode(r.textContent),i=r.getAttribute("tag");i&&(t[i]=n),r.replaceWith(n)}return t}},Symbol.toStringTag,{value:"Module"})),G=Object.freeze(Object.defineProperty({__proto__:null,pipe:(t,...e)=>e.reduce((r,n)=>n(r),t),dispatch:(t,e,r)=>t.dispatchEvent(new CustomEvent(e,{bubbles:!0,cancelable:!0,composed:!0,...r})),createDestructable:(t,e)=>{const r={...t,[Symbol.iterator]:()=>e[Symbol.iterator]()};return Object.defineProperty(r,Symbol.iterator,{enumerable:!1}),r},functionAsObject:t=>new Proxy({},{get:(e,r)=>t(r)})},Symbol.toStringTag,{value:"Module"}));a.dom=$,a.reactive=L,a.util=G,Object.defineProperties(a,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
2
2
  //# sourceMappingURL=bruh.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bruh.umd.js","sources":["../src/dom/live-fragment.mjs","../src/reactive/index.mjs","../src/dom/index.browser.mjs","../src/util/index.mjs"],"sourcesContent":["// Lightweight and performant DOM fragment that keeps its place,\n// useful for grouping siblings without making a parent element.\n// Not a true analog of the DocumentFragment, because the implementation\n// would be infeasible with that scope, adding a performance penalty as well.\n// Works as long as the start & end placeholders are siblings in that order\n// and they do not overlap other LiveFragment's:\n// Works: (start A)(start B)(end B)(end A)\n// Fails: (start A)(start B)(end A)(end B)\n// Also, make sure not to call .normalize() on the parent element,\n// because that would ruin the placeholders.\nexport class LiveFragment {\n startMarker = document.createTextNode(\"\")\n endMarker = document.createTextNode(\"\")\n\n static from(firstNode, lastNode) {\n const liveFragment = new this()\n firstNode.before(liveFragment.startMarker)\n lastNode.after(liveFragment.endMarker)\n return liveFragment\n }\n\n before(...xs) {\n this.startMarker.before(...xs)\n }\n\n prepend(...xs) {\n this.startMarker.after(...xs)\n }\n\n append(...xs) {\n this.endMarker.before(...xs)\n }\n\n after(...xs) {\n this.endMarker.after(...xs)\n }\n\n remove() {\n const range = document.createRange()\n range.setStartBefore(this.startMarker)\n range.setEndAfter(this.endMarker)\n range.deleteContents()\n }\n\n replaceChildren(...xs) {\n const range = document.createRange()\n range.setStartAfter(this.startMarker)\n range.setEndBefore(this.endMarker)\n range.deleteContents()\n this.startMarker.after(...xs)\n }\n\n replaceWith(...xs) {\n this.endMarker.after(...xs)\n this.remove()\n }\n\n get childNodes() {\n const childNodes = []\n\n for (\n let currentNode = this.startMarker.nextSibling;\n currentNode != this.endMarker && currentNode;\n currentNode = currentNode.nextSibling\n )\n childNodes.push(currentNode)\n\n return childNodes\n }\n\n get children() {\n return this.childNodes\n .filter(node => node instanceof HTMLElement)\n }\n}\n","export const isReactive = Symbol.for(\"bruh reactive\")\n\n// A super simple and performant reactive value implementation\nexport class SimpleReactive {\n [isReactive] = true\n\n #value\n #reactions = new Set()\n\n constructor(value) {\n this.#value = value\n }\n\n get value() {\n return this.#value\n }\n\n set value(newValue) {\n if (newValue === this.#value)\n return\n\n this.#value = newValue\n for (const reaction of this.#reactions)\n reaction()\n }\n\n addReaction(reaction) {\n this.#reactions.add(reaction)\n\n return () =>\n this.#reactions.delete(reaction)\n }\n}\n\n// A reactive implementation for building functional reactive graphs\n// Ensures state consistency, minimal node updates, and transparent update batching\nexport class FunctionalReactive {\n [isReactive] = true\n\n #value\n #reactions = new Set()\n\n // For derived nodes, f is the derivation function\n #f\n // Source nodes are 0 deep in the derivation graph\n // This is for topological sort\n #depth = 0\n // All nodes have a set of derivatives that update when the node changes\n #derivatives = new Set()\n\n // Keep track of all the pending changes from the value setter\n static #settersQueue = new Map()\n // A queue of derivatives to potentially update, sorted into sets by depth\n // This starts with depth 1 and can potentially have holes\n static #derivativesQueue = []\n // A queue of reactions to run after the graph is fully updated\n static #reactionsQueue = []\n\n constructor(x, f) {\n if (!f) {\n this.#value = x\n return\n }\n\n this.#value = f()\n this.#f = f\n this.#depth = Math.max(...x.map(d => d.#depth)) + 1\n\n x.forEach(d => d.#derivatives.add(this))\n }\n\n get value() {\n // If there are any pending updates\n if (FunctionalReactive.#settersQueue.size) {\n // Heuristic quick invalidation for derived nodes\n // Apply updates now, it's ok that there's already a microtask queued for this\n if (this.#depth !== 0)\n FunctionalReactive.applyUpdates()\n // If this is a source node that was updated, just return that\n // new value without actually updating any derived nodes yet\n else if (FunctionalReactive.#settersQueue.has(this))\n return FunctionalReactive.#settersQueue.get(this)\n }\n\n return this.#value\n }\n\n set value(newValue) {\n // Only allow source nodes to be directly updated\n if (this.#depth !== 0)\n return\n\n // Unless asked for earlier, these updates are just queued up until the microtasks run\n if (!FunctionalReactive.#settersQueue.size)\n queueMicrotask(FunctionalReactive.applyUpdates)\n\n FunctionalReactive.#settersQueue.set(this, newValue)\n }\n\n addReaction(reaction) {\n this.#reactions.add(reaction)\n\n return () =>\n this.#reactions.delete(reaction)\n }\n\n // Apply an update for a node and queue its derivatives if it actually changed\n #applyUpdate(newValue) {\n if (newValue === this.#value)\n return\n\n this.#value = newValue\n FunctionalReactive.#reactionsQueue.push(...this.#reactions)\n\n const queue = FunctionalReactive.#derivativesQueue\n for (const derivative of this.#derivatives) {\n const depth = derivative.#depth\n if (!queue[depth])\n queue[depth] = new Set()\n\n queue[depth].add(derivative)\n }\n }\n\n // Apply pending updates from actually changed source nodes\n static applyUpdates() {\n if (!FunctionalReactive.#settersQueue.size)\n return\n\n // Bootstrap by applying the updates from the pending setters\n for (const [sourceNode, newValue] of FunctionalReactive.#settersQueue.entries())\n sourceNode.#applyUpdate(newValue)\n FunctionalReactive.#settersQueue.clear()\n\n // Iterate down the depths, ignoring holes\n // Note that both the queue (Array) and each depth Set iterators update as items are added\n for (const depthSet of FunctionalReactive.#derivativesQueue) if (depthSet)\n for (const derivative of depthSet)\n derivative.#applyUpdate(derivative.#f())\n FunctionalReactive.#derivativesQueue.length = 0\n\n // Call all reactions now that the graph has a fully consistent state\n for (const reaction of FunctionalReactive.#reactionsQueue)\n reaction()\n FunctionalReactive.#reactionsQueue.length = 0\n }\n}\n\n// A little convenience function\nexport const r = (x, f) => new FunctionalReactive(x, f)\n\n// Do something with a value, updating if it is reactive\nexport const reactiveDo = (x, f) => {\n if (x?.[isReactive]) {\n f(x.value)\n return x.addReaction(() => f(x.value))\n }\n\n f(x)\n}\n","import { LiveFragment } from \"./live-fragment.mjs\"\nimport { isReactive, reactiveDo } from \"../reactive/index.mjs\"\n\n//#region Bruh child functions e.g. bruhChildrenToNodes()\n\n// A basic check for if a value is allowed as a child in bruh\n// It's responsible for quickly checking the type, not deep validation\nconst isBruhChild = x =>\n // Reactives and DOM nodes\n x?.[isReactive] ||\n x instanceof Node ||\n // Any array, just assume it contains valid children\n Array.isArray(x) ||\n // Allow nullish\n x == null ||\n // Disallow functions and objects\n !(typeof x === \"function\" || typeof x === \"object\")\n // Everything else can be a child when stringified\n\n// Coerces input into a DOM node, if it isn't already one\nconst toNode = x =>\n x instanceof Node\n ? x\n : document.createTextNode(x)\n\n// Processes bruh children into an array of DOM nodes\n// Reactive values are automatically replaced, so the output must be placed into a parent node\n// before any top level (after flattening arrays) reactions run\nexport const bruhChildrenToNodes = (...children) =>\n children\n .flat(Infinity)\n .flatMap(child => {\n // Non-reactive values are untouched\n if (!child[isReactive])\n return [toNode(child)]\n\n // Reactive arrays become live fragments with auto-swapped children\n if (Array.isArray(child.value)) {\n const liveFragment = new LiveFragment()\n child.addReaction(() => {\n liveFragment.replaceChildren(...bruhChildrenToNodes(...child.value))\n })\n return [liveFragment.startMarker, ...bruhChildrenToNodes(...child.value), liveFragment.endMarker]\n }\n\n // Reactive values become auto-swapped DOM nodes\n let node = toNode(child.value)\n child.addReaction(() => {\n const oldNode = node\n node = toNode(child.value)\n oldNode.replaceWith(node)\n })\n return [node]\n })\n\n//#endregion\n\n//#region Reactive-aware element helper functions e.g. applyAttributes()\n\n// Style attribute rules from an object with\n// potentially reactive and/or undefined values\nexport const applyStyles = (element, styles) => {\n for (const property in styles)\n reactiveDo(styles[property], value => {\n if (value !== undefined)\n element.style.setProperty (property, value)\n else\n element.style.removeProperty(property)\n })\n}\n\n// Class list from an object mapping from\n// class names to potentially reactive booleans\nexport const applyClasses = (element, classes) => {\n for (const name in classes)\n reactiveDo(classes[name], value => {\n element.classList.toggle(name, value)\n })\n}\n\n// Attributes from an object with\n// potentially reactive and/or undefined values\nexport const applyAttributes = (element, attributes) => {\n for (const name in attributes)\n reactiveDo(attributes[name], value => {\n if (value !== undefined)\n element.setAttribute (name, value)\n else\n element.removeAttribute(name)\n })\n}\n\n//#endregion\n\n//#region t() for text nodes and e() for element nodes\n\n// Text nodes\nexport const t = textContent => {\n // Non-reactive values are just text nodes\n if (!textContent[isReactive])\n return document.createTextNode(textContent)\n\n // Reactive values auto-update the node's text content\n const node = document.createTextNode(textContent.value)\n textContent.addReaction(() => {\n node.textContent = textContent.value\n })\n return node\n}\n\n// Elements\nexport const e = name => (...variadic) => {\n // If there are no props\n if (isBruhChild(variadic[0])) {\n const element = document.createElement(name)\n element.append(...bruhChildrenToNodes(...variadic))\n return element\n }\n\n // If props exist as the first variadic argument\n const [props, ...children] = variadic\n\n // Extract explicit options from the bruh prop\n const { namespace } = props.bruh ?? {}\n delete props.bruh\n\n // Make an element with optional namespace\n const element =\n namespace\n ? document.createElementNS(namespace, name)\n : document.createElement ( name)\n\n // Apply overloaded props, if possible\n\n // Inline style object\n if (typeof props.style === \"object\" && !props.style[isReactive]) {\n applyStyles(element, props.style)\n delete props.style\n }\n // Classes object\n if (typeof props.class === \"object\" && !props.style[isReactive]) {\n applyClasses(element, props.class)\n delete props.class\n }\n for (const name in props) {\n // Event listener functions\n if (name.startsWith(\"on\") && typeof props[name] === \"function\") {\n element.addEventListener(name.slice(2), props[name])\n delete props[name]\n }\n }\n\n // The rest of the props are attributes\n applyAttributes(element, props)\n\n // Add the children to the element\n element.append(...bruhChildrenToNodes(...children))\n return element\n}\n\n//#endregion\n\n//#region JSX integration\n\n// The function that jsx tags (except fragments) compile to\nexport const h = (nameOrComponent, props, ...children) => {\n // If we are making an element, this is just a wrapper of e()\n // This is likely when the JSX tag name begins with a lowercase character\n if (typeof nameOrComponent === \"string\") {\n const makeElement = e(nameOrComponent)\n return props\n ? makeElement(props, ...children)\n : makeElement(...children)\n }\n\n // It must be a component, then, as bruh components are just functions\n // Due to JSX, this would mean a function with only one parameter - props\n // This object includes the all of the normal props and a \"children\" key\n return nameOrComponent({ ...props, children })\n}\n\n// The JSX fragment is made into a bruh fragment (just an array)\nexport const JSXFragment = ({ children }) => children\n\n//#endregion\n\n\n\n// Hydration of all bruh-textnode's from prerendered html\nexport const hydrateTextNodes = () => {\n const tagged = {}\n const bruhTextNodes = document.getElementsByTagName(\"bruh-textnode\")\n\n for (const bruhTextNode of bruhTextNodes) {\n const textNode = document.createTextNode(bruhTextNode.textContent)\n\n const tag = bruhTextNode.getAttribute(\"tag\")\n if (tag)\n tagged[tag] = textNode\n\n bruhTextNode.replaceWith(textNode)\n }\n\n return tagged\n}\n","// Create a pipeline with an initial value and a series of functions\nexport const pipe = (x, ...fs) =>\n fs.reduce((y, f) => f(y), x)\n\n// Dispatch a custom event to (capturing) and from (bubbling) a target (usually a DOM node)\n// Returns false if the event was cancelled (preventDefault()) and true otherwise\nexport const dispatch = (target, type, options) =>\n target.dispatchEvent(\n // Default to behave like most DOM events\n new CustomEvent(type, {\n bubbles: true,\n cancelable: true,\n composed: true,\n ...options\n })\n )\n\n// Inspired by https://antfu.me/posts/destructuring-with-object-or-array#take-away\n// Creates an object that is both destructable with {...} and [...]\n// Useful for writing library functions à la react-use & vueuse\nexport const createDestructable = (object, iterable) => {\n const destructable = {\n ...object,\n [Symbol.iterator]: () => iterable[Symbol.iterator]()\n }\n\n Object.defineProperty(destructable, Symbol.iterator, {\n enumerable: false\n })\n\n return destructable\n}\n\n// Creates an object (as a Proxy) that acts as a function\n// So functionAsObject(f).property is equivalent to f(\"property\")\n// This is can be useful when combined with destructuring syntax, e.g.:\n// const { html, head, title, body, main, h1, p } = functionAsObject(e)\nexport const functionAsObject = f =>\n new Proxy({}, {\n get: (_, property) => f(property)\n })\n"],"names":[],"mappings":"4nCAUO,OAAmB,CAAnB,cACL,qBAAc,SAAS,eAAe,KACtC,mBAAc,SAAS,eAAe,WAE/B,MAAK,EAAW,EAAU,CAC/B,KAAM,GAAe,GAAI,MACzB,SAAU,OAAO,EAAa,aAC9B,EAAS,MAAM,EAAa,WACrB,EAGT,UAAU,EAAI,CACZ,KAAK,YAAY,OAAO,GAAG,GAG7B,WAAW,EAAI,CACb,KAAK,YAAY,MAAM,GAAG,GAG5B,UAAU,EAAI,CACZ,KAAK,UAAU,OAAO,GAAG,GAG3B,SAAS,EAAI,CACX,KAAK,UAAU,MAAM,GAAG,GAG1B,QAAS,CACP,KAAM,GAAQ,SAAS,cACvB,EAAM,eAAe,KAAK,aAC1B,EAAM,YAAY,KAAK,WACvB,EAAM,iBAGR,mBAAmB,EAAI,CACrB,KAAM,GAAQ,SAAS,cACvB,EAAM,cAAc,KAAK,aACzB,EAAM,aAAa,KAAK,WACxB,EAAM,iBACN,KAAK,YAAY,MAAM,GAAG,GAG5B,eAAe,EAAI,CACjB,KAAK,UAAU,MAAM,GAAG,GACxB,KAAK,YAGH,aAAa,CACf,KAAM,GAAa,GAEnB,OACM,GAAc,KAAK,YAAY,YACnC,GAAe,KAAK,WAAa,EACjC,EAAc,EAAY,YAE1B,EAAW,KAAK,GAElB,MAAO,MAGL,WAAW,CACb,MAAO,MAAK,WACT,OAAO,GAAQ,YAAgB,kGCxE/B,KAAM,GAAa,OAAO,IAAI,iBAG9B,OAAqB,CAM1B,YAAY,EAAO,CALlB,UAAc,IAEf,iBACA,SAAa,GAAI,MAGf,OAAK,EAAS,MAGZ,QAAQ,CACV,MAAO,QAAK,MAGV,OAAM,EAAU,CAClB,GAAI,IAAa,OAAK,GAGtB,QAAK,EAAS,GACd,SAAW,KAAY,QAAK,GAC1B,KAGJ,YAAY,EAAU,CACpB,cAAK,GAAW,IAAI,GAEb,IACL,OAAK,GAAW,OAAO,IA1B1B,KAED,cACA,cA6BK,aAAyB,CAsB9B,YAAY,EAAG,EAAG,CAiDlB,UAtEC,UAAc,IAEf,iBACA,SAAa,GAAI,MAGjB,iBAGA,SAAS,GAET,SAAe,GAAI,MAWjB,GAAI,CAAC,EAAG,CACN,OAAK,EAAS,GACd,OAGF,OAAK,EAAS,KACd,OAAK,EAAK,GACV,OAAK,EAAS,KAAK,IAAI,GAAG,EAAE,IAAI,GAAK,IAAE,KAAW,GAElD,EAAE,QAAQ,GAAK,IAAE,GAAa,IAAI,UAGhC,QAAQ,CAEV,GAAI,IAAmB,GAAc,MAGnC,GAAI,OAAK,KAAW,EAClB,EAAmB,uBAGZ,IAAmB,GAAc,IAAI,MAC5C,MAAO,KAAmB,GAAc,IAAI,MAGhD,MAAO,QAAK,MAGV,OAAM,EAAU,CAElB,AAAI,OAAK,KAAW,GAIf,KAAmB,GAAc,MACpC,eAAe,EAAmB,cAEpC,IAAmB,GAAc,IAAI,KAAM,IAG7C,YAAY,EAAU,CACpB,cAAK,GAAW,IAAI,GAEb,IACL,OAAK,GAAW,OAAO,SAsBpB,eAAe,WACpB,GAAI,EAAC,IAAmB,GAAc,KAItC,UAAW,CAAC,EAAY,IAAa,KAAmB,GAAc,UACpE,MAAW,KAAX,OAAwB,GAC1B,IAAmB,GAAc,QAIjC,SAAW,KAAY,KAAmB,GAAmB,GAAI,EAC/D,SAAW,KAAc,GACvB,MAAW,KAAX,OAAwB,MAAW,GAAX,SAC5B,IAAmB,GAAkB,OAAS,EAG9C,SAAW,KAAY,KAAmB,GACxC,IACF,IAAmB,GAAgB,OAAS,KA5GzC,QACJ,KAED,cACA,cAGA,cAGA,cAEA,cAGO,cAGA,cAEA,cAmDP,gBAAY,SAAC,EAAU,CACrB,GAAI,IAAa,OAAK,GACpB,OAEF,OAAK,EAAS,GACd,IAAmB,GAAgB,KAAK,GAAG,OAAK,IAEhD,KAAM,GAAQ,IAAmB,GACjC,SAAW,KAAc,QAAK,GAAc,CAC1C,KAAM,GAAQ,IAAW,GACzB,AAAK,EAAM,IACT,GAAM,GAAS,GAAI,MAErB,EAAM,GAAO,IAAI,KArEd,EAfF,EAeE,EAAgB,GAAI,MAGpB,EAlBF,EAkBE,EAAoB,IAEpB,EApBF,EAoBE,EAAkB,IA6FpB,KAAM,GAAI,CAAC,EAAG,IAAM,GAAI,GAAmB,EAAG,GAGxC,EAAa,CAAC,EAAG,IAAM,CAClC,GAAI,iBAAI,GACN,SAAE,EAAE,OACG,EAAE,YAAY,IAAM,EAAE,EAAE,QAGjC,EAAE,4ICvJJ,KAAM,GAAc,GAElB,kBAAI,KACJ,YAAa,OAEb,MAAM,QAAQ,IAEd,GAAK,MAEL,CAAE,OAAO,IAAM,YAAc,MAAO,IAAM,UAItC,EAAS,GACb,YAAa,MACT,EACA,SAAS,eAAe,GAKjB,EAAsB,IAAI,IACrC,EACG,KAAK,KACL,QAAQ,GAAS,CAEhB,GAAI,CAAC,EAAM,GACT,MAAO,CAAC,EAAO,IAGjB,GAAI,MAAM,QAAQ,EAAM,OAAQ,CAC9B,KAAM,GAAe,GAAI,GACzB,SAAM,YAAY,IAAM,CACtB,EAAa,gBAAgB,GAAG,EAAoB,GAAG,EAAM,UAExD,CAAC,EAAa,YAAa,GAAG,EAAoB,GAAG,EAAM,OAAQ,EAAa,WAIzF,GAAI,GAAO,EAAO,EAAM,OACxB,SAAM,YAAY,IAAM,CACtB,KAAM,GAAU,EAChB,EAAO,EAAO,EAAM,OACpB,EAAQ,YAAY,KAEf,CAAC,KASD,EAAc,CAAC,EAAS,IAAW,CAC9C,SAAW,KAAY,GACrB,EAAW,EAAO,GAAW,GAAS,CACpC,AAAI,IAAU,OACZ,EAAQ,MAAM,YAAe,EAAU,GAEvC,EAAQ,MAAM,eAAe,MAMxB,EAAe,CAAC,EAAS,IAAY,CAChD,SAAW,KAAQ,GACjB,EAAW,EAAQ,GAAO,GAAS,CACjC,EAAQ,UAAU,OAAO,EAAM,MAMxB,EAAkB,CAAC,EAAS,IAAe,CACtD,SAAW,KAAQ,GACjB,EAAW,EAAW,GAAO,GAAS,CACpC,AAAI,IAAU,OACZ,EAAQ,aAAgB,EAAM,GAE9B,EAAQ,gBAAgB,MASnB,EAAI,GAAe,CAE9B,GAAI,CAAC,EAAY,GACf,MAAO,UAAS,eAAe,GAGjC,KAAM,GAAO,SAAS,eAAe,EAAY,OACjD,SAAY,YAAY,IAAM,CAC5B,EAAK,YAAc,EAAY,QAE1B,GAII,EAAI,GAAQ,IAAI,IAAa,OAExC,GAAI,EAAY,EAAS,IAAK,CAC5B,KAAM,GAAU,SAAS,cAAc,GACvC,SAAQ,OAAO,GAAG,EAAoB,GAAG,IAClC,EAIT,KAAM,CAAC,KAAU,GAAY,EAGvB,CAAE,aAAc,KAAM,OAAN,OAAc,GACpC,MAAO,GAAM,KAGb,KAAM,GACJ,EACI,SAAS,gBAAgB,EAAW,GACpC,SAAS,cAA2B,GAK1C,AAAI,MAAO,GAAM,OAAU,UAAY,CAAC,EAAM,MAAM,IAClD,GAAY,EAAS,EAAM,OAC3B,MAAO,GAAM,OAGX,MAAO,GAAM,OAAU,UAAY,CAAC,EAAM,MAAM,IAClD,GAAa,EAAS,EAAM,OAC5B,MAAO,GAAM,OAEf,SAAW,KAAQ,GAEjB,AAAI,EAAK,WAAW,OAAS,MAAO,GAAM,IAAU,YAClD,GAAQ,iBAAiB,EAAK,MAAM,GAAI,EAAM,IAC9C,MAAO,GAAM,IAKjB,SAAgB,EAAS,GAGzB,EAAQ,OAAO,GAAG,EAAoB,GAAG,IAClC,GAQI,EAAI,CAAC,EAAiB,KAAU,IAAa,CAGxD,GAAI,MAAO,IAAoB,SAAU,CACvC,KAAM,GAAc,EAAE,GACtB,MAAO,GACH,EAAY,EAAO,GAAG,GACtB,EAAY,GAAG,GAMrB,MAAO,GAAgB,OAAK,GAAL,CAAY,eAIxB,EAAc,CAAC,CAAE,cAAe,EAOhC,EAAmB,IAAM,CACpC,KAAM,GAAS,GACT,EAAgB,SAAS,qBAAqB,iBAEpD,SAAW,KAAgB,GAAe,CACxC,KAAM,GAAW,SAAS,eAAe,EAAa,aAEhD,EAAM,EAAa,aAAa,OACtC,AAAI,GACF,GAAO,GAAO,GAEhB,EAAa,YAAY,GAG3B,MAAO,0LC1MF,KAAM,GAAO,CAAC,KAAM,IACzB,EAAG,OAAO,CAAC,EAAG,IAAM,EAAE,GAAI,GAIf,EAAW,CAAC,EAAQ,EAAM,IACrC,EAAO,cAEL,GAAI,aAAY,EAAM,GACpB,QAAS,GACT,WAAY,GACZ,SAAU,IACP,KAOI,GAAqB,CAAC,EAAQ,IAAa,CACtD,KAAM,GAAe,OAChB,GADgB,EAElB,OAAO,UAAW,IAAM,EAAS,OAAO,cAG3C,cAAO,eAAe,EAAc,OAAO,SAAU,CACnD,WAAY,KAGP,GAOI,GAAmB,GAC9B,GAAI,OAAM,GAAI,CACZ,IAAK,CAAC,EAAG,IAAa,EAAE"}
1
+ {"version":3,"file":"bruh.umd.js","sources":["../src/reactive/index.mjs","../src/dom/index.browser.mjs","../src/util/index.mjs"],"sourcesContent":["export const isReactive = Symbol.for(\"bruh reactive\")\n\n// A super simple and performant reactive value implementation\nexport class SimpleReactive {\n [isReactive] = true\n\n #value\n #reactions = new Set()\n\n constructor(value) {\n this.#value = value\n }\n\n get value() {\n return this.#value\n }\n\n set value(newValue) {\n if (newValue === this.#value)\n return\n\n this.#value = newValue\n for (const reaction of this.#reactions)\n reaction()\n }\n\n addReaction(reaction) {\n this.#reactions.add(reaction)\n\n return () =>\n this.#reactions.delete(reaction)\n }\n}\n\n// A reactive implementation for building functional reactive graphs\n// Ensures state consistency, minimal node updates, and transparent update batching\nexport class FunctionalReactive {\n [isReactive] = true\n\n #value\n #reactions = new Set()\n\n // For derived nodes, f is the derivation function\n #f\n // Source nodes are 0 deep in the derivation graph\n // This is for topological sort\n #depth = 0\n // All nodes have a set of derivatives that update when the node changes\n #derivatives = new Set()\n\n // Keep track of all the pending changes from the value setter\n static #settersQueue = new Map()\n // A queue of derivatives to potentially update, sorted into sets by depth\n // This starts with depth 1 and can potentially have holes\n static #derivativesQueue = []\n // A queue of reactions to run after the graph is fully updated\n static #reactionsQueue = []\n\n constructor(x, f) {\n if (!f) {\n this.#value = x\n return\n }\n\n this.#value = f()\n this.#f = f\n this.#depth = Math.max(...x.map(d => d.#depth)) + 1\n\n x.forEach(d => d.#derivatives.add(this))\n }\n\n get value() {\n // If there are any pending updates\n if (FunctionalReactive.#settersQueue.size) {\n // Heuristic quick invalidation for derived nodes\n // Apply updates now, it's ok that there's already a microtask queued for this\n if (this.#depth !== 0)\n FunctionalReactive.applyUpdates()\n // If this is a source node that was updated, just return that\n // new value without actually updating any derived nodes yet\n else if (FunctionalReactive.#settersQueue.has(this))\n return FunctionalReactive.#settersQueue.get(this)\n }\n\n return this.#value\n }\n\n set value(newValue) {\n // Only allow source nodes to be directly updated\n if (this.#depth !== 0)\n return\n\n // Unless asked for earlier, these updates are just queued up until the microtasks run\n if (!FunctionalReactive.#settersQueue.size)\n queueMicrotask(FunctionalReactive.applyUpdates)\n\n FunctionalReactive.#settersQueue.set(this, newValue)\n }\n\n addReaction(reaction) {\n this.#reactions.add(reaction)\n\n return () =>\n this.#reactions.delete(reaction)\n }\n\n // Apply an update for a node and queue its derivatives if it actually changed\n #applyUpdate(newValue) {\n if (newValue === this.#value)\n return\n\n this.#value = newValue\n FunctionalReactive.#reactionsQueue.push(...this.#reactions)\n\n const queue = FunctionalReactive.#derivativesQueue\n for (const derivative of this.#derivatives) {\n const depth = derivative.#depth\n if (!queue[depth])\n queue[depth] = new Set()\n\n queue[depth].add(derivative)\n }\n }\n\n // Apply pending updates from actually changed source nodes\n static applyUpdates() {\n if (!FunctionalReactive.#settersQueue.size)\n return\n\n // Bootstrap by applying the updates from the pending setters\n for (const [sourceNode, newValue] of FunctionalReactive.#settersQueue.entries())\n sourceNode.#applyUpdate(newValue)\n FunctionalReactive.#settersQueue.clear()\n\n // Iterate down the depths, ignoring holes\n // Note that both the queue (Array) and each depth Set iterators update as items are added\n for (const depthSet of FunctionalReactive.#derivativesQueue) if (depthSet)\n for (const derivative of depthSet)\n derivative.#applyUpdate(derivative.#f())\n FunctionalReactive.#derivativesQueue.length = 0\n\n // Call all reactions now that the graph has a fully consistent state\n for (const reaction of FunctionalReactive.#reactionsQueue)\n reaction()\n FunctionalReactive.#reactionsQueue.length = 0\n }\n}\n\n// A little convenience function\nexport const r = (x, f) => new FunctionalReactive(x, f)\n\n// Do something with a value, updating if it is reactive\nexport const reactiveDo = (x, f) => {\n if (x?.[isReactive]) {\n f(x.value)\n return x.addReaction(() => f(x.value))\n }\n\n f(x)\n}\n","import { isReactive, reactiveDo } from \"../reactive/index.mjs\"\n\n//#region Bruh child functions e.g. bruhChildrenToNodes()\n\n// A basic check for if a value is allowed as a child in bruh\n// It's responsible for quickly checking the type, not deep validation\nconst isBruhChild = x =>\n // Reactives and DOM nodes\n x?.[isReactive] ||\n x instanceof Node ||\n // Any array, just assume it contains valid children\n Array.isArray(x) ||\n // Allow nullish\n x == null ||\n // Disallow functions and objects\n !(typeof x === \"function\" || typeof x === \"object\")\n // Everything else can be a child when stringified\n\n// Coerces input into a DOM node, if it isn't already one\nconst unreactiveChildToNode = x => {\n // Existing DOM nodes are untouched\n if (x instanceof Node)\n return x\n // booleans and nullish are ignored\n else if (typeof x === \"boolean\" || x === undefined || x === null)\n return document.createComment(x)\n // Anything else is treated as text\n else\n return document.createTextNode(x)\n}\n\n// Auto-swapping single reactive node\nconst reactiveChildToNode = child => {\n let node = unreactiveChildToNode(child.value)\n\n const stopReacting = child.addReaction(() => {\n // Stop swapping if no longer possible\n if (!node.parentNode) {\n stopReacting()\n return\n }\n\n // Normal swap\n if (!Array.isArray(child.value)) {\n const oldNode = node\n node = unreactiveChildToNode(child.value)\n oldNode.replaceWith(node)\n }\n // If an array now, stop swapping, then switch to reactive array swapping\n else {\n stopReacting()\n node.replaceWith(...reactiveArrayChildToNodes(child))\n }\n })\n\n return node\n}\n\n// Auto-swapping reactive array of nodes\nconst reactiveArrayChildToNodes = child => {\n // Markers owned by the swapper here itself, so that\n // the values in the array can be swapped separately\n const first = document.createComment(\"[\")\n const last = document.createComment(\"]\")\n\n const stopReacting = child.addReaction(() => {\n // Stop swapping if there is no parent to swap within\n if (!first.parentNode) {\n stopReacting()\n return\n }\n\n // Make a range starting after the first marker\n const range = document.createRange()\n range.setStartAfter(first)\n\n // Normal swap, replacing content between the first and last markers\n if (Array.isArray(child.value)) {\n range.setEndBefore(last)\n range.deleteContents()\n first.after(...bruhChildrenToNodes(child.value))\n }\n // Switch to single swapping node by replacing everything\n else {\n stopReacting()\n range.setEndAfter(last)\n range.deleteContents()\n first.replaceWith(reactiveChildToNode(child))\n }\n })\n\n return [\n first,\n ...bruhChildrenToNodes(child.value),\n last\n ]\n}\n\n// Processes bruh children into an array of DOM nodes\n// Reactive values are automatically replaced, so the output must be placed into a parent node\n// before any top level (after flattening arrays) reactions run\nexport const bruhChildrenToNodes = children =>\n children\n .flat(Infinity)\n .flatMap(child => {\n // Non-reactive child\n if (!child?.[isReactive])\n return [unreactiveChildToNode(child)]\n\n // Single reactive value\n if (!Array.isArray(child.value))\n return [reactiveChildToNode(child)]\n\n // Reactive array\n return reactiveArrayChildToNodes(child)\n })\n\n//#endregion\n\n//#region Reactive-aware element helper functions e.g. applyAttributes()\n\n// Style attribute rules from an object with\n// potentially reactive and/or undefined values\nexport const applyStyles = (element, styles) => {\n for (const property in styles)\n reactiveDo(styles[property], value => {\n if (value !== undefined)\n element.style.setProperty (property, value)\n else\n element.style.removeProperty(property)\n })\n}\n\n// Class list from an object mapping from\n// class names to potentially reactive booleans\nexport const applyClasses = (element, classes) => {\n for (const name in classes)\n reactiveDo(classes[name], value => {\n element.classList.toggle(name, value)\n })\n}\n\n// Attributes from an object with\n// potentially reactive and/or undefined values\nexport const applyAttributes = (element, attributes) => {\n for (const name in attributes)\n reactiveDo(attributes[name], value => {\n if (value !== undefined)\n element.setAttribute (name, value)\n else\n element.removeAttribute(name)\n })\n}\n\n//#endregion\n\n//#region t() for text nodes and e() for element nodes\n\n// Text nodes\nexport const t = textContent => {\n // Non-reactive values are just text nodes\n if (!textContent[isReactive])\n return document.createTextNode(textContent)\n\n // Reactive values auto-update the node's text content\n const node = document.createTextNode(textContent.value)\n textContent.addReaction(() => {\n node.textContent = textContent.value\n })\n return node\n}\n\n// Elements\nexport const e = name => (...variadic) => {\n if (variadic.length === 0)\n return document.createElement(name)\n\n // If there are no props\n if (isBruhChild(variadic[0])) {\n const element = document.createElement(name)\n element.append(...bruhChildrenToNodes(variadic))\n return element\n }\n\n // If props exist as the first variadic argument\n const [props, ...children] = variadic\n\n // Extract explicit options from the bruh prop\n const { namespace } = props.bruh ?? {}\n delete props.bruh\n\n // Make an element with optional namespace\n const element =\n namespace\n ? document.createElementNS(namespace, name)\n : document.createElement ( name)\n\n // Apply overloaded props, if possible\n\n // Inline style object\n if (typeof props.style === \"object\" && !props.style[isReactive]) {\n applyStyles(element, props.style)\n delete props.style\n }\n // Classes object\n if (typeof props.class === \"object\" && !props.class[isReactive]) {\n applyClasses(element, props.class)\n delete props.class\n }\n for (const name in props) {\n // Event listener functions\n if (name.startsWith(\"on\") && typeof props[name] === \"function\") {\n element.addEventListener(name.slice(2), props[name])\n delete props[name]\n }\n }\n\n // The rest of the props are attributes\n applyAttributes(element, props)\n\n // Add the children to the element\n element.append(...bruhChildrenToNodes(children))\n return element\n}\n\n//#endregion\n\n//#region JSX integration\n\n// The function that jsx tags (except fragments) compile to\nexport const h = (nameOrComponent, props, ...children) => {\n // If we are making an element, this is just a wrapper of e()\n // This is likely when the JSX tag name begins with a lowercase character\n if (typeof nameOrComponent === \"string\") {\n const makeElement = e(nameOrComponent)\n return props\n ? makeElement(props, ...children)\n : makeElement(...children)\n }\n\n // It must be a component, then, as bruh components are just functions\n // Due to JSX, this would mean a function with only one parameter - props\n // This object includes the all of the normal props and a \"children\" key\n return nameOrComponent({ ...props, children })\n}\n\n// The JSX fragment is made into a bruh fragment (just an array)\nexport const JSXFragment = ({ children }) => children\n\n//#endregion\n\n\n\n// Hydration of all bruh-textnode's from prerendered html\nexport const hydrateTextNodes = () => {\n const tagged = {}\n const bruhTextNodes = document.getElementsByTagName(\"bruh-textnode\")\n\n for (const bruhTextNode of bruhTextNodes) {\n const textNode = document.createTextNode(bruhTextNode.textContent)\n\n const tag = bruhTextNode.getAttribute(\"tag\")\n if (tag)\n tagged[tag] = textNode\n\n bruhTextNode.replaceWith(textNode)\n }\n\n return tagged\n}\n","// Create a pipeline with an initial value and a series of functions\nexport const pipe = (x, ...fs) =>\n fs.reduce((y, f) => f(y), x)\n\n// Dispatch a custom event to (capturing) and from (bubbling) a target (usually a DOM node)\n// Returns false if the event was cancelled (preventDefault()) and true otherwise\n// Note that this is synchronous\nexport const dispatch = (target, type, options) =>\n target.dispatchEvent(\n // Default to behave like most DOM events\n new CustomEvent(type, {\n bubbles: true,\n cancelable: true,\n composed: true,\n ...options\n })\n )\n\n// Inspired by https://antfu.me/posts/destructuring-with-object-or-array#take-away\n// Creates an object that is both destructable with {...} and [...]\n// Useful for writing library functions à la react-use & vueuse\nexport const createDestructable = (object, iterable) => {\n const destructable = {\n ...object,\n [Symbol.iterator]: () => iterable[Symbol.iterator]()\n }\n\n Object.defineProperty(destructable, Symbol.iterator, {\n enumerable: false\n })\n\n return destructable\n}\n\n// Creates an object (as a Proxy) that acts as a function\n// So functionAsObject(f).property is equivalent to f(\"property\")\n// This is can be useful when combined with destructuring syntax, e.g.:\n// const { html, head, title, body, main, h1, p } = functionAsObject(e)\nexport const functionAsObject = f =>\n new Proxy({}, {\n get: (_, property) => f(property)\n })\n"],"names":["isReactive","SimpleReactive","value","__publicField","_a","__privateAdd","_value","_reactions","__privateSet","__privateGet","newValue","reaction","_FunctionalReactive","x","f","_applyUpdate","_b","_f","_depth","_derivatives","d","_settersQueue","sourceNode","__privateMethod","applyUpdate_fn","depthSet","_derivativesQueue","derivative","_c","_reactionsQueue","FunctionalReactive","queue","depth","r","reactiveDo","isBruhChild","unreactiveChildToNode","reactiveChildToNode","child","node","stopReacting","reactiveArrayChildToNodes","oldNode","first","last","range","bruhChildrenToNodes","children","applyStyles","element","styles","property","applyClasses","classes","name","applyAttributes","attributes","t","textContent","e","variadic","props","namespace","nameOrComponent","makeElement","tagged","bruhTextNodes","bruhTextNode","textNode","tag","fs","y","target","type","options","object","iterable","destructable","_"],"mappings":"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"}
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "library",
11
11
  "modern"
12
12
  ],
13
- "version": "1.11.0",
13
+ "version": "1.13.1",
14
14
  "license": "MIT",
15
15
  "author": {
16
16
  "name": "Daniel Ethridge",
@@ -25,37 +25,39 @@
25
25
  },
26
26
  "type": "module",
27
27
  "main": "./dist/bruh.umd.js",
28
+ "sideEffects": false,
28
29
  "exports": {
29
- "./": {
30
+ ".": {
30
31
  "browser": "./dist/bruh.es.js",
31
32
  "default": "./dist/bruh.umd.js"
32
33
  },
33
34
  "./dom": {
34
- "node": "./src/dom/index.node.mjs",
35
+ "node": "./src/dom/index.server.mjs",
35
36
  "browser": "./src/dom/index.browser.mjs"
36
37
  },
37
- "./dom/live-fragment": {
38
- "browser": "./src/dom/live-fragment.mjs"
39
- },
40
38
  "./reactive": "./src/reactive/index.mjs",
41
39
  "./util": "./src/util/index.mjs",
42
40
  "./components/*": "./src/components/*.mjs",
43
41
  "./media/images": {
44
- "node": "./src/media/images.mjs"
42
+ "node": "./src/media/images.node.mjs"
45
43
  }
46
44
  },
47
45
  "bin": {
48
46
  "bruh": "./src/cli/index.mjs"
49
47
  },
48
+ "files": [
49
+ "./src/",
50
+ "./dist/"
51
+ ],
50
52
  "scripts": {
51
53
  "build": "vite build",
52
54
  "prepare": "npm run build"
53
55
  },
54
56
  "optionalDependencies": {
55
- "cac": "^6.7.11",
56
- "sharp": "^0.29.2"
57
+ "cac": "^6.7.14",
58
+ "sharp": "^0.31.0"
57
59
  },
58
60
  "devDependencies": {
59
- "vite": "^2.6.10"
61
+ "vite": "^3.1.0"
60
62
  }
61
63
  }
@@ -1,4 +1,3 @@
1
- import { LiveFragment } from "./live-fragment.mjs"
2
1
  import { isReactive, reactiveDo } from "../reactive/index.mjs"
3
2
 
4
3
  //#region Bruh child functions e.g. bruhChildrenToNodes()
@@ -18,39 +17,102 @@ const isBruhChild = x =>
18
17
  // Everything else can be a child when stringified
19
18
 
20
19
  // Coerces input into a DOM node, if it isn't already one
21
- const toNode = x =>
22
- x instanceof Node
23
- ? x
24
- : document.createTextNode(x)
20
+ const unreactiveChildToNode = x => {
21
+ // Existing DOM nodes are untouched
22
+ if (x instanceof Node)
23
+ return x
24
+ // booleans and nullish are ignored
25
+ else if (typeof x === "boolean" || x === undefined || x === null)
26
+ return document.createComment(x)
27
+ // Anything else is treated as text
28
+ else
29
+ return document.createTextNode(x)
30
+ }
31
+
32
+ // Auto-swapping single reactive node
33
+ const reactiveChildToNode = child => {
34
+ let node = unreactiveChildToNode(child.value)
35
+
36
+ const stopReacting = child.addReaction(() => {
37
+ // Stop swapping if no longer possible
38
+ if (!node.parentNode) {
39
+ stopReacting()
40
+ return
41
+ }
42
+
43
+ // Normal swap
44
+ if (!Array.isArray(child.value)) {
45
+ const oldNode = node
46
+ node = unreactiveChildToNode(child.value)
47
+ oldNode.replaceWith(node)
48
+ }
49
+ // If an array now, stop swapping, then switch to reactive array swapping
50
+ else {
51
+ stopReacting()
52
+ node.replaceWith(...reactiveArrayChildToNodes(child))
53
+ }
54
+ })
55
+
56
+ return node
57
+ }
58
+
59
+ // Auto-swapping reactive array of nodes
60
+ const reactiveArrayChildToNodes = child => {
61
+ // Markers owned by the swapper here itself, so that
62
+ // the values in the array can be swapped separately
63
+ const first = document.createComment("[")
64
+ const last = document.createComment("]")
65
+
66
+ const stopReacting = child.addReaction(() => {
67
+ // Stop swapping if there is no parent to swap within
68
+ if (!first.parentNode) {
69
+ stopReacting()
70
+ return
71
+ }
72
+
73
+ // Make a range starting after the first marker
74
+ const range = document.createRange()
75
+ range.setStartAfter(first)
76
+
77
+ // Normal swap, replacing content between the first and last markers
78
+ if (Array.isArray(child.value)) {
79
+ range.setEndBefore(last)
80
+ range.deleteContents()
81
+ first.after(...bruhChildrenToNodes(child.value))
82
+ }
83
+ // Switch to single swapping node by replacing everything
84
+ else {
85
+ stopReacting()
86
+ range.setEndAfter(last)
87
+ range.deleteContents()
88
+ first.replaceWith(reactiveChildToNode(child))
89
+ }
90
+ })
91
+
92
+ return [
93
+ first,
94
+ ...bruhChildrenToNodes(child.value),
95
+ last
96
+ ]
97
+ }
25
98
 
26
99
  // Processes bruh children into an array of DOM nodes
27
100
  // Reactive values are automatically replaced, so the output must be placed into a parent node
28
101
  // before any top level (after flattening arrays) reactions run
29
- export const bruhChildrenToNodes = (...children) =>
102
+ export const bruhChildrenToNodes = children =>
30
103
  children
31
104
  .flat(Infinity)
32
105
  .flatMap(child => {
33
- // Non-reactive values are untouched
34
- if (!child[isReactive])
35
- return [toNode(child)]
36
-
37
- // Reactive arrays become live fragments with auto-swapped children
38
- if (Array.isArray(child.value)) {
39
- const liveFragment = new LiveFragment()
40
- child.addReaction(() => {
41
- liveFragment.replaceChildren(...bruhChildrenToNodes(...child.value))
42
- })
43
- return [liveFragment.startMarker, ...bruhChildrenToNodes(...child.value), liveFragment.endMarker]
44
- }
45
-
46
- // Reactive values become auto-swapped DOM nodes
47
- let node = toNode(child.value)
48
- child.addReaction(() => {
49
- const oldNode = node
50
- node = toNode(child.value)
51
- oldNode.replaceWith(node)
52
- })
53
- return [node]
106
+ // Non-reactive child
107
+ if (!child?.[isReactive])
108
+ return [unreactiveChildToNode(child)]
109
+
110
+ // Single reactive value
111
+ if (!Array.isArray(child.value))
112
+ return [reactiveChildToNode(child)]
113
+
114
+ // Reactive array
115
+ return reactiveArrayChildToNodes(child)
54
116
  })
55
117
 
56
118
  //#endregion
@@ -110,10 +172,13 @@ export const t = textContent => {
110
172
 
111
173
  // Elements
112
174
  export const e = name => (...variadic) => {
175
+ if (variadic.length === 0)
176
+ return document.createElement(name)
177
+
113
178
  // If there are no props
114
179
  if (isBruhChild(variadic[0])) {
115
180
  const element = document.createElement(name)
116
- element.append(...bruhChildrenToNodes(...variadic))
181
+ element.append(...bruhChildrenToNodes(variadic))
117
182
  return element
118
183
  }
119
184
 
@@ -138,7 +203,7 @@ export const e = name => (...variadic) => {
138
203
  delete props.style
139
204
  }
140
205
  // Classes object
141
- if (typeof props.class === "object" && !props.style[isReactive]) {
206
+ if (typeof props.class === "object" && !props.class[isReactive]) {
142
207
  applyClasses(element, props.class)
143
208
  delete props.class
144
209
  }
@@ -154,7 +219,7 @@ export const e = name => (...variadic) => {
154
219
  applyAttributes(element, props)
155
220
 
156
221
  // Add the children to the element
157
- element.append(...bruhChildrenToNodes(...children))
222
+ element.append(...bruhChildrenToNodes(children))
158
223
  return element
159
224
  }
160
225
 
@@ -125,6 +125,7 @@ export class MetaElement {
125
125
 
126
126
  const contents = this.children
127
127
  .flat(Infinity)
128
+ .filter(x => typeof x !== "boolean" && x !== undefined && x !== null)
128
129
  .map(child =>
129
130
  (child[isMetaNode] || child[isMetaRawString])
130
131
  ? child.toString()
@@ -220,6 +221,9 @@ export const t = textContent =>
220
221
  export const e = name => (...variadic) => {
221
222
  const element = new MetaElement(name)
222
223
 
224
+ if (variadic.length === 0)
225
+ return element
226
+
223
227
  // If there are no props
224
228
  if (isMetaChild(variadic[0])) {
225
229
  element.children.push(...variadic)
@@ -1,4 +1,3 @@
1
1
  export * as dom from "./dom/index.browser.mjs"
2
- export * as liveFragment from "./dom/live-fragment.mjs"
3
2
  export * as reactive from "./reactive/index.mjs"
4
3
  export * as util from "./util/index.mjs"
File without changes
@@ -4,6 +4,7 @@ export const pipe = (x, ...fs) =>
4
4
 
5
5
  // Dispatch a custom event to (capturing) and from (bubbling) a target (usually a DOM node)
6
6
  // Returns false if the event was cancelled (preventDefault()) and true otherwise
7
+ // Note that this is synchronous
7
8
  export const dispatch = (target, type, options) =>
8
9
  target.dispatchEvent(
9
10
  // Default to behave like most DOM events
@@ -1,75 +0,0 @@
1
- // Lightweight and performant DOM fragment that keeps its place,
2
- // useful for grouping siblings without making a parent element.
3
- // Not a true analog of the DocumentFragment, because the implementation
4
- // would be infeasible with that scope, adding a performance penalty as well.
5
- // Works as long as the start & end placeholders are siblings in that order
6
- // and they do not overlap other LiveFragment's:
7
- // Works: (start A)(start B)(end B)(end A)
8
- // Fails: (start A)(start B)(end A)(end B)
9
- // Also, make sure not to call .normalize() on the parent element,
10
- // because that would ruin the placeholders.
11
- export class LiveFragment {
12
- startMarker = document.createTextNode("")
13
- endMarker = document.createTextNode("")
14
-
15
- static from(firstNode, lastNode) {
16
- const liveFragment = new this()
17
- firstNode.before(liveFragment.startMarker)
18
- lastNode.after(liveFragment.endMarker)
19
- return liveFragment
20
- }
21
-
22
- before(...xs) {
23
- this.startMarker.before(...xs)
24
- }
25
-
26
- prepend(...xs) {
27
- this.startMarker.after(...xs)
28
- }
29
-
30
- append(...xs) {
31
- this.endMarker.before(...xs)
32
- }
33
-
34
- after(...xs) {
35
- this.endMarker.after(...xs)
36
- }
37
-
38
- remove() {
39
- const range = document.createRange()
40
- range.setStartBefore(this.startMarker)
41
- range.setEndAfter(this.endMarker)
42
- range.deleteContents()
43
- }
44
-
45
- replaceChildren(...xs) {
46
- const range = document.createRange()
47
- range.setStartAfter(this.startMarker)
48
- range.setEndBefore(this.endMarker)
49
- range.deleteContents()
50
- this.startMarker.after(...xs)
51
- }
52
-
53
- replaceWith(...xs) {
54
- this.endMarker.after(...xs)
55
- this.remove()
56
- }
57
-
58
- get childNodes() {
59
- const childNodes = []
60
-
61
- for (
62
- let currentNode = this.startMarker.nextSibling;
63
- currentNode != this.endMarker && currentNode;
64
- currentNode = currentNode.nextSibling
65
- )
66
- childNodes.push(currentNode)
67
-
68
- return childNodes
69
- }
70
-
71
- get children() {
72
- return this.childNodes
73
- .filter(node => node instanceof HTMLElement)
74
- }
75
- }
package/vite.config.mjs DELETED
@@ -1,12 +0,0 @@
1
- import { defineConfig } from "vite"
2
-
3
- export default defineConfig({
4
- build: {
5
- lib: {
6
- name: "bruh",
7
- entry: new URL("./src/index.mjs", import.meta.url).pathname,
8
- fileName: format => `bruh.${format}.js`
9
- },
10
- sourcemap: true
11
- }
12
- })