bruh 1.8.0 → 1.9.2-types.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 CHANGED
@@ -44,3 +44,5 @@ developers who know what they are doing - a group which you might fit into.
44
44
  # Where is the documentation?
45
45
 
46
46
  [Right here](https://technicalsource.dev/bruh)
47
+
48
+ https://codesandbox.io/s/github/Technical-Source/bruh/tree/main/packages/create-bruh/vite
package/dist/bruh.es.js CHANGED
@@ -1,2 +1,410 @@
1
- var e,t,r,a,n,o,s,i,d,c,l,h,u,p=Object.defineProperty,f=Object.defineProperties,b=Object.getOwnPropertyDescriptors,m=Object.getOwnPropertySymbols,v=Object.prototype.hasOwnProperty,y=Object.prototype.propertyIsEnumerable,M=(e,t,r)=>t in e?p(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,g=(e,t)=>{for(var r in t||(t={}))v.call(t,r)&&M(e,r,t[r]);if(m)for(var r of m(t))y.call(t,r)&&M(e,r,t[r]);return e},w=(e,t,r)=>(M(e,"symbol"!=typeof t?t+"":t,r),r),k=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)},S=(e,t,r)=>(k(e,t,"read from private field"),r?r.call(e):t.get(e)),O=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},x=(e,t,r,a)=>(k(e,t,"write to private field"),a?a.call(e,r):t.set(e,r),r),T=(e,t,r)=>(k(e,t,"access private method"),r);class W{constructor(){this.startMarker=document.createTextNode(""),this.endMarker=document.createTextNode("")}static from(e,t){const r=new this;return e.before(r.startMarker),t.after(r.endMarker),r}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 _=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",LiveFragment:W});const j=Symbol.for("bruh reactive");e=j,t=new WeakMap,r=new WeakMap;const A=class{constructor(e,t){O(this,h),w(this,a,!0),O(this,n,void 0),O(this,o,new Set),O(this,s,void 0),O(this,i,0),O(this,d,new Set),t?(x(this,n,t()),x(this,s,t),x(this,i,Math.max(...e.map((e=>S(e,i))))+1),e.forEach((e=>S(e,d).add(this)))):x(this,n,e)}get value(){return S(A,c).size&&A.applyUpdates(),S(this,n)}set value(e){0===S(this,i)&&(S(A,c).size||queueMicrotask(A.applyUpdates),S(A,c).set(this,e))}addReaction(e){return S(this,o).add(e),()=>S(this,o).delete(e)}static applyUpdates(){var e,t,r;if(S(A,c).size){for(const[t,r]of S(A,c).entries())T(e=t,h,u).call(e,r);S(A,c).clear();for(const e of S(A,l))if(e)for(const a of e)T(r=a,h,u).call(r,S(t=a,s).call(t));S(A,l).length=0}}};let N=A;a=j,n=new WeakMap,o=new WeakMap,s=new WeakMap,i=new WeakMap,d=new WeakMap,c=new WeakMap,l=new WeakMap,h=new WeakSet,u=function(e){if(e===S(this,n))return;x(this,n,e);for(const r of S(this,o))r(e);const t=S(A,l);for(const r of S(this,d)){const e=S(r,i);t[e]||(t[e]=new Set),t[e].add(r)}},O(N,c,new Map),O(N,l,[]);const E=(e,t)=>{if(null==e?void 0:e[j])return t(e.value),e.addReaction((()=>t(e.value)));t(e)};var C=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",SimpleReactive:class{constructor(a){w(this,e,!0),O(this,t,void 0),O(this,r,new Set),x(this,t,a)}get value(){return S(this,t)}set value(e){if(e!==S(this,t)){x(this,t,e);for(const e of S(this,r))e()}}addReaction(e){return S(this,r).add(e),()=>S(this,r).delete(e)}},FunctionalReactive:N,r:(e,t)=>new N(e,t),reactiveDo:E});const R=(e,t)=>r=>{Array.isArray(r)?r.length?e(r[0]):t():e(r)};var P=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",pipe:(e,...t)=>t.reduce(((e,t)=>t(e)),e),dispatch:(e,t,r)=>e.dispatchEvent(new CustomEvent(t,g({bubbles:!0,cancelable:!0,composed:!0},r))),createDestructable:(e,t)=>{const r=(a=g({},e),n={[Symbol.iterator]:()=>t[Symbol.iterator]()},f(a,b(n)));var a,n;return Object.defineProperty(r,Symbol.iterator,{enumerable:!1}),r},maybeDo:R,functionAsObject:e=>new Proxy({},{get:(t,r)=>e(r)})});const z=Symbol.for("bruh reactive"),D=Symbol.for("bruh meta node"),B=Symbol.for("bruh meta text node"),F=Symbol.for("bruh meta element"),U=e=>e[D]?e.node:e instanceof Node?e:document.createTextNode(e),L=e=>e.flat(1/0).flatMap((e=>{if(!e[z])return[U(e)];if(Array.isArray(e.value)){const t=new W;return e.addReaction((()=>{t.replaceChildren(...L(e.value))})),[t.startMarker,...L(e.value),t.endMarker]}let t=U(e.value);return e.addReaction((()=>{const r=t;t=U(e.value),r.replaceWith(t)})),[t]}));class q{constructor(e){this[D]=this[B]=!0,e[z]?(this.node=document.createTextNode(e.value),e.addReaction((()=>{this.node.textContent=e.value}))):this.node=document.createTextNode(e)}addProperties(e={}){return Object.assign(this.node,e),this}}class H{constructor(e,t){this[D]=this[F]=!0,this.node=t?document.createElementNS(t,e):document.createElement(e)}static from(e){const t=new this("div");return t.node=e,t}addProperties(e={}){return Object.assign(this.node,e),this}addAttributes(e={}){for(const t in e)E(e[t],R((e=>this.node.setAttribute(t,e)),(()=>this.node.removeAttribute(t))));return this}addDataAttributes(e={}){for(const t in e)E(e[t],R((e=>this.node.dataset[t]=e),(()=>delete this.node.dataset[t])));return this}before(...e){this.node.before(...L(e))}prepend(...e){this.node.prepend(...L(e))}append(...e){this.node.append(...L(e))}after(...e){this.node.after(...L(e))}replaceChildren(...e){this.node.replaceChildren(...L(e))}replaceWith(...e){this.node.replaceWith(...L(e))}}var I=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",childrenToNodes:L,MetaTextNode:q,MetaElement:H,hydrateTextNodes:()=>{const e={},t=document.getElementsByTagName("bruh-textnode");for(const r of t){const t=document.createTextNode(r.textContent);r.dataset.tag&&(e[r.dataset.tag]=t),r.replaceWith(t)}return e},t:e=>new q(e),e:(e,t)=>(...r)=>{const a=new H(e,t);if((null==(n=r[0])?void 0:n[D])||(null==n?void 0:n[z])||n instanceof Node||Array.isArray(n)||"function"!=typeof n)a.append(r);else{const[e,...t]=r;a.addAttributes(e),a.append(t)}var n;return a},h:(e,t,...r)=>{if("string"==typeof e){const a=new H(e);return a.addAttributes(t||{}),a.append(r),a}return e(Object.assign({},t,{children:r}))},JSXFragment:({children:e})=>e});export{I as dom,_ as liveFragment,C as reactive,P as util};
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))
34
+ 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, _c, _d, _e, _f2;
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$1 = 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);
109
+ }
110
+ get value() {
111
+ return __privateGet(this, _value);
112
+ }
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();
119
+ }
120
+ addReaction(reaction) {
121
+ __privateGet(this, _reactions).add(reaction);
122
+ return () => __privateGet(this, _reactions).delete(reaction);
123
+ }
124
+ }
125
+ _a = isReactive$1;
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);
139
+ return;
140
+ }
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));
145
+ }
146
+ get value() {
147
+ if (__privateGet(_FunctionalReactive, _settersQueue).size)
148
+ _FunctionalReactive.applyUpdates();
149
+ return __privateGet(this, _value2);
150
+ }
151
+ set value(newValue) {
152
+ if (__privateGet(this, _depth) !== 0)
153
+ return;
154
+ if (!__privateGet(_FunctionalReactive, _settersQueue).size)
155
+ queueMicrotask(_FunctionalReactive.applyUpdates);
156
+ __privateGet(_FunctionalReactive, _settersQueue).set(this, newValue);
157
+ }
158
+ addReaction(reaction) {
159
+ __privateGet(this, _reactions2).add(reaction);
160
+ return () => __privateGet(this, _reactions2).delete(reaction);
161
+ }
162
+ static applyUpdates() {
163
+ var _a2, _b2, _c2;
164
+ if (!__privateGet(_FunctionalReactive, _settersQueue).size)
165
+ return;
166
+ for (const [sourceNode, newValue] of __privateGet(_FunctionalReactive, _settersQueue).entries())
167
+ __privateMethod(_a2 = sourceNode, _applyUpdate, applyUpdate_fn).call(_a2, newValue);
168
+ __privateGet(_FunctionalReactive, _settersQueue).clear();
169
+ for (const depthSet of __privateGet(_FunctionalReactive, _derivativesQueue))
170
+ if (depthSet)
171
+ for (const derivative of depthSet)
172
+ __privateMethod(_c2 = derivative, _applyUpdate, applyUpdate_fn).call(_c2, __privateGet(_b2 = derivative, _f).call(_b2));
173
+ __privateGet(_FunctionalReactive, _derivativesQueue).length = 0;
174
+ for (const reaction of __privateGet(_FunctionalReactive, _reactionsQueue))
175
+ reaction();
176
+ __privateGet(_FunctionalReactive, _reactionsQueue).length = 0;
177
+ }
178
+ };
179
+ let FunctionalReactive = _FunctionalReactive;
180
+ _b = isReactive$1;
181
+ _value2 = new WeakMap();
182
+ _reactions2 = new WeakMap();
183
+ _f = new WeakMap();
184
+ _depth = new WeakMap();
185
+ _derivatives = new WeakMap();
186
+ _settersQueue = new WeakMap();
187
+ _derivativesQueue = new WeakMap();
188
+ _reactionsQueue = new WeakMap();
189
+ _applyUpdate = new WeakSet();
190
+ applyUpdate_fn = function(newValue) {
191
+ if (newValue === __privateGet(this, _value2))
192
+ return;
193
+ __privateSet(this, _value2, newValue);
194
+ __privateGet(_FunctionalReactive, _reactionsQueue).push(...__privateGet(this, _reactions2));
195
+ const queue = __privateGet(_FunctionalReactive, _derivativesQueue);
196
+ for (const derivative of __privateGet(this, _derivatives)) {
197
+ const depth = __privateGet(derivative, _depth);
198
+ if (!queue[depth])
199
+ queue[depth] = new Set();
200
+ queue[depth].add(derivative);
201
+ }
202
+ };
203
+ __privateAdd(FunctionalReactive, _settersQueue, new Map());
204
+ __privateAdd(FunctionalReactive, _derivativesQueue, []);
205
+ __privateAdd(FunctionalReactive, _reactionsQueue, []);
206
+ const r = (x, f) => new FunctionalReactive(x, f);
207
+ const reactiveDo = (x, f) => {
208
+ if (x == null ? void 0 : x[isReactive$1]) {
209
+ f(x.value);
210
+ return x.addReaction(() => f(x.value));
211
+ }
212
+ f(x);
213
+ };
214
+ var index$1 = /* @__PURE__ */ Object.freeze({
215
+ __proto__: null,
216
+ [Symbol.toStringTag]: "Module",
217
+ SimpleReactive,
218
+ FunctionalReactive,
219
+ r,
220
+ reactiveDo
221
+ });
222
+ const pipe = (x, ...fs) => fs.reduce((y, f) => f(y), x);
223
+ const dispatch = (target, type, options) => target.dispatchEvent(new CustomEvent(type, __spreadValues({
224
+ bubbles: true,
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) => {
271
+ if (!child[isReactive])
272
+ return [toNode(child)];
273
+ if (Array.isArray(child.value)) {
274
+ const liveFragment2 = new LiveFragment();
275
+ child.addReaction(() => {
276
+ liveFragment2.replaceChildren(...childrenToNodes(child.value));
277
+ });
278
+ return [liveFragment2.startMarker, ...childrenToNodes(child.value), liveFragment2.endMarker];
279
+ }
280
+ let node = toNode(child.value);
281
+ child.addReaction(() => {
282
+ const oldNode = node;
283
+ node = toNode(child.value);
284
+ oldNode.replaceWith(node);
285
+ });
286
+ return [node];
287
+ });
288
+ class MetaTextNode {
289
+ constructor(textContent) {
290
+ __publicField(this, _c, true);
291
+ __publicField(this, _d, true);
292
+ __publicField(this, "node");
293
+ if (!textContent[isReactive]) {
294
+ this.node = document.createTextNode(textContent);
295
+ return;
296
+ }
297
+ this.node = document.createTextNode(textContent.value);
298
+ textContent.addReaction(() => {
299
+ this.node.textContent = textContent.value;
300
+ });
301
+ }
302
+ addProperties(properties = {}) {
303
+ Object.assign(this.node, properties);
304
+ return this;
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;
364
+ const hydrateTextNodes = () => {
365
+ const tagged = {};
366
+ const bruhTextNodes = document.getElementsByTagName("bruh-textnode");
367
+ for (const bruhTextNode of bruhTextNodes) {
368
+ const textNode = document.createTextNode(bruhTextNode.textContent);
369
+ if (bruhTextNode.dataset.tag)
370
+ tagged[bruhTextNode.dataset.tag] = textNode;
371
+ bruhTextNode.replaceWith(textNode);
372
+ }
373
+ return tagged;
374
+ };
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
+ var index_browser = /* @__PURE__ */ Object.freeze({
398
+ __proto__: null,
399
+ [Symbol.toStringTag]: "Module",
400
+ childrenToNodes,
401
+ MetaTextNode,
402
+ MetaElement,
403
+ hydrateTextNodes,
404
+ t: createMetaTextNode,
405
+ e: createMetaElement,
406
+ h: createMetaElementJSX,
407
+ JSXFragment
408
+ });
409
+ export { index_browser as dom, liveFragment, index$1 as reactive, index as util };
2
410
  //# 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/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 constructor() {\n this.startMarker = document.createTextNode(\"\")\n this.endMarker = document.createTextNode(\"\")\n }\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","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 #pendingUpdates = 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\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.#pendingUpdates.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.#pendingUpdates.size)\n queueMicrotask(FunctionalReactive.applyUpdates)\n\n FunctionalReactive.#pendingUpdates.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 for (const reaction of this.#reactions)\n reaction(newValue)\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.#pendingUpdates.size)\n return\n\n // Bootstrap by applying the updates from the pending source node updates\n for (const [sourceNode, newValue] of FunctionalReactive.#pendingUpdates.entries())\n sourceNode.#applyUpdate(newValue)\n\n FunctionalReactive.#pendingUpdates.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\n FunctionalReactive.#derivativesQueue.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","import { 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 // Everything else, as long as it isn't a function, can be a child when stringified\n typeof x !== \"function\"\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 constructor(textContent) {\n this[isMetaNode] =\n this[isMetaTextNode] = true\n\n if (textContent[isReactive]) {\n this.node = document.createTextNode(textContent.value)\n textContent.addReaction(() => {\n this.node.textContent = textContent.value\n })\n }\n else {\n this.node = document.createTextNode(textContent)\n }\n }\n\n addProperties(properties = {}) {\n Object.assign(this.node, properties)\n\n return this\n }\n}\n\nexport class MetaElement {\n constructor(name, namespace) {\n this[isMetaNode] =\n this[isMetaElement] = true\n\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 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":["constructor","startMarker","document","createTextNode","endMarker","firstNode","lastNode","liveFragment2","this","before","after","xs","prepend","append","remove","range","createRange","setStartBefore","setEndAfter","deleteContents","replaceChildren","setStartAfter","setEndBefore","replaceWith","childNodes","currentNode","nextSibling","push","filter","node","HTMLElement","isReactive","Symbol","for","_a","_value","_reactions","x","f","Set","_value2","_f","_depth","Math","max","map","__privateGet","forEach","_derivatives","add","_pendingUpdates","size","applyUpdates","newValue","_FunctionalReactive","set","addReaction","reaction","_reactions2","delete","sourceNode","entries","_applyUpdate","call","clear","depthSet","_derivativesQueue","derivative","length","_b","applyUpdate_fn","queue","depth","__privateAdd","FunctionalReactive","Map","reactiveDo","value","maybeDo","existsThen","emptyThen","Array","isArray","fs","reduce","y","target","type","options","dispatchEvent","CustomEvent","__spreadValues","bubbles","cancelable","composed","object","iterable","destructable","iterator","defineProperty","enumerable","Proxy","get","_","property","isMetaNode","isMetaTextNode","isMetaElement","toNode","Node","childrenToNodes","children","flat","Infinity","flatMap","child","LiveFragment","oldNode","textContent","addProperties","properties","assign","name","namespace","createElementNS","createElement","element","result","addAttributes","attributes","setAttribute","removeAttribute","addDataAttributes","dataAttributes","dataset","tagged","bruhTextNodes","getElementsByTagName","bruhTextNode","textNode","tag","MetaTextNode","variadic","meta","MetaElement","nameOrComponent","attributesOrProps","Object"],"mappings":"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"}
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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"}
package/dist/bruh.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- var __defProp=Object.defineProperty,__defProps=Object.defineProperties,__getOwnPropDescs=Object.getOwnPropertyDescriptors,__getOwnPropSymbols=Object.getOwnPropertySymbols,__hasOwnProp=Object.prototype.hasOwnProperty,__propIsEnum=Object.prototype.propertyIsEnumerable,__defNormalProp=(e,t,r)=>t in e?__defProp(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,__spreadValues=(e,t)=>{for(var r in t||(t={}))__hasOwnProp.call(t,r)&&__defNormalProp(e,r,t[r]);if(__getOwnPropSymbols)for(var r of __getOwnPropSymbols(t))__propIsEnum.call(t,r)&&__defNormalProp(e,r,t[r]);return e},__spreadProps=(e,t)=>__defProps(e,__getOwnPropDescs(t)),__publicField=(e,t,r)=>(__defNormalProp(e,"symbol"!=typeof t?t+"":t,r),r),__accessCheck=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)},__privateGet=(e,t,r)=>(__accessCheck(e,t,"read from private field"),r?r.call(e):t.get(e)),__privateAdd=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},__privateSet=(e,t,r,a)=>(__accessCheck(e,t,"write to private field"),a?a.call(e,r):t.set(e,r),r),__privateMethod=(e,t,r)=>(__accessCheck(e,t,"access private method"),r);!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).bruh={})}(this,(function(e){var t,r,a,o,i,n,s,d,_,p,c,l,h;class u{constructor(){this.startMarker=document.createTextNode(""),this.endMarker=document.createTextNode("")}static from(e,t){const r=new this;return e.before(r.startMarker),t.after(r.endMarker),r}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 f=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",LiveFragment:u});const v=Symbol.for("bruh reactive");t=v,r=new WeakMap,a=new WeakMap;const b=class{constructor(e,t){__privateAdd(this,l),__publicField(this,o,!0),__privateAdd(this,i,void 0),__privateAdd(this,n,new Set),__privateAdd(this,s,void 0),__privateAdd(this,d,0),__privateAdd(this,_,new Set),t?(__privateSet(this,i,t()),__privateSet(this,s,t),__privateSet(this,d,Math.max(...e.map((e=>__privateGet(e,d))))+1),e.forEach((e=>__privateGet(e,_).add(this)))):__privateSet(this,i,e)}get value(){return __privateGet(b,p).size&&b.applyUpdates(),__privateGet(this,i)}set value(e){0===__privateGet(this,d)&&(__privateGet(b,p).size||queueMicrotask(b.applyUpdates),__privateGet(b,p).set(this,e))}addReaction(e){return __privateGet(this,n).add(e),()=>__privateGet(this,n).delete(e)}static applyUpdates(){var e,t,r;if(__privateGet(b,p).size){for(const[t,r]of __privateGet(b,p).entries())__privateMethod(e=t,l,h).call(e,r);__privateGet(b,p).clear();for(const e of __privateGet(b,c))if(e)for(const a of e)__privateMethod(r=a,l,h).call(r,__privateGet(t=a,s).call(t));__privateGet(b,c).length=0}}};let m=b;o=v,i=new WeakMap,n=new WeakMap,s=new WeakMap,d=new WeakMap,_=new WeakMap,p=new WeakMap,c=new WeakMap,l=new WeakSet,h=function(e){if(e===__privateGet(this,i))return;__privateSet(this,i,e);for(const r of __privateGet(this,n))r(e);const t=__privateGet(b,c);for(const r of __privateGet(this,_)){const e=__privateGet(r,d);t[e]||(t[e]=new Set),t[e].add(r)}},__privateAdd(m,p,new Map),__privateAdd(m,c,[]);const y=(e,t)=>{if(null==e?void 0:e[v])return t(e.value),e.addReaction((()=>t(e.value)));t(e)};var g=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",SimpleReactive:class{constructor(e){__publicField(this,t,!0),__privateAdd(this,r,void 0),__privateAdd(this,a,new Set),__privateSet(this,r,e)}get value(){return __privateGet(this,r)}set value(e){if(e!==__privateGet(this,r)){__privateSet(this,r,e);for(const e of __privateGet(this,a))e()}}addReaction(e){return __privateGet(this,a).add(e),()=>__privateGet(this,a).delete(e)}},FunctionalReactive:m,r:(e,t)=>new m(e,t),reactiveDo:y});const M=(e,t)=>r=>{Array.isArray(r)?r.length?e(r[0]):t():e(r)};var S=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",pipe:(e,...t)=>t.reduce(((e,t)=>t(e)),e),dispatch:(e,t,r)=>e.dispatchEvent(new CustomEvent(t,__spreadValues({bubbles:!0,cancelable:!0,composed:!0},r))),createDestructable:(e,t)=>{const r=__spreadProps(__spreadValues({},e),{[Symbol.iterator]:()=>t[Symbol.iterator]()});return Object.defineProperty(r,Symbol.iterator,{enumerable:!1}),r},maybeDo:M,functionAsObject:e=>new Proxy({},{get:(t,r)=>e(r)})});const w=Symbol.for("bruh reactive"),k=Symbol.for("bruh meta node"),P=Symbol.for("bruh meta text node"),A=Symbol.for("bruh meta element"),G=e=>e[k]?e.node:e instanceof Node?e:document.createTextNode(e),O=e=>e.flat(1/0).flatMap((e=>{if(!e[w])return[G(e)];if(Array.isArray(e.value)){const t=new u;return e.addReaction((()=>{t.replaceChildren(...O(e.value))})),[t.startMarker,...O(e.value),t.endMarker]}let t=G(e.value);return e.addReaction((()=>{const r=t;t=G(e.value),r.replaceWith(t)})),[t]}));class T{constructor(e){this[k]=this[P]=!0,e[w]?(this.node=document.createTextNode(e.value),e.addReaction((()=>{this.node.textContent=e.value}))):this.node=document.createTextNode(e)}addProperties(e={}){return Object.assign(this.node,e),this}}class x{constructor(e,t){this[k]=this[A]=!0,this.node=t?document.createElementNS(t,e):document.createElement(e)}static from(e){const t=new this("div");return t.node=e,t}addProperties(e={}){return Object.assign(this.node,e),this}addAttributes(e={}){for(const t in e)y(e[t],M((e=>this.node.setAttribute(t,e)),(()=>this.node.removeAttribute(t))));return this}addDataAttributes(e={}){for(const t in e)y(e[t],M((e=>this.node.dataset[t]=e),(()=>delete this.node.dataset[t])));return this}before(...e){this.node.before(...O(e))}prepend(...e){this.node.prepend(...O(e))}append(...e){this.node.append(...O(e))}after(...e){this.node.after(...O(e))}replaceChildren(...e){this.node.replaceChildren(...O(e))}replaceWith(...e){this.node.replaceWith(...O(e))}}var N=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",childrenToNodes:O,MetaTextNode:T,MetaElement:x,hydrateTextNodes:()=>{const e={},t=document.getElementsByTagName("bruh-textnode");for(const r of t){const t=document.createTextNode(r.textContent);r.dataset.tag&&(e[r.dataset.tag]=t),r.replaceWith(t)}return e},t:e=>new T(e),e:(e,t)=>(...r)=>{const a=new x(e,t);if((null==(o=r[0])?void 0:o[k])||(null==o?void 0:o[w])||o instanceof Node||Array.isArray(o)||"function"!=typeof o)a.append(r);else{const[e,...t]=r;a.addAttributes(e),a.append(t)}var o;return a},h:(e,t,...r)=>{if("string"==typeof e){const a=new x(e);return a.addAttributes(t||{}),a.append(r),a}return e(Object.assign({},t,{children:r}))},JSXFragment:({children:e})=>e});e.dom=N,e.liveFragment=f,e.reactive=g,e.util=S,Object.defineProperty(e,"__esModule",{value:!0}),e[Symbol.toStringTag]="Module"}));
1
+ var se=Object.defineProperty,ae=Object.defineProperties;var ie=Object.getOwnPropertyDescriptors;var U=Object.getOwnPropertySymbols;var de=Object.prototype.hasOwnProperty,ce=Object.prototype.propertyIsEnumerable;var P=(o,s,i)=>s in o?se(o,s,{enumerable:!0,configurable:!0,writable:!0,value:i}):o[s]=i,_=(o,s)=>{for(var i in s||(s={}))de.call(s,i)&&P(o,i,s[i]);if(U)for(var i of U(s))ce.call(s,i)&&P(o,i,s[i]);return o},B=(o,s)=>ae(o,ie(s));var l=(o,s,i)=>(P(o,typeof s!="symbol"?s+"":s,i),i),C=(o,s,i)=>{if(!s.has(o))throw TypeError("Cannot "+i)};var a=(o,s,i)=>(C(o,s,"read from private field"),i?i.call(o):s.get(o)),u=(o,s,i)=>{if(s.has(o))throw TypeError("Cannot add the same private member more than once");s instanceof WeakSet?s.add(o):s.set(o,i)},m=(o,s,i,v)=>(C(o,s,"write to private field"),v?v.call(o,i):s.set(o,i),i);var W=(o,s,i)=>(C(o,s,"access private method"),i);(function(o,s){typeof exports=="object"&&typeof module!="undefined"?s(exports):typeof define=="function"&&define.amd?define(["exports"],s):(o=typeof globalThis!="undefined"?globalThis:o||self,s(o.bruh={}))})(this,function(o){var ue,b,M,le,p,S,w,g,E,f,N,T,j,J,he,fe,pe,me;"use strict";class s{constructor(){l(this,"startMarker",document.createTextNode(""));l(this,"endMarker",document.createTextNode(""))}static from(e,t){const n=new this;return e.before(n.startMarker),t.after(n.endMarker),n}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 v=Symbol.for("bruh reactive");class Q{constructor(e){l(this,ue,!0);u(this,b,void 0);u(this,M,new Set);m(this,b,e)}get value(){return a(this,b)}set value(e){if(e!==a(this,b)){m(this,b,e);for(const t of a(this,M))t()}}addReaction(e){return a(this,M).add(e),()=>a(this,M).delete(e)}}ue=v,b=new WeakMap,M=new WeakMap;const d=class{constructor(e,t){u(this,j);l(this,le,!0);u(this,p,void 0);u(this,S,new Set);u(this,w,void 0);u(this,g,0);u(this,E,new Set);if(!t){m(this,p,e);return}m(this,p,t()),m(this,w,t),m(this,g,Math.max(...e.map(n=>a(n,g)))+1),e.forEach(n=>a(n,E).add(this))}get value(){return a(d,f).size&&d.applyUpdates(),a(this,p)}set value(e){a(this,g)===0&&(a(d,f).size||queueMicrotask(d.applyUpdates),a(d,f).set(this,e))}addReaction(e){return a(this,S).add(e),()=>a(this,S).delete(e)}static applyUpdates(){var e,t,n;if(!!a(d,f).size){for(const[c,k]of a(d,f).entries())W(e=c,j,J).call(e,k);a(d,f).clear();for(const c of a(d,N))if(c)for(const k of c)W(n=k,j,J).call(n,a(t=k,w).call(t));a(d,N).length=0;for(const c of a(d,T))c();a(d,T).length=0}}};let y=d;le=v,p=new WeakMap,S=new WeakMap,w=new WeakMap,g=new WeakMap,E=new WeakMap,f=new WeakMap,N=new WeakMap,T=new WeakMap,j=new WeakSet,J=function(e){if(e===a(this,p))return;m(this,p,e),a(d,T).push(...a(this,S));const t=a(d,N);for(const n of a(this,E)){const c=a(n,g);t[c]||(t[c]=new Set),t[c].add(n)}},u(y,f,new Map),u(y,N,[]),u(y,T,[]);const X=(r,e)=>new y(r,e),A=(r,e)=>{if(r==null?void 0:r[v])return e(r.value),r.addReaction(()=>e(r.value));e(r)};var q=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",SimpleReactive:Q,FunctionalReactive:y,r:X,reactiveDo:A});const $=(r,...e)=>e.reduce((t,n)=>n(t),r),H=(r,e,t)=>r.dispatchEvent(new CustomEvent(e,_({bubbles:!0,cancelable:!0,composed:!0},t))),I=(r,e)=>{const t=B(_({},r),{[Symbol.iterator]:()=>e[Symbol.iterator]()});return Object.defineProperty(t,Symbol.iterator,{enumerable:!1}),t},R=(r,e)=>t=>{Array.isArray(t)?t.length?r(t[0]):e():r(t)},G=r=>new Proxy({},{get:(e,t)=>r(t)});var K=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",pipe:$,dispatch:H,createDestructable:I,maybeDo:R,functionAsObject:G});const z=Symbol.for("bruh reactive"),O=Symbol.for("bruh meta node"),Y=Symbol.for("bruh meta text node"),Z=Symbol.for("bruh meta element"),V=r=>(r==null?void 0:r[O])||(r==null?void 0:r[z])||r instanceof Node||Array.isArray(r)||r==null||!(typeof r=="function"||typeof r=="object"),D=r=>r[O]?r.node:r instanceof Node?r:document.createTextNode(r),h=r=>r.flat(1/0).flatMap(e=>{if(!e[z])return[D(e)];if(Array.isArray(e.value)){const n=new s;return e.addReaction(()=>{n.replaceChildren(...h(e.value))}),[n.startMarker,...h(e.value),n.endMarker]}let t=D(e.value);return e.addReaction(()=>{const n=t;t=D(e.value),n.replaceWith(t)}),[t]});class L{constructor(e){l(this,he,!0);l(this,fe,!0);l(this,"node");if(!e[z]){this.node=document.createTextNode(e);return}this.node=document.createTextNode(e.value),e.addReaction(()=>{this.node.textContent=e.value})}addProperties(e={}){return Object.assign(this.node,e),this}}he=O,fe=Y;class F{constructor(e,t){l(this,pe,!0);l(this,me,!0);l(this,"node");this.node=t?document.createElementNS(t,e):document.createElement(e)}static from(e){const t=new this("div");return t.node=e,t}addProperties(e={}){return Object.assign(this.node,e),this}addAttributes(e={}){for(const t in e)A(e[t],R(n=>this.node.setAttribute(t,n),()=>this.node.removeAttribute(t)));return this}addDataAttributes(e={}){for(const t in e)A(e[t],R(n=>this.node.dataset[t]=n,()=>delete this.node.dataset[t]));return this}addStyles(e={}){for(const t in e)A(e[t],R(n=>this.node.style.setProperty(t,n),()=>this.node.style.removeProperty(t)));return this}toggleClasses(e={}){for(const t in e)A(e[t],n=>this.node.classList.toggle(t,n));return this}before(...e){this.node.before(...h(e))}prepend(...e){this.node.prepend(...h(e))}append(...e){this.node.append(...h(e))}after(...e){this.node.after(...h(e))}replaceChildren(...e){this.node.replaceChildren(...h(e))}replaceWith(...e){this.node.replaceWith(...h(e))}}pe=O,me=Z;const x=()=>{const r={},e=document.getElementsByTagName("bruh-textnode");for(const t of e){const n=document.createTextNode(t.textContent);t.dataset.tag&&(r[t.dataset.tag]=n),t.replaceWith(n)}return r},ee=r=>new L(r),te=(r,e)=>(...t)=>{const n=new F(r,e);if(V(t[0]))n.append(t);else{const[c,...k]=t;n.addAttributes(c),n.append(k)}return n},re=(r,e,...t)=>{if(typeof r=="string"){const n=new F(r);return n.addAttributes(e||{}),n.append(t),n}return r(Object.assign({},e,{children:t}))},ne=({children:r})=>r;var oe=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",childrenToNodes:h,MetaTextNode:L,MetaElement:F,hydrateTextNodes:x,t:ee,e:te,h:re,JSXFragment:ne});o.dom=oe,o.liveFragment=i,o.reactive=q,o.util=K,Object.defineProperty(o,"__esModule",{value:!0}),o[Symbol.toStringTag]="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/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 constructor() {\n this.startMarker = document.createTextNode(\"\")\n this.endMarker = document.createTextNode(\"\")\n }\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","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 #pendingUpdates = 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\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.#pendingUpdates.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.#pendingUpdates.size)\n queueMicrotask(FunctionalReactive.applyUpdates)\n\n FunctionalReactive.#pendingUpdates.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 for (const reaction of this.#reactions)\n reaction(newValue)\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.#pendingUpdates.size)\n return\n\n // Bootstrap by applying the updates from the pending source node updates\n for (const [sourceNode, newValue] of FunctionalReactive.#pendingUpdates.entries())\n sourceNode.#applyUpdate(newValue)\n\n FunctionalReactive.#pendingUpdates.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\n FunctionalReactive.#derivativesQueue.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","import { 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 // Everything else, as long as it isn't a function, can be a child when stringified\n typeof x !== \"function\"\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 constructor(textContent) {\n this[isMetaNode] =\n this[isMetaTextNode] = true\n\n if (textContent[isReactive]) {\n this.node = document.createTextNode(textContent.value)\n textContent.addReaction(() => {\n this.node.textContent = textContent.value\n })\n }\n else {\n this.node = document.createTextNode(textContent)\n }\n }\n\n addProperties(properties = {}) {\n Object.assign(this.node, properties)\n\n return this\n }\n}\n\nexport class MetaElement {\n constructor(name, namespace) {\n this[isMetaNode] =\n this[isMetaElement] = true\n\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 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":["constructor","startMarker","document","createTextNode","endMarker","firstNode","lastNode","liveFragment2","this","before","after","xs","prepend","append","remove","range","createRange","setStartBefore","setEndAfter","deleteContents","replaceChildren","setStartAfter","setEndBefore","replaceWith","childNodes","currentNode","nextSibling","push","filter","node","HTMLElement","isReactive","Symbol","for","x","f","Set","_value2","_f","_depth","Math","max","map","__privateGet","forEach","_derivatives","add","_pendingUpdates","size","applyUpdates","newValue","_FunctionalReactive","set","addReaction","reaction","_reactions2","delete","sourceNode","entries","_applyUpdate","call","clear","depthSet","_derivativesQueue","derivative","length","queue","depth","FunctionalReactive","Map","reactiveDo","value","_value","_reactions","maybeDo","existsThen","emptyThen","Array","isArray","fs","reduce","y","target","type","options","dispatchEvent","CustomEvent","__spreadValues","bubbles","cancelable","composed","object","iterable","destructable","__spreadProps","iterator","defineProperty","enumerable","Proxy","get","_","property","isMetaNode","isMetaTextNode","isMetaElement","toNode","Node","childrenToNodes","children","flat","Infinity","flatMap","child","LiveFragment","oldNode","textContent","addProperties","properties","assign","name","namespace","createElementNS","createElement","element","result","addAttributes","attributes","setAttribute","removeAttribute","addDataAttributes","dataAttributes","dataset","tagged","bruhTextNodes","getElementsByTagName","bruhTextNode","textNode","tag","MetaTextNode","variadic","meta","MetaElement","nameOrComponent","attributesOrProps","Object"],"mappings":"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"}
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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"}
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "library",
11
11
  "modern"
12
12
  ],
13
- "version": "1.8.0",
13
+ "version": "1.9.2-types.0",
14
14
  "license": "MIT",
15
15
  "author": {
16
16
  "name": "Daniel Ethridge",
@@ -1,4 +1,7 @@
1
- import { picture, source, img } from "bruh/dom/html"
1
+ import { e } from "bruh/dom"
2
+ import { functionAsObject } from "bruh/util"
3
+ const { picture, source, img } = functionAsObject(e)
4
+
2
5
  import { readFile } from "fs/promises"
3
6
 
4
7
  export default async options => {
@@ -0,0 +1,113 @@
1
+ import { Reactive } from "../reactive"
2
+
3
+ declare type MaybeReactiveRecord<T> = Record<string, T | Reactive<T>>
4
+
5
+ declare const isReactive: unique symbol
6
+ declare const isMetaNode: unique symbol
7
+ declare const isMetaTextNode: unique symbol
8
+ declare const isMetaElement: unique symbol
9
+
10
+ declare type Stringifyable = { toString: () => string }
11
+
12
+ declare type NonReactiveMetaNodeChild =
13
+ | MetaNode
14
+ | Node
15
+ | string
16
+ | number
17
+ | Array<NonReactiveMetaNodeChild>
18
+
19
+ export declare type MetaNodeChild =
20
+ | NonReactiveMetaNodeChild
21
+ | Reactive<NonReactiveMetaNodeChild>
22
+
23
+ export declare type childrenToNodes = (children: Array<MetaNodeChild>) => Array<Node>
24
+
25
+ export declare type MetaNode = {
26
+ [isMetaNode]: true
27
+ node: Node
28
+ addProperties: (properties: object) => MetaNode
29
+ }
30
+
31
+ export declare class MetaTextNode implements MetaNode {
32
+ constructor(value: string)
33
+
34
+ [isMetaNode]: true
35
+ [isMetaTextNode]: true
36
+ node: Text
37
+ addProperties: (properties: object) => MetaNode
38
+ }
39
+
40
+ export declare class MetaElement implements MetaNode {
41
+ constructor(name: string, namespace?: string)
42
+
43
+ static from: (element: Element) => MetaElement
44
+
45
+ [isMetaNode]: true
46
+ [isMetaElement]: true
47
+ node: Element
48
+ addProperties: (properties: object) => MetaNode
49
+
50
+ addAttributes: (attributes: MaybeReactiveRecord<Stringifyable | void>) => MetaNode
51
+ addDataAttributes: (dataAttributes: MaybeReactiveRecord<Stringifyable | void>) => MetaNode
52
+ addStyles: (styles: MaybeReactiveRecord<Stringifyable | void>) => MetaNode
53
+ toggleClasses: (classes: MaybeReactiveRecord<boolean>) => MetaNode
54
+
55
+ before: (...children: Array<MetaNodeChild>) => MetaNode
56
+ prepend: (...children: Array<MetaNodeChild>) => MetaNode
57
+ append: (...children: Array<MetaNodeChild>) => MetaNode
58
+ after: (...children: Array<MetaNodeChild>) => MetaNode
59
+ replaceChildren: (...children: Array<MetaNodeChild>) => MetaNode
60
+ replaceWith: (...children: Array<MetaNodeChild>) => MetaNode
61
+ }
62
+
63
+ export declare class MetaHTMLElement<Name extends keyof HTMLElementTagNameMap> extends MetaElement {
64
+ constructor(name: Name, namespace?: "http://www.w3.org/1999/xhtml")
65
+ node: HTMLElementTagNameMap[Name]
66
+ }
67
+ export declare class MetaSVGElement<Name extends keyof SVGElementTagNameMap> extends MetaElement {
68
+ constructor(name: Name, namespace: "http://www.w3.org/2000/svg")
69
+ node: SVGElementTagNameMap[Name]
70
+ }
71
+
72
+ export declare const hydrateTextNodes: () => Record<string, Text>
73
+
74
+ declare const createMetaTextNode: (value: string) => MetaTextNode
75
+
76
+ declare const createMetaElement: {
77
+ <Name extends keyof HTMLElementTagNameMap>
78
+ (name: Name, namespace?: "http://www.w3.org/1999/xhtml"): {
79
+ ( ...children: Array<MetaNodeChild>): MetaHTMLElement<Name>
80
+ (attributes: MaybeReactiveRecord<Stringifyable | void>, ...children: Array<MetaNodeChild>): MetaHTMLElement<Name>
81
+ }
82
+
83
+ <Name extends keyof SVGElementTagNameMap>
84
+ (name: Name, namespace: "http://www.w3.org/2000/svg"): {
85
+ ( ...children: Array<MetaNodeChild>): MetaSVGElement<Name>
86
+ (attributes: MaybeReactiveRecord<Stringifyable | void>, ...children: Array<MetaNodeChild>): MetaSVGElement<Name>
87
+ }
88
+
89
+ (name: string, namespace?: string): {
90
+ ( ...children: Array<MetaNodeChild>): MetaNode
91
+ (attributes: MaybeReactiveRecord<Stringifyable | void>, ...children: Array<MetaNodeChild>): MetaNode
92
+ }
93
+ }
94
+
95
+ declare const createMetaElementJSX: {
96
+ <Name extends keyof HTMLElementTagNameMap>
97
+ (name: Name, attributes: MaybeReactiveRecord<Stringifyable | void>, ...children: Array<MetaNodeChild>): MetaHTMLElement<Name>
98
+
99
+ <Props, Child, ReturnType>
100
+ (
101
+ component: (propsAndChildren: Props & { children: Array<Child> }) => ReturnType,
102
+ props: Props,
103
+ ...children: Array<Child>
104
+ ): ReturnType
105
+ }
106
+
107
+ export {
108
+ createMetaTextNode as t,
109
+ createMetaElement as e,
110
+ createMetaElementJSX as h
111
+ }
112
+
113
+ declare const JSXFragment: <Child>(argument: { children: Array<Child> }) => Array<Child>
@@ -1,3 +1,5 @@
1
+ /** @typedef { import("./index.browser") } */
2
+
1
3
  import { LiveFragment } from "./live-fragment.mjs"
2
4
  import { reactiveDo } from "../reactive/index.mjs"
3
5
  import { maybeDo } from "../util/index.mjs"
@@ -16,8 +18,11 @@ const isMetaNodeChild = x =>
16
18
  x instanceof Node ||
17
19
  // Any array, just assume it contains valid children
18
20
  Array.isArray(x) ||
19
- // Everything else, as long as it isn't a function, can be a child when stringified
20
- typeof x !== "function"
21
+ // Allow nullish
22
+ x == null ||
23
+ // Disallow functions and objects
24
+ !(typeof x === "function" || typeof x === "object")
25
+ // Everything else can be a child when stringified
21
26
 
22
27
  const toNode = x => {
23
28
  if (x[isMetaNode])
@@ -58,19 +63,21 @@ export const childrenToNodes = children =>
58
63
  // Meta Nodes
59
64
 
60
65
  export class MetaTextNode {
61
- constructor(textContent) {
62
- this[isMetaNode] =
63
- this[isMetaTextNode] = true
66
+ [isMetaNode] = true;
67
+ [isMetaTextNode] = true
64
68
 
65
- if (textContent[isReactive]) {
66
- this.node = document.createTextNode(textContent.value)
67
- textContent.addReaction(() => {
68
- this.node.textContent = textContent.value
69
- })
70
- }
71
- else {
69
+ node
70
+
71
+ constructor(textContent) {
72
+ if (!textContent[isReactive]) {
72
73
  this.node = document.createTextNode(textContent)
74
+ return
73
75
  }
76
+
77
+ this.node = document.createTextNode(textContent.value)
78
+ textContent.addReaction(() => {
79
+ this.node.textContent = textContent.value
80
+ })
74
81
  }
75
82
 
76
83
  addProperties(properties = {}) {
@@ -81,10 +88,12 @@ export class MetaTextNode {
81
88
  }
82
89
 
83
90
  export class MetaElement {
84
- constructor(name, namespace) {
85
- this[isMetaNode] =
86
- this[isMetaElement] = true
91
+ [isMetaNode] = true;
92
+ [isMetaElement] = true
87
93
 
94
+ node
95
+
96
+ constructor(name, namespace) {
88
97
  this.node =
89
98
  namespace
90
99
  ? document.createElementNS(namespace, name)
@@ -127,6 +136,27 @@ export class MetaElement {
127
136
  return this
128
137
  }
129
138
 
139
+ addStyles(styles = {}) {
140
+ for (const property in styles)
141
+ reactiveDo(styles[property],
142
+ maybeDo(
143
+ value => this.node.style.setProperty (property, value),
144
+ () => this.node.style.removeProperty(property)
145
+ )
146
+ )
147
+
148
+ return this
149
+ }
150
+
151
+ toggleClasses(classes = {}) {
152
+ for (const name in classes)
153
+ reactiveDo(classes[name],
154
+ value => this.node.classList.toggle(name, value)
155
+ )
156
+
157
+ return this
158
+ }
159
+
130
160
  before(...xs) {
131
161
  this.node.before(...childrenToNodes(xs))
132
162
  }
@@ -50,19 +50,24 @@ const isMetaNodeChild = x =>
50
50
  x?.[isMetaRawString] ||
51
51
  // Any array, just assume it contains valid children
52
52
  Array.isArray(x) ||
53
- // Everything else, as long as it isn't a function, can be a child when stringified
54
- typeof x !== "function"
53
+ // Allow nullish
54
+ x == null ||
55
+ // Disallow functions and objects
56
+ !(typeof x === "function" || typeof x === "object")
57
+ // Everything else can be a child when stringified
55
58
 
56
59
 
57
60
  // Meta Nodes
58
61
 
59
62
  export class MetaTextNode {
60
- constructor(textContent) {
61
- this[isMetaNode] =
62
- this[isMetaTextNode] = true
63
+ [isMetaNode] = true;
64
+ [isMetaTextNode] = true
65
+
66
+ textContent
67
+ tag
63
68
 
69
+ constructor(textContent) {
64
70
  this.textContent = textContent
65
- this.tag = undefined
66
71
  }
67
72
 
68
73
  toString() {
@@ -81,29 +86,21 @@ export class MetaTextNode {
81
86
  }
82
87
 
83
88
  export class MetaElement {
84
- constructor(name) {
85
- this[isMetaNode] =
86
- this[isMetaElement] = true
89
+ [isMetaNode] = true;
90
+ [isMetaElement] = true
87
91
 
88
- this.name = name
89
- this.children = []
92
+ name
93
+ attributes = {}
94
+ children = []
90
95
 
91
- this.attributes = {}
92
- this.dataset = {}
96
+ constructor(name) {
97
+ this.name = name
93
98
  }
94
99
 
95
100
  toString() {
96
101
  // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
97
102
  const attributes =
98
- [
99
- ...Object.entries(this.attributes),
100
- ...Object.entries(this.dataset)
101
- .map(([name, value]) => {
102
- // https://html.spec.whatwg.org/multipage/dom.html#dom-domstringmap-setitem
103
- const skewered = name.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`)
104
- return [`data-${skewered}`, value]
105
- })
106
- ]
103
+ Object.entries(this.attributes)
107
104
  .map(([name, value]) =>
108
105
  value === ""
109
106
  ? ` ${name}`
@@ -135,15 +132,64 @@ export class MetaElement {
135
132
  }
136
133
 
137
134
  addDataAttributes(dataAttributes = {}) {
138
- Object.assign(this.dataset, dataAttributes)
135
+ Object.entries(dataAttributes)
136
+ .forEach(([name, value]) => {
137
+ // https://html.spec.whatwg.org/multipage/dom.html#dom-domstringmap-setitem
138
+ const skewered = name.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`)
139
+ this.attributes[`data-${skewered}`] = value
140
+ })
141
+
142
+ return this
143
+ }
144
+
145
+ addStyles(styles = {}) {
146
+ // Doesn't support proper escaping
147
+ // https://www.w3.org/TR/css-syntax-3/#ref-for-parse-a-list-of-declarations%E2%91%A0
148
+ // https://www.w3.org/TR/css-syntax-3/#typedef-ident-token
149
+ const currentStyles = Object.fromEntries(
150
+ (this.attributes.style || "")
151
+ .split(";").filter(s => s.length)
152
+ .map(declaration => declaration.split(":").map(s => s.trim()))
153
+ )
154
+
155
+ Object.assign(currentStyles, styles)
156
+
157
+ this.attributes.style =
158
+ Object.entries(currentStyles)
159
+ .map(([property, value]) => `${property}:${value}`)
160
+ .join(";")
161
+
162
+ return this
163
+ }
164
+
165
+ toggleClasses(classes = {}) {
166
+ // Doesn't support proper escaping
167
+ // https://html.spec.whatwg.org/multipage/dom.html#global-attributes:classes-2
168
+ const classList = new Set(
169
+ (this.attributes.class || "")
170
+ .split(/\s+/).filter(s => s.length)
171
+ )
172
+
173
+ Object.entries(classes)
174
+ .forEach(([name, value]) => {
175
+ if (value)
176
+ classList.add(name)
177
+ else
178
+ classList.delete(name)
179
+ })
180
+
181
+ this.attributes.class = Array.from(classList).join(" ")
139
182
 
140
183
  return this
141
184
  }
142
185
  }
143
186
 
144
187
  export class MetaRawString {
188
+ [isMetaRawString] = true
189
+
190
+ string
191
+
145
192
  constructor(string) {
146
- this[isMetaRawString] = true
147
193
  this.string = string
148
194
  }
149
195
 
@@ -9,10 +9,8 @@
9
9
  // Also, make sure not to call .normalize() on the parent element,
10
10
  // because that would ruin the placeholders.
11
11
  export class LiveFragment {
12
- constructor() {
13
- this.startMarker = document.createTextNode("")
14
- this.endMarker = document.createTextNode("")
15
- }
12
+ startMarker = document.createTextNode("")
13
+ endMarker = document.createTextNode("")
16
14
 
17
15
  static from(firstNode, lastNode) {
18
16
  const liveFragment = new this()
@@ -1,4 +1,4 @@
1
- export declare const isReactive: unique symbol
1
+ declare const isReactive: unique symbol
2
2
 
3
3
  export declare type Reactive<T> = {
4
4
  [isReactive]: true
@@ -6,11 +6,6 @@ export declare type Reactive<T> = {
6
6
  addReaction: (reaction: Function) => Function
7
7
  }
8
8
 
9
- export declare const reactiveDo: {
10
- <T>(reactive: Reactive<T>, f: (value: T) => unknown): Function
11
- <T>(value: T, f: (value: T) => unknown): void
12
- }
13
-
14
9
  export declare class SimpleReactive<T> implements Reactive<T> {
15
10
  constructor(value: T)
16
11
 
@@ -22,10 +17,20 @@ export declare class SimpleReactive<T> implements Reactive<T> {
22
17
 
23
18
  export declare class FunctionalReactive<T> implements Reactive<T> {
24
19
  constructor(value: T)
25
- constructor(dependencies: Iterable<FunctionalReactive<unknown>>, f: () => T)
20
+ constructor(dependencies: Array<FunctionalReactive<unknown>>, f: () => T)
26
21
 
27
22
  [isReactive]: true
28
23
  get value(): T
29
24
  set value(newValue: T)
30
25
  addReaction(reaction: Function): () => boolean
31
26
  }
27
+
28
+ export declare const r: {
29
+ <T>(value: T): FunctionalReactive<T>
30
+ <T>(dependencies: Array<FunctionalReactive<unknown>>, f: () => T): FunctionalReactive<T>
31
+ }
32
+
33
+ export declare const reactiveDo: {
34
+ <T>(reactive: Reactive<T>, f: (value: T) => unknown): Function
35
+ <T>(value: T, f: (value: T) => unknown): void
36
+ }
@@ -1,3 +1,5 @@
1
+ /** @typedef { import("./index") } */
2
+
1
3
  const isReactive = Symbol.for("bruh reactive")
2
4
 
3
5
  // A super simple and performant reactive value implementation
@@ -49,10 +51,12 @@ export class FunctionalReactive {
49
51
  #derivatives = new Set()
50
52
 
51
53
  // Keep track of all the pending changes from the value setter
52
- static #pendingUpdates = new Map()
54
+ static #settersQueue = new Map()
53
55
  // A queue of derivatives to potentially update, sorted into sets by depth
54
56
  // This starts with depth 1 and can potentially have holes
55
57
  static #derivativesQueue = []
58
+ // A queue of reactions to run after the graph is fully updated
59
+ static #reactionsQueue = []
56
60
 
57
61
  constructor(x, f) {
58
62
  if (!f) {
@@ -70,7 +74,7 @@ export class FunctionalReactive {
70
74
  get value() {
71
75
  // If there are any pending updates, go ahead and apply them first
72
76
  // It's ok that there's already a microtask queued for this
73
- if (FunctionalReactive.#pendingUpdates.size)
77
+ if (FunctionalReactive.#settersQueue.size)
74
78
  FunctionalReactive.applyUpdates()
75
79
 
76
80
  return this.#value
@@ -82,10 +86,10 @@ export class FunctionalReactive {
82
86
  return
83
87
 
84
88
  // Unless asked for earlier, these updates are just queued up until the microtasks run
85
- if (!FunctionalReactive.#pendingUpdates.size)
89
+ if (!FunctionalReactive.#settersQueue.size)
86
90
  queueMicrotask(FunctionalReactive.applyUpdates)
87
91
 
88
- FunctionalReactive.#pendingUpdates.set(this, newValue)
92
+ FunctionalReactive.#settersQueue.set(this, newValue)
89
93
  }
90
94
 
91
95
  addReaction(reaction) {
@@ -101,8 +105,7 @@ export class FunctionalReactive {
101
105
  return
102
106
 
103
107
  this.#value = newValue
104
- for (const reaction of this.#reactions)
105
- reaction(newValue)
108
+ FunctionalReactive.#reactionsQueue.push(...this.#reactions)
106
109
 
107
110
  const queue = FunctionalReactive.#derivativesQueue
108
111
  for (const derivative of this.#derivatives) {
@@ -116,22 +119,25 @@ export class FunctionalReactive {
116
119
 
117
120
  // Apply pending updates from actually changed source nodes
118
121
  static applyUpdates() {
119
- if (!FunctionalReactive.#pendingUpdates.size)
122
+ if (!FunctionalReactive.#settersQueue.size)
120
123
  return
121
124
 
122
- // Bootstrap by applying the updates from the pending source node updates
123
- for (const [sourceNode, newValue] of FunctionalReactive.#pendingUpdates.entries())
125
+ // Bootstrap by applying the updates from the pending setters
126
+ for (const [sourceNode, newValue] of FunctionalReactive.#settersQueue.entries())
124
127
  sourceNode.#applyUpdate(newValue)
125
-
126
- FunctionalReactive.#pendingUpdates.clear()
128
+ FunctionalReactive.#settersQueue.clear()
127
129
 
128
130
  // Iterate down the depths, ignoring holes
129
131
  // Note that both the queue (Array) and each depth Set iterators update as items are added
130
132
  for (const depthSet of FunctionalReactive.#derivativesQueue) if (depthSet)
131
133
  for (const derivative of depthSet)
132
134
  derivative.#applyUpdate(derivative.#f())
133
-
134
135
  FunctionalReactive.#derivativesQueue.length = 0
136
+
137
+ // Call all reactions now that the graph has a fully consistent state
138
+ for (const reaction of FunctionalReactive.#reactionsQueue)
139
+ reaction()
140
+ FunctionalReactive.#reactionsQueue.length = 0
135
141
  }
136
142
  }
137
143