bruh 1.9.2-types.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/dist/bruh.es.js +113 -164
- package/dist/bruh.es.js.map +1 -1
- package/dist/bruh.umd.js +1 -1
- package/dist/bruh.umd.js.map +1 -1
- package/package.json +5 -13
- package/src/dom/index.browser.mjs +116 -175
- package/src/dom/index.node.mjs +149 -127
- package/src/reactive/index.mjs +2 -4
- package/src/util/index.mjs +0 -14
- package/src/dom/index.browser.d.ts +0 -113
- package/src/reactive/index.d.ts +0 -36
package/README.md
CHANGED
package/dist/bruh.es.js
CHANGED
|
@@ -43,7 +43,7 @@ var __privateMethod = (obj, member, method) => {
|
|
|
43
43
|
__accessCheck(obj, member, "access private method");
|
|
44
44
|
return method;
|
|
45
45
|
};
|
|
46
|
-
var _a, _value, _reactions, _b, _value2, _reactions2, _f, _depth, _derivatives, _settersQueue, _derivativesQueue, _reactionsQueue, _applyUpdate, applyUpdate_fn
|
|
46
|
+
var _a, _value, _reactions, _b, _value2, _reactions2, _f, _depth, _derivatives, _settersQueue, _derivativesQueue, _reactionsQueue, _applyUpdate, applyUpdate_fn;
|
|
47
47
|
class LiveFragment {
|
|
48
48
|
constructor() {
|
|
49
49
|
__publicField(this, "startMarker", document.createTextNode(""));
|
|
@@ -99,7 +99,7 @@ var liveFragment = /* @__PURE__ */ Object.freeze({
|
|
|
99
99
|
[Symbol.toStringTag]: "Module",
|
|
100
100
|
LiveFragment
|
|
101
101
|
});
|
|
102
|
-
const isReactive
|
|
102
|
+
const isReactive = Symbol.for("bruh reactive");
|
|
103
103
|
class SimpleReactive {
|
|
104
104
|
constructor(value) {
|
|
105
105
|
__publicField(this, _a, true);
|
|
@@ -122,7 +122,7 @@ class SimpleReactive {
|
|
|
122
122
|
return () => __privateGet(this, _reactions).delete(reaction);
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
|
-
_a = isReactive
|
|
125
|
+
_a = isReactive;
|
|
126
126
|
_value = new WeakMap();
|
|
127
127
|
_reactions = new WeakMap();
|
|
128
128
|
const _FunctionalReactive = class {
|
|
@@ -160,7 +160,7 @@ const _FunctionalReactive = class {
|
|
|
160
160
|
return () => __privateGet(this, _reactions2).delete(reaction);
|
|
161
161
|
}
|
|
162
162
|
static applyUpdates() {
|
|
163
|
-
var _a2, _b2,
|
|
163
|
+
var _a2, _b2, _c;
|
|
164
164
|
if (!__privateGet(_FunctionalReactive, _settersQueue).size)
|
|
165
165
|
return;
|
|
166
166
|
for (const [sourceNode, newValue] of __privateGet(_FunctionalReactive, _settersQueue).entries())
|
|
@@ -169,7 +169,7 @@ const _FunctionalReactive = class {
|
|
|
169
169
|
for (const depthSet of __privateGet(_FunctionalReactive, _derivativesQueue))
|
|
170
170
|
if (depthSet)
|
|
171
171
|
for (const derivative of depthSet)
|
|
172
|
-
__privateMethod(
|
|
172
|
+
__privateMethod(_c = derivative, _applyUpdate, applyUpdate_fn).call(_c, __privateGet(_b2 = derivative, _f).call(_b2));
|
|
173
173
|
__privateGet(_FunctionalReactive, _derivativesQueue).length = 0;
|
|
174
174
|
for (const reaction of __privateGet(_FunctionalReactive, _reactionsQueue))
|
|
175
175
|
reaction();
|
|
@@ -177,7 +177,7 @@ const _FunctionalReactive = class {
|
|
|
177
177
|
}
|
|
178
178
|
};
|
|
179
179
|
let FunctionalReactive = _FunctionalReactive;
|
|
180
|
-
_b = isReactive
|
|
180
|
+
_b = isReactive;
|
|
181
181
|
_value2 = new WeakMap();
|
|
182
182
|
_reactions2 = new WeakMap();
|
|
183
183
|
_f = new WeakMap();
|
|
@@ -205,7 +205,7 @@ __privateAdd(FunctionalReactive, _derivativesQueue, []);
|
|
|
205
205
|
__privateAdd(FunctionalReactive, _reactionsQueue, []);
|
|
206
206
|
const r = (x, f) => new FunctionalReactive(x, f);
|
|
207
207
|
const reactiveDo = (x, f) => {
|
|
208
|
-
if (x == null ? void 0 : x[isReactive
|
|
208
|
+
if (x == null ? void 0 : x[isReactive]) {
|
|
209
209
|
f(x.value);
|
|
210
210
|
return x.addReaction(() => f(x.value));
|
|
211
211
|
}
|
|
@@ -214,68 +214,23 @@ const reactiveDo = (x, f) => {
|
|
|
214
214
|
var index$1 = /* @__PURE__ */ Object.freeze({
|
|
215
215
|
__proto__: null,
|
|
216
216
|
[Symbol.toStringTag]: "Module",
|
|
217
|
+
isReactive,
|
|
217
218
|
SimpleReactive,
|
|
218
219
|
FunctionalReactive,
|
|
219
220
|
r,
|
|
220
221
|
reactiveDo
|
|
221
222
|
});
|
|
222
|
-
const
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
cancelable: true,
|
|
226
|
-
composed: true
|
|
227
|
-
}, options)));
|
|
228
|
-
const createDestructable = (object, iterable) => {
|
|
229
|
-
const destructable = __spreadProps(__spreadValues({}, object), {
|
|
230
|
-
[Symbol.iterator]: () => iterable[Symbol.iterator]()
|
|
231
|
-
});
|
|
232
|
-
Object.defineProperty(destructable, Symbol.iterator, {
|
|
233
|
-
enumerable: false
|
|
234
|
-
});
|
|
235
|
-
return destructable;
|
|
236
|
-
};
|
|
237
|
-
const maybeDo = (existsThen, emptyThen) => (x) => {
|
|
238
|
-
if (Array.isArray(x)) {
|
|
239
|
-
if (x.length)
|
|
240
|
-
existsThen(x[0]);
|
|
241
|
-
else
|
|
242
|
-
emptyThen();
|
|
243
|
-
} else
|
|
244
|
-
existsThen(x);
|
|
245
|
-
};
|
|
246
|
-
const functionAsObject = (f) => new Proxy({}, {
|
|
247
|
-
get: (_, property) => f(property)
|
|
248
|
-
});
|
|
249
|
-
var index = /* @__PURE__ */ Object.freeze({
|
|
250
|
-
__proto__: null,
|
|
251
|
-
[Symbol.toStringTag]: "Module",
|
|
252
|
-
pipe,
|
|
253
|
-
dispatch,
|
|
254
|
-
createDestructable,
|
|
255
|
-
maybeDo,
|
|
256
|
-
functionAsObject
|
|
257
|
-
});
|
|
258
|
-
const isReactive = Symbol.for("bruh reactive");
|
|
259
|
-
const isMetaNode = Symbol.for("bruh meta node");
|
|
260
|
-
const isMetaTextNode = Symbol.for("bruh meta text node");
|
|
261
|
-
const isMetaElement = Symbol.for("bruh meta element");
|
|
262
|
-
const isMetaNodeChild = (x) => (x == null ? void 0 : x[isMetaNode]) || (x == null ? void 0 : x[isReactive]) || x instanceof Node || Array.isArray(x) || x == null || !(typeof x === "function" || typeof x === "object");
|
|
263
|
-
const toNode = (x) => {
|
|
264
|
-
if (x[isMetaNode])
|
|
265
|
-
return x.node;
|
|
266
|
-
if (x instanceof Node)
|
|
267
|
-
return x;
|
|
268
|
-
return document.createTextNode(x);
|
|
269
|
-
};
|
|
270
|
-
const childrenToNodes = (children) => children.flat(Infinity).flatMap((child) => {
|
|
223
|
+
const isBruhChild = (x) => (x == null ? void 0 : x[isReactive]) || x instanceof Node || Array.isArray(x) || x == null || !(typeof x === "function" || typeof x === "object");
|
|
224
|
+
const toNode = (x) => x instanceof Node ? x : document.createTextNode(x);
|
|
225
|
+
const bruhChildrenToNodes = (...children) => children.flat(Infinity).flatMap((child) => {
|
|
271
226
|
if (!child[isReactive])
|
|
272
227
|
return [toNode(child)];
|
|
273
228
|
if (Array.isArray(child.value)) {
|
|
274
229
|
const liveFragment2 = new LiveFragment();
|
|
275
230
|
child.addReaction(() => {
|
|
276
|
-
liveFragment2.replaceChildren(...
|
|
231
|
+
liveFragment2.replaceChildren(...bruhChildrenToNodes(...child.value));
|
|
277
232
|
});
|
|
278
|
-
return [liveFragment2.startMarker, ...
|
|
233
|
+
return [liveFragment2.startMarker, ...bruhChildrenToNodes(...child.value), liveFragment2.endMarker];
|
|
279
234
|
}
|
|
280
235
|
let node = toNode(child.value);
|
|
281
236
|
child.addReaction(() => {
|
|
@@ -285,126 +240,120 @@ const childrenToNodes = (children) => children.flat(Infinity).flatMap((child) =>
|
|
|
285
240
|
});
|
|
286
241
|
return [node];
|
|
287
242
|
});
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
this.node = document.createTextNode(textContent.value);
|
|
298
|
-
textContent.addReaction(() => {
|
|
299
|
-
this.node.textContent = textContent.value;
|
|
243
|
+
const applyStyles = (element, styles) => {
|
|
244
|
+
for (const property in styles)
|
|
245
|
+
reactiveDo(styles[property], (value) => {
|
|
246
|
+
if (value !== void 0)
|
|
247
|
+
element.style.setProperty(property, value);
|
|
248
|
+
else
|
|
249
|
+
element.style.removeProperty(property);
|
|
300
250
|
});
|
|
251
|
+
};
|
|
252
|
+
const applyClasses = (element, classes) => {
|
|
253
|
+
for (const name in classes)
|
|
254
|
+
reactiveDo(classes[name], (value) => {
|
|
255
|
+
element.classList.toggle(name, value);
|
|
256
|
+
});
|
|
257
|
+
};
|
|
258
|
+
const applyAttributes = (element, attributes) => {
|
|
259
|
+
for (const name in attributes)
|
|
260
|
+
reactiveDo(attributes[name], (value) => {
|
|
261
|
+
if (value !== void 0)
|
|
262
|
+
element.setAttribute(name, value);
|
|
263
|
+
else
|
|
264
|
+
element.removeAttribute(name);
|
|
265
|
+
});
|
|
266
|
+
};
|
|
267
|
+
const t = (textContent) => {
|
|
268
|
+
if (!textContent[isReactive])
|
|
269
|
+
return document.createTextNode(textContent);
|
|
270
|
+
const node = document.createTextNode(textContent.value);
|
|
271
|
+
textContent.addReaction(() => {
|
|
272
|
+
node.textContent = textContent.value;
|
|
273
|
+
});
|
|
274
|
+
return node;
|
|
275
|
+
};
|
|
276
|
+
const e = (name) => (...variadic) => {
|
|
277
|
+
var _a2;
|
|
278
|
+
if (isBruhChild(variadic[0])) {
|
|
279
|
+
const element2 = document.createElement(name);
|
|
280
|
+
element2.append(...bruhChildrenToNodes(...variadic));
|
|
281
|
+
return element2;
|
|
282
|
+
}
|
|
283
|
+
const [props, ...children] = variadic;
|
|
284
|
+
const { namespace } = (_a2 = props.bruh) != null ? _a2 : {};
|
|
285
|
+
delete props.bruh;
|
|
286
|
+
const element = namespace ? document.createElementNS(namespace, name) : document.createElement(name);
|
|
287
|
+
if (typeof props.style === "object") {
|
|
288
|
+
applyStyles(element, props.style);
|
|
289
|
+
delete props.style;
|
|
290
|
+
}
|
|
291
|
+
if (typeof props.class === "object") {
|
|
292
|
+
applyClasses(element, props.class);
|
|
293
|
+
delete props.class;
|
|
294
|
+
}
|
|
295
|
+
applyAttributes(element, props);
|
|
296
|
+
element.append(...bruhChildrenToNodes(...children));
|
|
297
|
+
return element;
|
|
298
|
+
};
|
|
299
|
+
const h = (nameOrComponent, props, ...children) => {
|
|
300
|
+
if (typeof nameOrComponent === "string") {
|
|
301
|
+
const makeElement = e(nameOrComponent);
|
|
302
|
+
return props ? makeElement(props, ...children) : makeElement(...children);
|
|
301
303
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
_c = isMetaNode, _d = isMetaTextNode;
|
|
308
|
-
class MetaElement {
|
|
309
|
-
constructor(name, namespace) {
|
|
310
|
-
__publicField(this, _e, true);
|
|
311
|
-
__publicField(this, _f2, true);
|
|
312
|
-
__publicField(this, "node");
|
|
313
|
-
this.node = namespace ? document.createElementNS(namespace, name) : document.createElement(name);
|
|
314
|
-
}
|
|
315
|
-
static from(element) {
|
|
316
|
-
const result = new this("div");
|
|
317
|
-
result.node = element;
|
|
318
|
-
return result;
|
|
319
|
-
}
|
|
320
|
-
addProperties(properties = {}) {
|
|
321
|
-
Object.assign(this.node, properties);
|
|
322
|
-
return this;
|
|
323
|
-
}
|
|
324
|
-
addAttributes(attributes = {}) {
|
|
325
|
-
for (const name in attributes)
|
|
326
|
-
reactiveDo(attributes[name], maybeDo((value) => this.node.setAttribute(name, value), () => this.node.removeAttribute(name)));
|
|
327
|
-
return this;
|
|
328
|
-
}
|
|
329
|
-
addDataAttributes(dataAttributes = {}) {
|
|
330
|
-
for (const name in dataAttributes)
|
|
331
|
-
reactiveDo(dataAttributes[name], maybeDo((value) => this.node.dataset[name] = value, () => delete this.node.dataset[name]));
|
|
332
|
-
return this;
|
|
333
|
-
}
|
|
334
|
-
addStyles(styles = {}) {
|
|
335
|
-
for (const property in styles)
|
|
336
|
-
reactiveDo(styles[property], maybeDo((value) => this.node.style.setProperty(property, value), () => this.node.style.removeProperty(property)));
|
|
337
|
-
return this;
|
|
338
|
-
}
|
|
339
|
-
toggleClasses(classes = {}) {
|
|
340
|
-
for (const name in classes)
|
|
341
|
-
reactiveDo(classes[name], (value) => this.node.classList.toggle(name, value));
|
|
342
|
-
return this;
|
|
343
|
-
}
|
|
344
|
-
before(...xs) {
|
|
345
|
-
this.node.before(...childrenToNodes(xs));
|
|
346
|
-
}
|
|
347
|
-
prepend(...xs) {
|
|
348
|
-
this.node.prepend(...childrenToNodes(xs));
|
|
349
|
-
}
|
|
350
|
-
append(...xs) {
|
|
351
|
-
this.node.append(...childrenToNodes(xs));
|
|
352
|
-
}
|
|
353
|
-
after(...xs) {
|
|
354
|
-
this.node.after(...childrenToNodes(xs));
|
|
355
|
-
}
|
|
356
|
-
replaceChildren(...xs) {
|
|
357
|
-
this.node.replaceChildren(...childrenToNodes(xs));
|
|
358
|
-
}
|
|
359
|
-
replaceWith(...xs) {
|
|
360
|
-
this.node.replaceWith(...childrenToNodes(xs));
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
_e = isMetaNode, _f2 = isMetaElement;
|
|
304
|
+
return nameOrComponent(__spreadProps(__spreadValues({}, props), { children }));
|
|
305
|
+
};
|
|
306
|
+
const JSXFragment = ({ children }) => children;
|
|
364
307
|
const hydrateTextNodes = () => {
|
|
365
308
|
const tagged = {};
|
|
366
309
|
const bruhTextNodes = document.getElementsByTagName("bruh-textnode");
|
|
367
310
|
for (const bruhTextNode of bruhTextNodes) {
|
|
368
311
|
const textNode = document.createTextNode(bruhTextNode.textContent);
|
|
369
|
-
|
|
370
|
-
|
|
312
|
+
const tag = bruhTextNode.getAttribute("tag");
|
|
313
|
+
if (tag)
|
|
314
|
+
tagged[tag] = textNode;
|
|
371
315
|
bruhTextNode.replaceWith(textNode);
|
|
372
316
|
}
|
|
373
317
|
return tagged;
|
|
374
318
|
};
|
|
375
|
-
const createMetaTextNode = (textContent) => new MetaTextNode(textContent);
|
|
376
|
-
const createMetaElement = (name, namespace) => (...variadic) => {
|
|
377
|
-
const meta = new MetaElement(name, namespace);
|
|
378
|
-
if (!isMetaNodeChild(variadic[0])) {
|
|
379
|
-
const [attributes, ...children] = variadic;
|
|
380
|
-
meta.addAttributes(attributes);
|
|
381
|
-
meta.append(children);
|
|
382
|
-
} else {
|
|
383
|
-
meta.append(variadic);
|
|
384
|
-
}
|
|
385
|
-
return meta;
|
|
386
|
-
};
|
|
387
|
-
const createMetaElementJSX = (nameOrComponent, attributesOrProps, ...children) => {
|
|
388
|
-
if (typeof nameOrComponent == "string") {
|
|
389
|
-
const meta = new MetaElement(nameOrComponent);
|
|
390
|
-
meta.addAttributes(attributesOrProps || {});
|
|
391
|
-
meta.append(children);
|
|
392
|
-
return meta;
|
|
393
|
-
}
|
|
394
|
-
return nameOrComponent(Object.assign({}, attributesOrProps, { children }));
|
|
395
|
-
};
|
|
396
|
-
const JSXFragment = ({ children }) => children;
|
|
397
319
|
var index_browser = /* @__PURE__ */ Object.freeze({
|
|
398
320
|
__proto__: null,
|
|
399
321
|
[Symbol.toStringTag]: "Module",
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
t
|
|
405
|
-
e
|
|
406
|
-
h
|
|
407
|
-
JSXFragment
|
|
322
|
+
bruhChildrenToNodes,
|
|
323
|
+
applyStyles,
|
|
324
|
+
applyClasses,
|
|
325
|
+
applyAttributes,
|
|
326
|
+
t,
|
|
327
|
+
e,
|
|
328
|
+
h,
|
|
329
|
+
JSXFragment,
|
|
330
|
+
hydrateTextNodes
|
|
331
|
+
});
|
|
332
|
+
const pipe = (x, ...fs) => fs.reduce((y, f) => f(y), x);
|
|
333
|
+
const dispatch = (target, type, options) => target.dispatchEvent(new CustomEvent(type, __spreadValues({
|
|
334
|
+
bubbles: true,
|
|
335
|
+
cancelable: true,
|
|
336
|
+
composed: true
|
|
337
|
+
}, options)));
|
|
338
|
+
const createDestructable = (object, iterable) => {
|
|
339
|
+
const destructable = __spreadProps(__spreadValues({}, object), {
|
|
340
|
+
[Symbol.iterator]: () => iterable[Symbol.iterator]()
|
|
341
|
+
});
|
|
342
|
+
Object.defineProperty(destructable, Symbol.iterator, {
|
|
343
|
+
enumerable: false
|
|
344
|
+
});
|
|
345
|
+
return destructable;
|
|
346
|
+
};
|
|
347
|
+
const functionAsObject = (f) => new Proxy({}, {
|
|
348
|
+
get: (_, property) => f(property)
|
|
349
|
+
});
|
|
350
|
+
var index = /* @__PURE__ */ Object.freeze({
|
|
351
|
+
__proto__: null,
|
|
352
|
+
[Symbol.toStringTag]: "Module",
|
|
353
|
+
pipe,
|
|
354
|
+
dispatch,
|
|
355
|
+
createDestructable,
|
|
356
|
+
functionAsObject
|
|
408
357
|
});
|
|
409
358
|
export { index_browser as dom, liveFragment, index$1 as reactive, index as util };
|
|
410
359
|
//# sourceMappingURL=bruh.es.js.map
|
package/dist/bruh.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bruh.es.js","sources":["../src/dom/live-fragment.mjs","../src/reactive/index.mjs","../src/util/index.mjs","../src/dom/index.browser.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","/** @typedef { import(\"./index\") } */\n\nconst 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, go ahead and apply them first\n // It's ok that there's already a microtask queued for this\n if (FunctionalReactive.#settersQueue.size)\n FunctionalReactive.applyUpdates()\n\n return this.#value\n }\n\n set value(newValue) {\n // Only allow souce 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","// 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// A function that acts like Maybe.from(x).ifExists(existsThen).ifEmpty(emptyThen)\n// Except we just use an array in place of a true Maybe type\n// This is useful for setting and removing reactive attributes\nexport const maybeDo = (existsThen, emptyThen) => x => {\n if (Array.isArray(x)) {\n if (x.length)\n existsThen(x[0])\n else\n emptyThen()\n }\n else\n existsThen(x)\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","/** @typedef { import(\"./index.browser\") } */\n\nimport { LiveFragment } from \"./live-fragment.mjs\"\nimport { reactiveDo } from \"../reactive/index.mjs\"\nimport { maybeDo } from \"../util/index.mjs\"\n\nconst isReactive = Symbol.for(\"bruh reactive\")\nconst isMetaNode = Symbol.for(\"bruh meta node\")\nconst isMetaTextNode = Symbol.for(\"bruh meta text node\")\nconst isMetaElement = Symbol.for(\"bruh meta element\")\n\n// A basic check for if a value is allowed as a meta node's child\n// It's responsible for quickly checking the type, not deep validation\nconst isMetaNodeChild = x =>\n // meta nodes, reactives, and DOM nodes\n x?.[isMetaNode] ||\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\nconst toNode = x => {\n if (x[isMetaNode])\n return x.node\n\n if (x instanceof Node)\n return x\n\n return document.createTextNode(x)\n}\n\nexport const childrenToNodes = children =>\n children\n .flat(Infinity)\n .flatMap(child => {\n if (!child[isReactive])\n return [toNode(child)]\n\n if (Array.isArray(child.value)) {\n const liveFragment = new LiveFragment()\n child.addReaction(() => {\n liveFragment.replaceChildren(...childrenToNodes(child.value))\n })\n return [liveFragment.startMarker, ...childrenToNodes(child.value), liveFragment.endMarker]\n }\n\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\n\n// Meta Nodes\n\nexport class MetaTextNode {\n [isMetaNode] = true;\n [isMetaTextNode] = true\n\n node\n\n constructor(textContent) {\n if (!textContent[isReactive]) {\n this.node = document.createTextNode(textContent)\n return\n }\n\n this.node = document.createTextNode(textContent.value)\n textContent.addReaction(() => {\n this.node.textContent = textContent.value\n })\n }\n\n addProperties(properties = {}) {\n Object.assign(this.node, properties)\n\n return this\n }\n}\n\nexport class MetaElement {\n [isMetaNode] = true;\n [isMetaElement] = true\n\n node\n\n constructor(name, namespace) {\n this.node =\n namespace\n ? document.createElementNS(namespace, name)\n : document.createElement ( name)\n }\n\n static from(element) {\n const result = new this(\"div\")\n result.node = element\n return result\n }\n\n addProperties(properties = {}) {\n Object.assign(this.node, properties)\n\n return this\n }\n\n addAttributes(attributes = {}) {\n for (const name in attributes)\n reactiveDo(attributes[name],\n maybeDo(\n value => this.node.setAttribute (name, value),\n () => this.node.removeAttribute(name)\n )\n )\n\n return this\n }\n\n addDataAttributes(dataAttributes = {}) {\n for (const name in dataAttributes)\n reactiveDo(dataAttributes[name],\n maybeDo(\n value => this.node.dataset[name] = value,\n () => delete this.node.dataset[name]\n )\n )\n\n return this\n }\n\n addStyles(styles = {}) {\n for (const property in styles)\n reactiveDo(styles[property],\n maybeDo(\n value => this.node.style.setProperty (property, value),\n () => this.node.style.removeProperty(property)\n )\n )\n\n return this\n }\n\n toggleClasses(classes = {}) {\n for (const name in classes)\n reactiveDo(classes[name],\n value => this.node.classList.toggle(name, value)\n )\n\n return this\n }\n\n before(...xs) {\n this.node.before(...childrenToNodes(xs))\n }\n\n prepend(...xs) {\n this.node.prepend(...childrenToNodes(xs))\n }\n\n append(...xs) {\n this.node.append(...childrenToNodes(xs))\n }\n\n after(...xs) {\n this.node.after(...childrenToNodes(xs))\n }\n\n replaceChildren(...xs) {\n this.node.replaceChildren(...childrenToNodes(xs))\n }\n\n replaceWith(...xs) {\n this.node.replaceWith(...childrenToNodes(xs))\n }\n}\n\n\n\n// Convenience functions\n\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 if (bruhTextNode.dataset.tag)\n tagged[bruhTextNode.dataset.tag] = textNode\n\n bruhTextNode.replaceWith(textNode)\n }\n\n return tagged\n}\n\nconst createMetaTextNode = textContent =>\n new MetaTextNode(textContent)\n\nconst createMetaElement = (name, namespace) => (...variadic) => {\n const meta = new MetaElement(name, namespace)\n\n // Implement optional attributes as first argument\n if (!isMetaNodeChild(variadic[0])) {\n const [attributes, ...children] = variadic\n meta.addAttributes(attributes)\n meta.append(children)\n }\n else {\n meta.append(variadic)\n }\n\n return meta\n}\n\n// JSX integration\nconst createMetaElementJSX = (nameOrComponent, attributesOrProps, ...children) => {\n // If we are making a html element\n // This is likely when the jsx tag name begins with a lowercase character\n if (typeof nameOrComponent == \"string\") {\n const meta = new MetaElement(nameOrComponent)\n\n // These are attributes then, but they might be null/undefined\n meta.addAttributes(attributesOrProps || {})\n meta.append(children)\n\n return meta\n }\n\n // It must be a component, then\n // Bruh components are just functions that return meta elements\n // Due to JSX, this would mean a function with only one parameter - a \"props\" object\n // This object includes the all of the attributes and a \"children\" key\n return nameOrComponent( Object.assign({}, attributesOrProps, { children }) )\n}\n\n// These will be called with short names\nexport {\n createMetaTextNode as t,\n createMetaElement as e,\n createMetaElementJSX as h\n}\n\n// The JSX fragment is made into a bruh fragment (just an array)\nexport const JSXFragment = ({ children }) => children\n"],"names":["isReactive"],"mappings":"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"}
|
|
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, go ahead and apply them first\n // It's ok that there's already a microtask queued for this\n if (FunctionalReactive.#settersQueue.size)\n FunctionalReactive.applyUpdates()\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 if (typeof props.style === \"object\") {\n applyStyles(element, props.style)\n delete props.style\n }\n if (typeof props.class === \"object\") {\n applyClasses(element, props.class)\n delete props.class\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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"}
|
package/dist/bruh.umd.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var ne=Object.defineProperty,oe=Object.defineProperties;var se=Object.getOwnPropertyDescriptors;var W=Object.getOwnPropertySymbols;var ae=Object.prototype.hasOwnProperty,ie=Object.prototype.propertyIsEnumerable;var C=(n,o,i)=>o in n?ne(n,o,{enumerable:!0,configurable:!0,writable:!0,value:i}):n[o]=i,R=(n,o)=>{for(var i in o||(o={}))ae.call(o,i)&&C(n,i,o[i]);if(W)for(var i of W(o))ie.call(o,i)&&C(n,i,o[i]);return n},F=(n,o)=>oe(n,se(o));var E=(n,o,i)=>(C(n,typeof o!="symbol"?o+"":o,i),i),O=(n,o,i)=>{if(!o.has(n))throw TypeError("Cannot "+i)};var a=(n,o,i)=>(O(n,o,"read from private field"),i?i.call(n):o.get(n)),u=(n,o,i)=>{if(o.has(n))throw TypeError("Cannot add the same private member more than once");o instanceof WeakSet?o.add(n):o.set(n,i)},b=(n,o,i,l)=>(O(n,o,"write to private field"),l?l.call(n,i):o.set(n,i),i);var _=(n,o,i)=>(O(n,o,"access private method"),i);(function(n,o){typeof exports=="object"&&typeof module!="undefined"?o(exports):typeof define=="function"&&define.amd?define(["exports"],o):(n=typeof globalThis!="undefined"?globalThis:n||self,o(n.bruh={}))})(this,function(n){var ce,m,g,de,h,S,k,y,A,p,M,N,j,q;"use strict";class o{constructor(){E(this,"startMarker",document.createTextNode(""));E(this,"endMarker",document.createTextNode(""))}static from(e,t){const s=new this;return e.before(s.startMarker),t.after(s.endMarker),s}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:o});const l=Symbol.for("bruh reactive");class J{constructor(e){E(this,ce,!0);u(this,m,void 0);u(this,g,new Set);b(this,m,e)}get value(){return a(this,m)}set value(e){if(e!==a(this,m)){b(this,m,e);for(const t of a(this,g))t()}}addReaction(e){return a(this,g).add(e),()=>a(this,g).delete(e)}}ce=l,m=new WeakMap,g=new WeakMap;const c=class{constructor(e,t){u(this,j);E(this,de,!0);u(this,h,void 0);u(this,S,new Set);u(this,k,void 0);u(this,y,0);u(this,A,new Set);if(!t){b(this,h,e);return}b(this,h,t()),b(this,k,t),b(this,y,Math.max(...e.map(s=>a(s,y)))+1),e.forEach(s=>a(s,A).add(this))}get value(){return a(c,p).size&&c.applyUpdates(),a(this,h)}set value(e){a(this,y)===0&&(a(c,p).size||queueMicrotask(c.applyUpdates),a(c,p).set(this,e))}addReaction(e){return a(this,S).add(e),()=>a(this,S).delete(e)}static applyUpdates(){var e,t,s;if(!!a(c,p).size){for(const[d,f]of a(c,p).entries())_(e=d,j,q).call(e,f);a(c,p).clear();for(const d of a(c,M))if(d)for(const f of d)_(s=f,j,q).call(s,a(t=f,k).call(t));a(c,M).length=0;for(const d of a(c,N))d();a(c,N).length=0}}};let v=c;de=l,h=new WeakMap,S=new WeakMap,k=new WeakMap,y=new WeakMap,A=new WeakMap,p=new WeakMap,M=new WeakMap,N=new WeakMap,j=new WeakSet,q=function(e){if(e===a(this,h))return;b(this,h,e),a(c,N).push(...a(this,S));const t=a(c,M);for(const s of a(this,A)){const d=a(s,y);t[d]||(t[d]=new Set),t[d].add(s)}},u(v,p,new Map),u(v,M,[]),u(v,N,[]);const X=(r,e)=>new v(r,e),w=(r,e)=>{if(r==null?void 0:r[l])return e(r.value),r.addReaction(()=>e(r.value));e(r)};var H=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",isReactive:l,SimpleReactive:J,FunctionalReactive:v,r:X,reactiveDo:w});const I=r=>(r==null?void 0:r[l])||r instanceof Node||Array.isArray(r)||r==null||!(typeof r=="function"||typeof r=="object"),z=r=>r instanceof Node?r:document.createTextNode(r),T=(...r)=>r.flat(1/0).flatMap(e=>{if(!e[l])return[z(e)];if(Array.isArray(e.value)){const s=new o;return e.addReaction(()=>{s.replaceChildren(...T(...e.value))}),[s.startMarker,...T(...e.value),s.endMarker]}let t=z(e.value);return e.addReaction(()=>{const s=t;t=z(e.value),s.replaceWith(t)}),[t]}),P=(r,e)=>{for(const t in e)w(e[t],s=>{s!==void 0?r.style.setProperty(t,s):r.style.removeProperty(t)})},B=(r,e)=>{for(const t in e)w(e[t],s=>{r.classList.toggle(t,s)})},D=(r,e)=>{for(const t in e)w(e[t],s=>{s!==void 0?r.setAttribute(t,s):r.removeAttribute(t)})},$=r=>{if(!r[l])return document.createTextNode(r);const e=document.createTextNode(r.value);return r.addReaction(()=>{e.textContent=r.value}),e},L=r=>(...e)=>{var U;if(I(e[0])){const Q=document.createElement(r);return Q.append(...T(...e)),Q}const[t,...s]=e,{namespace:d}=(U=t.bruh)!=null?U:{};delete t.bruh;const f=d?document.createElementNS(d,r):document.createElement(r);return typeof t.style=="object"&&(P(f,t.style),delete t.style),typeof t.class=="object"&&(B(f,t.class),delete t.class),D(f,t),f.append(...T(...s)),f},G=(r,e,...t)=>{if(typeof r=="string"){const s=L(r);return e?s(e,...t):s(...t)}return r(F(R({},e),{children:t}))},K=({children:r})=>r,Y=()=>{const r={},e=document.getElementsByTagName("bruh-textnode");for(const t of e){const s=document.createTextNode(t.textContent),d=t.getAttribute("tag");d&&(r[d]=s),t.replaceWith(s)}return r};var Z=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",bruhChildrenToNodes:T,applyStyles:P,applyClasses:B,applyAttributes:D,t:$,e:L,h:G,JSXFragment:K,hydrateTextNodes:Y});const V=(r,...e)=>e.reduce((t,s)=>s(t),r),x=(r,e,t)=>r.dispatchEvent(new CustomEvent(e,R({bubbles:!0,cancelable:!0,composed:!0},t))),ee=(r,e)=>{const t=F(R({},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"});
|
|
2
2
|
//# sourceMappingURL=bruh.umd.js.map
|
package/dist/bruh.umd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bruh.umd.js","sources":["../src/dom/live-fragment.mjs","../src/reactive/index.mjs","../src/util/index.mjs","../src/dom/index.browser.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","/** @typedef { import(\"./index\") } */\n\nconst 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, go ahead and apply them first\n // It's ok that there's already a microtask queued for this\n if (FunctionalReactive.#settersQueue.size)\n FunctionalReactive.applyUpdates()\n\n return this.#value\n }\n\n set value(newValue) {\n // Only allow souce 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","// 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// A function that acts like Maybe.from(x).ifExists(existsThen).ifEmpty(emptyThen)\n// Except we just use an array in place of a true Maybe type\n// This is useful for setting and removing reactive attributes\nexport const maybeDo = (existsThen, emptyThen) => x => {\n if (Array.isArray(x)) {\n if (x.length)\n existsThen(x[0])\n else\n emptyThen()\n }\n else\n existsThen(x)\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","/** @typedef { import(\"./index.browser\") } */\n\nimport { LiveFragment } from \"./live-fragment.mjs\"\nimport { reactiveDo } from \"../reactive/index.mjs\"\nimport { maybeDo } from \"../util/index.mjs\"\n\nconst isReactive = Symbol.for(\"bruh reactive\")\nconst isMetaNode = Symbol.for(\"bruh meta node\")\nconst isMetaTextNode = Symbol.for(\"bruh meta text node\")\nconst isMetaElement = Symbol.for(\"bruh meta element\")\n\n// A basic check for if a value is allowed as a meta node's child\n// It's responsible for quickly checking the type, not deep validation\nconst isMetaNodeChild = x =>\n // meta nodes, reactives, and DOM nodes\n x?.[isMetaNode] ||\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\nconst toNode = x => {\n if (x[isMetaNode])\n return x.node\n\n if (x instanceof Node)\n return x\n\n return document.createTextNode(x)\n}\n\nexport const childrenToNodes = children =>\n children\n .flat(Infinity)\n .flatMap(child => {\n if (!child[isReactive])\n return [toNode(child)]\n\n if (Array.isArray(child.value)) {\n const liveFragment = new LiveFragment()\n child.addReaction(() => {\n liveFragment.replaceChildren(...childrenToNodes(child.value))\n })\n return [liveFragment.startMarker, ...childrenToNodes(child.value), liveFragment.endMarker]\n }\n\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\n\n// Meta Nodes\n\nexport class MetaTextNode {\n [isMetaNode] = true;\n [isMetaTextNode] = true\n\n node\n\n constructor(textContent) {\n if (!textContent[isReactive]) {\n this.node = document.createTextNode(textContent)\n return\n }\n\n this.node = document.createTextNode(textContent.value)\n textContent.addReaction(() => {\n this.node.textContent = textContent.value\n })\n }\n\n addProperties(properties = {}) {\n Object.assign(this.node, properties)\n\n return this\n }\n}\n\nexport class MetaElement {\n [isMetaNode] = true;\n [isMetaElement] = true\n\n node\n\n constructor(name, namespace) {\n this.node =\n namespace\n ? document.createElementNS(namespace, name)\n : document.createElement ( name)\n }\n\n static from(element) {\n const result = new this(\"div\")\n result.node = element\n return result\n }\n\n addProperties(properties = {}) {\n Object.assign(this.node, properties)\n\n return this\n }\n\n addAttributes(attributes = {}) {\n for (const name in attributes)\n reactiveDo(attributes[name],\n maybeDo(\n value => this.node.setAttribute (name, value),\n () => this.node.removeAttribute(name)\n )\n )\n\n return this\n }\n\n addDataAttributes(dataAttributes = {}) {\n for (const name in dataAttributes)\n reactiveDo(dataAttributes[name],\n maybeDo(\n value => this.node.dataset[name] = value,\n () => delete this.node.dataset[name]\n )\n )\n\n return this\n }\n\n addStyles(styles = {}) {\n for (const property in styles)\n reactiveDo(styles[property],\n maybeDo(\n value => this.node.style.setProperty (property, value),\n () => this.node.style.removeProperty(property)\n )\n )\n\n return this\n }\n\n toggleClasses(classes = {}) {\n for (const name in classes)\n reactiveDo(classes[name],\n value => this.node.classList.toggle(name, value)\n )\n\n return this\n }\n\n before(...xs) {\n this.node.before(...childrenToNodes(xs))\n }\n\n prepend(...xs) {\n this.node.prepend(...childrenToNodes(xs))\n }\n\n append(...xs) {\n this.node.append(...childrenToNodes(xs))\n }\n\n after(...xs) {\n this.node.after(...childrenToNodes(xs))\n }\n\n replaceChildren(...xs) {\n this.node.replaceChildren(...childrenToNodes(xs))\n }\n\n replaceWith(...xs) {\n this.node.replaceWith(...childrenToNodes(xs))\n }\n}\n\n\n\n// Convenience functions\n\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 if (bruhTextNode.dataset.tag)\n tagged[bruhTextNode.dataset.tag] = textNode\n\n bruhTextNode.replaceWith(textNode)\n }\n\n return tagged\n}\n\nconst createMetaTextNode = textContent =>\n new MetaTextNode(textContent)\n\nconst createMetaElement = (name, namespace) => (...variadic) => {\n const meta = new MetaElement(name, namespace)\n\n // Implement optional attributes as first argument\n if (!isMetaNodeChild(variadic[0])) {\n const [attributes, ...children] = variadic\n meta.addAttributes(attributes)\n meta.append(children)\n }\n else {\n meta.append(variadic)\n }\n\n return meta\n}\n\n// JSX integration\nconst createMetaElementJSX = (nameOrComponent, attributesOrProps, ...children) => {\n // If we are making a html element\n // This is likely when the jsx tag name begins with a lowercase character\n if (typeof nameOrComponent == \"string\") {\n const meta = new MetaElement(nameOrComponent)\n\n // These are attributes then, but they might be null/undefined\n meta.addAttributes(attributesOrProps || {})\n meta.append(children)\n\n return meta\n }\n\n // It must be a component, then\n // Bruh components are just functions that return meta elements\n // Due to JSX, this would mean a function with only one parameter - a \"props\" object\n // This object includes the all of the attributes and a \"children\" key\n return nameOrComponent( Object.assign({}, attributesOrProps, { children }) )\n}\n\n// These will be called with short names\nexport {\n createMetaTextNode as t,\n createMetaElement as e,\n createMetaElementJSX as h\n}\n\n// The JSX fragment is made into a bruh fragment (just an array)\nexport const JSXFragment = ({ children }) => children\n"],"names":["isReactive"],"mappings":"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"}
|
|
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, go ahead and apply them first\n // It's ok that there's already a microtask queued for this\n if (FunctionalReactive.#settersQueue.size)\n FunctionalReactive.applyUpdates()\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 if (typeof props.style === \"object\") {\n applyStyles(element, props.style)\n delete props.style\n }\n if (typeof props.class === \"object\") {\n applyClasses(element, props.class)\n delete props.class\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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"}
|