native-document 1.0.13 → 1.0.14

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.
@@ -193,11 +193,15 @@ var NativeDocument = (function (exports) {
193
193
  function ObservableChecker($observable, $checker) {
194
194
  this.observable = $observable;
195
195
  this.checker = $checker;
196
+ const $unSubscriptions = [];
196
197
 
197
198
  this.subscribe = function(callback) {
198
- return $observable.subscribe((value) => {
199
+ const unSubscribe = $observable.subscribe((value) => {
199
200
  callback && callback($checker(value));
200
201
  });
202
+ $unSubscriptions.push(unSubscribe);
203
+
204
+ return unSubscribe;
201
205
  };
202
206
 
203
207
  this.val = function() {
@@ -215,7 +219,7 @@ var NativeDocument = (function (exports) {
215
219
  };
216
220
 
217
221
  this.cleanup = function() {
218
- return $observable.cleanup();
222
+ $unSubscriptions.forEach(unSubscription => unSubscription());
219
223
  };
220
224
  }
221
225
 
@@ -685,7 +689,7 @@ var NativeDocument = (function (exports) {
685
689
  };
686
690
  });
687
691
 
688
- const overrideMethods = ['map', 'filter', 'reduce', 'some', 'every', 'find'];
692
+ const overrideMethods = ['map', 'filter', 'reduce', 'some', 'every', 'find', 'findIndex'];
689
693
  overrideMethods.forEach((method) => {
690
694
  observer[method] = function(callback) {
691
695
  return observer.val()[method](callback);
@@ -1442,12 +1446,21 @@ var NativeDocument = (function (exports) {
1442
1446
  * @param {Set} keyIds
1443
1447
  */
1444
1448
  const cleanBlockByCache = (cache, keyIds) => {
1445
- for(const [key, {child}] of cache.entries()) {
1449
+ const toRemove = [];
1450
+ for(const [key, cacheItem] of cache.entries()) {
1446
1451
  if(keyIds.has(key)) {
1447
1452
  continue;
1448
1453
  }
1449
- child.remove();
1454
+ toRemove.push({ key, cacheItem });
1455
+ }
1456
+ if(toRemove.length === 0) {
1457
+ return;
1450
1458
  }
1459
+ toRemove.forEach(({ key, cacheItem }) => {
1460
+ cacheItem.child.remove();
1461
+ cacheItem.indexObserver.cleanup();
1462
+ cache.delete(key);
1463
+ });
1451
1464
  };
1452
1465
 
1453
1466
  /**
@@ -1460,33 +1473,102 @@ var NativeDocument = (function (exports) {
1460
1473
  function ForEach(data, callback, key) {
1461
1474
  const element = new Anchor('ForEach');
1462
1475
  const blockEnd = element.endElement();
1476
+ const blockStart = element.startElement();
1463
1477
 
1464
1478
  let cache = new Map();
1479
+ const keyIds = new Set();
1465
1480
 
1466
1481
  const handleContentItem = (item, indexKey) => {
1467
1482
  const keyId = getKey(item, indexKey, key);
1468
1483
 
1469
1484
  if(cache.has(keyId)) {
1470
- cache.get(keyId).indexObserver.set(indexKey);
1485
+ const cacheItem = cache.get(keyId);
1486
+ cacheItem.indexObserver.set(indexKey);
1487
+ cacheItem.isNew = false;
1471
1488
  }
1472
1489
  else {
1473
- const indexObserver = Observable(indexKey);
1474
- let child = callback(item, indexObserver);
1475
- if(Validator.isStringOrObservable(child)) {
1476
- child = createTextNode(child);
1490
+
1491
+ try {
1492
+ const indexObserver = Observable(indexKey);
1493
+ let child = callback(item, indexObserver);
1494
+ if(Validator.isStringOrObservable(child)) {
1495
+ child = createTextNode(child);
1496
+ }
1497
+ cache.set(keyId, { isNew: true, child, indexObserver});
1498
+ } catch (e) {
1499
+ DebugManager.error('ForEach', `Error creating element for key ${keyId}` , e);
1500
+ throw e;
1477
1501
  }
1478
- cache.set(keyId, { child, indexObserver});
1479
1502
  }
1480
1503
  return keyId;
1481
1504
  };
1482
- const keyIds = new Set();
1483
1505
 
1484
- const buildContent = () => {
1485
- const items = (Validator.isObservable(data)) ? data.val() : data;
1506
+ const batchDOMUpdates = () => {
1486
1507
  const parent = blockEnd.parentNode;
1487
1508
  if(!parent) {
1488
1509
  return;
1489
1510
  }
1511
+
1512
+ let previousElementSibling = blockStart;
1513
+ const elementsToInsert = [];
1514
+ const elementsToMove = [];
1515
+ let fragment = null;
1516
+
1517
+ let saveFragment = (beforeTarget) => {
1518
+ if(fragment) {
1519
+ elementsToInsert.push({ child: fragment, before: beforeTarget });
1520
+ fragment = null;
1521
+ }
1522
+ };
1523
+
1524
+ const keyIdsArray = Array.from(keyIds);
1525
+ for(let i = 0; i < keyIdsArray.length; i++) {
1526
+ const itemKey = keyIdsArray[i];
1527
+ const cacheItem = cache.get(itemKey);
1528
+ if(!cacheItem) {
1529
+ continue;
1530
+ }
1531
+
1532
+ if(previousElementSibling && previousElementSibling.nextSibling === cacheItem.child) {
1533
+ previousElementSibling = cacheItem.child;
1534
+ saveFragment(cacheItem.child);
1535
+ continue;
1536
+ }
1537
+ if(cacheItem.isNew) {
1538
+ fragment = fragment || document.createDocumentFragment();
1539
+ fragment.append(cacheItem.child);
1540
+ cacheItem.isNew = false;
1541
+ continue;
1542
+ }
1543
+ saveFragment(cacheItem.child);
1544
+ const nextChild = cache.get(keyIdsArray[i + 1])?.child;
1545
+ if(nextChild) {
1546
+ if(cacheItem.child.nextSibling !== nextChild) {
1547
+ elementsToMove.push({ child: cacheItem.child, before: nextChild });
1548
+ }
1549
+ }
1550
+
1551
+ previousElementSibling = cacheItem.child;
1552
+ }
1553
+ saveFragment(blockEnd);
1554
+
1555
+ elementsToInsert.forEach(({ child, before }) => {
1556
+ if(before) {
1557
+ parent.insertBefore(child, before);
1558
+ } else {
1559
+ element.appendChild(child);
1560
+ }
1561
+ });
1562
+
1563
+ elementsToMove.forEach(({ child, before }) => {
1564
+ parent.insertBefore(child, before);
1565
+ });
1566
+ saveFragment = null;
1567
+
1568
+ };
1569
+
1570
+ const buildContent = () => {
1571
+ const items = (Validator.isObservable(data)) ? data.val() : data;
1490
1572
  keyIds.clear();
1491
1573
  if(Array.isArray(items)) {
1492
1574
  items.forEach((item, index) => keyIds.add(handleContentItem(item, index)));
@@ -1497,25 +1579,13 @@ var NativeDocument = (function (exports) {
1497
1579
  }
1498
1580
 
1499
1581
  cleanBlockByCache(cache, keyIds);
1500
- let nextElementSibling = blockEnd;
1501
- for(const item of [...keyIds].reverse()) {
1502
- const { child } = cache.get(item);
1503
- if(child) {
1504
- if(nextElementSibling && nextElementSibling.previousSibling === child) {
1505
- nextElementSibling = child;
1506
- continue;
1507
- }
1508
- parent.insertBefore(child, nextElementSibling);
1509
- nextElementSibling = child;
1510
- }
1511
- }
1582
+
1583
+ batchDOMUpdates();
1512
1584
  };
1513
1585
 
1514
1586
  buildContent();
1515
1587
  if(Validator.isObservable(data)) {
1516
- data.subscribe(throttle((newValue, oldValue) => {
1517
- buildContent();
1518
- }, 50, { debounce: true }));
1588
+ data.subscribe(buildContent);
1519
1589
  }
1520
1590
  return element;
1521
1591
  }
@@ -1 +1 @@
1
- var NativeDocument=function(t){"use strict";function n(e,t,n){return e.addEventListener(t,n),e}const r={enabled:!1,enable(){this.enabled=!0,console.log("🔍 NativeDocument Debug Mode enabled")},disable(){this.enabled=!1},log(e,t,n){this.enabled&&(console.group(`🔍 [${e}] ${t}`),n&&console.log(n),console.trace(),console.groupEnd())},warn(e,t,n){this.enabled&&console.warn(`⚠️ [${e}] ${t}`,n)},error(e,t,n){console.error(`❌ [${e}] ${t}`,n)}},o=function(){let e=0;const t=new Map;let n=null;try{n=new FinalizationRegistry(e=>{r.log("MemoryManager","🧹 Auto-cleanup observable:",e),e.listeners.splice(0)})}catch(e){r.warn("MemoryManager","FinalizationRegistry not supported, observables will not be cleaned automatically")}return{register(r,o){const s=++e,i={id:s,listeners:o};return n&&n.register(r,i),t.set(s,new WeakRef(r)),s},getObservableById:e=>t.get(e)?.deref(),cleanup(){for(const[e,n]of t){const e=n.deref();e&&e.cleanup()}t.clear()},cleanObservables(e){if(t.size<e)return;let n=0;for(const[e,r]of t)r.deref()||(t.delete(e),n++);n>0&&r.log("Memory Auto Clean",`🧹 Cleaned ${n} orphaned observables`)}}}();class s extends Error{constructor(e,t={}){super(e),this.name="NativeDocumentError",this.context=t,this.timestamp=(new Date).toISOString()}}function i(e,t){this.observable=e,this.checker=t,this.subscribe=function(n){return e.subscribe(e=>{n&&n(t(e))})},this.val=function(){return t&&t(e.val())},this.check=function(t){return e.check(()=>t(this.val()))},this.set=function(t){return e.set(t)},this.trigger=function(){return e.trigger()},this.cleanup=function(){return e.cleanup()}}function a(e){if(void 0===e)throw new s("ObservableItem requires an initial value");if(e instanceof a)throw new s("ObservableItem cannot be an Observable");const t="object"==typeof e?JSON.parse(JSON.stringify(e)):e;let n=e,u=e,c=!1;const l=[],d=o.register(this,l);this.trigger=()=>{l.forEach(e=>{try{e(u,n)}catch(t){r.error("Listener Undefined","Error in observable listener:",t),this.unsubscribe(e)}})},this.originalValue=()=>t,this.set=e=>{const t="function"==typeof e?e(u):e;u!==t&&(n=u,u=t,this.trigger())},this.val=()=>u,this.cleanup=function(){l.splice(0),c=!0},this.subscribe=e=>{if(c)return r.warn("Observable subscription","⚠️ Attempted to subscribe to a cleaned up observable."),()=>{};if("function"!=typeof e)throw new s("Callback must be a function");return l.push(e),()=>this.unsubscribe(e)},this.unsubscribe=e=>{const t=l.indexOf(e);t>-1&&l.splice(t,1)},this.check=function(e){return new i(this,e)};const p=this;Object.defineProperty(p,"$value",{get:()=>p.val(),set:e=>(p.set(e),p)}),this.toString=function(){return"{{#ObItem::("+d+")}}"}}const u={isObservable:e=>e instanceof a||e instanceof i,isProxy:e=>e?.__isProxy__,isObservableChecker:e=>e instanceof i,isArray:e=>Array.isArray(e),isString:e=>"string"==typeof e,isNumber:e=>"number"==typeof e,isBoolean:e=>"boolean"==typeof e,isFunction:e=>"function"==typeof e,isAsyncFunction:e=>"function"==typeof e&&"AsyncFunction"===e.constructor.name,isObject:e=>"object"==typeof e,isJson:e=>"object"==typeof e&&null!==e&&"Object"===e.constructor.name&&!Array.isArray(e),isElement:e=>e instanceof HTMLElement||e instanceof DocumentFragment||e instanceof Text,isFragment:e=>e instanceof DocumentFragment,isStringOrObservable(e){return this.isString(e)||this.isObservable(e)},isValidChild(e){return null===e||this.isElement(e)||this.isObservable(e)||["string","number","boolean"].includes(typeof e)},isValidChildren(e){Array.isArray(e)||(e=[e]);return 0===e.filter(e=>!this.isValidChild(e)).length},validateChildren(e){Array.isArray(e)||(e=[e]);const t=e.filter(e=>!this.isValidChild(e));if(t.length>0)throw new s(`Invalid children detected: ${t.map(e=>typeof e).join(", ")}`);return e},containsObservables:e=>!!e&&(u.isObject(e)&&Object.values(e).some(e=>u.isObservable(e))),containsObservableReference:e=>!(!e||"string"!=typeof e)&&/\{\{#ObItem::\([0-9]+\)\}\}/.test(e),validateAttributes(e){if(!e||"object"!=typeof e)return e;const t=[],n=Object.keys(e).filter(e=>t.includes(e));return n.length>0&&r.warn("Validator",`Reserved attributes found: ${n.join(", ")}`),e},validateEventCallback(e){if("function"!=typeof e)throw new s("Event callback must be a function")}},c=["checked","selected","disabled","readonly","required","autofocus","multiple","autocomplete","hidden","contenteditable","spellcheck","translate","draggable","async","defer","autoplay","controls","loop","muted","download","reversed","open","default","formnovalidate","novalidate","scoped","itemscope","allowfullscreen","allowpaymentrequest","playsinline"],l=function(e,t,n={}){let r=null,o=0;const{leading:s=!0,trailing:i=!0,debounce:a=!1}=n;return function(...n){const u=Date.now();if(a)return clearTimeout(r),void(r=setTimeout(()=>e.apply(this,n),t));s&&u-o>=t&&(e.apply(this,n),o=u),i&&!r&&(r=setTimeout(()=>{e.apply(this,n),o=Date.now(),r=null},t-(u-o)))}},d=function(e,t){return e.replace(new RegExp(`^[${t}]+|[${t}]+$`,"g"),"")};function p(e){return new a(e)}p.computed=function(e,t=[]){const n=new a(e()),r=()=>n.set(e());if(u.isFunction(t)){if(!u.isObservable(t.$observer))throw new s("Observable.computed : dependencies must be valid batch function");return t.$observer.subscribe(r),n}return t.forEach(e=>e.subscribe(r)),n},p.batch=function(e){const t=p(0),n=function(){if(u.isAsyncFunction(e))return e(...arguments).then(()=>{t.trigger()}).catch(e=>{throw e});e(...arguments),t.trigger()};return n.$observer=t,n},p.getById=function(e){const t=o.getObservableById(parseInt(e));if(!t)throw new s("Observable.getById : No observable found with id "+e);return t},p.cleanup=function(e){e.cleanup()},p.value=function(e){if(u.isObservable(e))return e.val();if(u.isProxy(e))return e.$val();if(u.isArray(e)){const t=[];return e.forEach(e=>{t.push(p.value(e))}),t}return e},p.init=function(e){const t={};for(const n in e){const r=e[n];u.isJson(r)?t[n]=p.init(r):u.isArray(r)?t[n]=p.array(r):t[n]=p(r)}const n=function(){const e={};for(const n in t){const r=t[n];u.isObservable(r)?e[n]=r.val():u.isProxy(r)?e[n]=r.$val():e[n]=r}return e},r=function(){};return new Proxy(t,{get:(e,t)=>"__isProxy__"===t||("$val"===t?n:"$clone"===t?r:void 0!==e[t]?e[t]:void 0),set(e,t,n){void 0!==e[t]&&e[t].set(n)}})},p.object=p.init,p.json=p.init,p.update=function(e,t){for(const n in t){const r=e[n],o=t[n];if(u.isObservable(r)){if(u.isArray(o)){p.update(r,o);continue}r.set(o)}else u.isProxy(r)?p.update(r,o):e[n]=o}},p.array=function(e){if(!Array.isArray(e))throw new s("Observable.array : target must be an array");const t=p(e);["push","pop","shift","unshift","reverse","sort","splice"].forEach(e=>{t[e]=function(...n){const r=t.val(),o=r[e].apply(r,arguments);return t.trigger(),o}});return["map","filter","reduce","some","every","find"].forEach(e=>{t[e]=function(n){return t.val()[e](n)}}),t},p.autoCleanup=function(e=!1,t={}){if(!e)return;const{interval:n=6e4,threshold:r=100}=t;window.addEventListener("beforeunload",()=>{o.cleanup()}),setInterval(()=>o.cleanObservables(r),n)};const h=function(e,t,n){n?e.classList.add(t):e.classList.remove(t)};function f(e,t){for(let n in t){const r=t[n];u.isObservable(r)?(h(e,n,r.val()),r.subscribe(t=>h(e,n,t))):h(e,n,r)}}function b(e,t){for(let n in t){const r=t[n];u.isObservable(r)?(e.style[n]=r.val(),r.subscribe(t=>{e.style[n]=t})):e.style[n]=r}}function m(e,t,n){const r=u.isObservable(n)?n.val():n;u.isBoolean(r)?e[t]=r:e[t]=r===e.value,u.isObservable(n)&&(["checked"].includes(t)&&e.addEventListener("input",()=>{u.isBoolean(r)?n.set(e[t]):n.set(e.value)}),n.subscribe(n=>{u.isBoolean(n)?e[t]=n:e[t]=n===e.value}))}function v(e,t,n){const r=n=>{"value"!==t?e.setAttribute(t,n):e.value=n};n.subscribe(r),r(n.val()),"value"===t&&e.addEventListener("input",()=>n.set(e.value))}const y={elements:new Map,observer:null,checkMutation:l(function(){for(const[e,t]of y.elements.entries()){const n=document.body.contains(e);n&&!t.inDom?(t.inDom=!0,t.mounted.forEach(t=>t(e))):!n&&t.inDom&&(t.inDom=!1,t.unmounted.forEach(t=>t(e)))}},10,{debounce:!0}),watch:function(e){let t={};if(y.elements.has(e))t=y.elements.get(e);else{const n=document.body.contains(e);t={inDom:n,mounted:new Set,unmounted:new Set},y.elements.set(e,t)}return{watch:()=>y.elements.set(e,t),disconnect:()=>y.elements.delete(e),mounted:e=>t.mounted.add(e),unmounted:e=>t.unmounted.add(e)}}};y.observer=new MutationObserver(y.checkMutation),y.observer.observe(document.body,{childList:!0,subtree:!0});const g=e=>u.isFunction(e)?g(e()):u.isElement(e)?e:S(e);function w(e){const t=document.createDocumentFragment(),n=document.createComment("Anchor Start : "+e),o=document.createComment("/ Anchor End "+e);t.appendChild(n),t.appendChild(o),t.nativeInsertBefore=t.insertBefore,t.nativeAppendChild=t.appendChild;const s=function(e,n,r){e!==t?e.insertBefore(g(n),r):e.nativeInsertBefore(g(n),r)};return t.appendChild=function(e,n=null){const i=o.parentNode;if(i){if(n=n??o,u.isArray(e))return e.forEach(e=>{s(i,e,n)}),t;s(i,e,n)}else r.error("Anchor","Anchor : parent not found",e)},t.remove=function(e){if(o.parentNode===t)return;let r,s=n.nextSibling;for(;s!==o;)r=s.nextSibling,e?s.remove():t.nativeAppendChild(s),s=r;e&&(o.remove(),n.remove())},t.insertBefore=function(e,n=null){t.appendChild(e,n)},t.clear=function(){t.remove()},t.endElement=function(){return o},t.startElement=function(){return n},t}const O=function(){const e=[];return{list:()=>e,add:t=>e.push(t)}}(),C=function(e,t){const n=document.createTextNode("");return t.subscribe(e=>n.textContent=String(e)),n.textContent=t.val(),e&&e.appendChild(n),n},E=function(e,t){const n=document.createTextNode("");return n.textContent=String(t),e&&e.appendChild(n),n},S=function(e){return u.isObservable(e)?C(null,e):E(null,e)},A={createElement:e=>e?document.createElement(e):new w("Fragment"),processChildren(e,t){if(null===e)return;(Array.isArray(e)?e:[e]).forEach(e=>{null!==e&&(u.isString(e)&&u.isFunction(e.resolveObservableTemplate)&&(e=e.resolveObservableTemplate()),u.isFunction(e)?this.processChildren(e(),t):u.isArray(e)?this.processChildren(e,t):u.isElement(e)?t.appendChild(e):u.isObservable(e)?C(t,e):e&&E(t,e))})},processAttributes(e,t){u.isFragment(e)||t&&function(e,t){if(u.validateAttributes(t),!u.isObject(t))throw new s("Attributes must be an object");for(let n in t){const r=n.toLowerCase();let o=t[r];if(u.isString(o)&&u.isFunction(o.resolveObservableTemplate)&&(o=o.resolveObservableTemplate(),u.isArray(o))){const e=o.filter(e=>u.isObservable(e));o=p.computed(()=>o.map(e=>u.isObservable(e)?e.val():e).join(" ")||" ",e)}c.includes(r)?m(e,r,o):u.isObservable(o)?v(e,r,o):"class"===r&&u.isJson(o)?f(e,o):"style"===r&&u.isJson(o)?b(e,o):e.setAttribute(r,o)}}(e,t)},setup(e,t,r){e.nd={},function(e){e.nd||(e.nd={}),e.nd.on=function(t){for(const r in t){const o=t[r];n(e,r,o)}return e},e.nd.on.prevent=function(t){for(const r in t){const o=t[r];n(e,r,t=>(t.preventDefault(),o&&o(t),e))}return e};const t={click:t=>n(e,"click",t),focus:t=>n(e,"focus",t),blur:t=>n(e,"blur",t),input:t=>n(e,"input",t),change:t=>n(e,"change",t),keyup:t=>n(e,"keyup",t),keydown:t=>n(e,"keydown",t),beforeInput:t=>n(e,"beforeinput",t),mouseOver:t=>n(e,"mouseover",t),mouseOut:t=>n(e,"mouseout",t),mouseDown:t=>n(e,"mousedown",t),mouseUp:t=>n(e,"mouseup",t),mouseMove:t=>n(e,"mousemove",t),hover:(t,n)=>{e.addEventListener("mouseover",t),e.addEventListener("mouseout",n)},dropped:t=>n(e,"drop",t),submit:t=>n(e,"submit",t),dragEnd:t=>n(e,"dragend",t),dragStart:t=>n(e,"dragstart",t),drop:t=>n(e,"drop",t),dragOver:t=>n(e,"dragover",t),dragEnter:t=>n(e,"dragenter",t),dragLeave:t=>n(e,"dragleave",t)};for(let r in t)e.nd.on[r]=t[r],e.nd.on.prevent[r]=function(t){return n(e,r.toLowerCase(),e=>{e.preventDefault(),t&&t(e)}),e}}(e);const o="function"==typeof r?r(e):e;return function(e){e.nd.wrap=t=>{if(!u.isFunction(t))throw new s("Callback must be a function");return t&&t(e),e},e.nd.ref=(t,n)=>(t[n]=e,e);let t=null;e.nd.appendChild=function(t){u.isArray(t)?A.processChildren(t,e):(u.isFunction(t)&&(t=t(),A.processChildren(t(),e)),u.isElement(t)&&A.processChildren(t,e))},e.nd.lifecycle=function(n){return t=t||y.watch(e),n.mounted&&t.mounted(n.mounted),n.unmounted&&t.unmounted(n.unmounted),e},e.nd.mounted=n=>(t=t||y.watch(e),t.mounted(n),e),e.nd.unmounted=n=>(t=t||y.watch(e),t.unmounted(n),e)}(o),O.list().forEach(e=>{e?.element?.setup&&e.element.setup(o,t)}),o}};function I(e,t){const n=e.toLowerCase().trim(),o=function(e,o=null){try{if(u.isValidChildren(e)){const t=o;o=e,e=t}const r=A.createElement(n);return A.processAttributes(r,e),A.processChildren(o,r),A.setup(r,e,t)}catch(e){r.error("ElementCreation",`Error creating ${n}`,e)}};return o.hold=(e,t)=>()=>o(e,t),o}class k extends Error{constructor(e,t){super(`${e}\n\n${t.join("\n")}\n\n`)}}const $={string:e=>({name:e,type:"string",validate:e=>u.isString(e)}),number:e=>({name:e,type:"number",validate:e=>u.isNumber(e)}),boolean:e=>({name:e,type:"boolean",validate:e=>u.isBoolean(e)}),observable:e=>({name:e,type:"observable",validate:e=>u.isObservable(e)}),element:e=>({name:e,type:"element",validate:e=>u.isElement(e)}),function:e=>({name:e,type:"function",validate:e=>u.isFunction(e)}),object:e=>({name:e,type:"object",validate:e=>u.isObject(e)}),objectNotNull:e=>({name:e,type:"object",validate:e=>u.isObject(e)&&null!==e}),children:e=>({name:e,type:"children",validate:e=>u.validateChildren(e)}),attributes:e=>({name:e,type:"attributes",validate:e=>u.validateAttributes(e)}),optional:e=>({...e,optional:!0}),oneOf:(e,...t)=>({name:e,type:"oneOf",types:t,validate:e=>t.some(t=>t.validate(e))})},F=(e,t,n="Function")=>{if(!u.isArray(t))throw new s("withValidation : argSchema must be an array");return function(...r){return((e,t,n="Function")=>{if(!t)return;const r=[],o=t.filter(e=>!e.optional).length;if(e.length<o&&r.push(`${n}: Expected at least ${o} arguments, got ${e.length}`),t.forEach((t,o)=>{const s=o+1,i=e[o];if(void 0!==i){if(!t.validate(i)){const e=i?.constructor?.name||typeof i;r.push(`${n}: Invalid argument '${t.name}' at position ${s}, expected ${t.type}, got ${e}`)}}else t.optional||r.push(`${n}: Missing required argument '${t.name}' at position ${s}`)}),r.length>0)throw new k("Argument validation failed",r)})(r,t,e.name||n),e.apply(this,r)}};Function.prototype.args=function(...e){return F(this,e)},Function.prototype.errorBoundary=function(e){return(...t)=>{try{return this.apply(this,t)}catch(t){return e(t)}}},String.prototype.use=function(e){const t=this;return p.computed(()=>t.replace(/\$\{(.*?)}/g,(t,n)=>{const r=e[n];return u.isObservable(r)?r.val():r}),Object.values(e))},String.prototype.resolveObservableTemplate=function(){return u.containsObservableReference(this)?this.split(/(\{\{#ObItem::\([0-9]+\)\}\})/g).filter(Boolean).map(e=>{if(!u.containsObservableReference(e))return e;const[t,n]=e.match(/\{\{#ObItem::\(([0-9]+)\)\}\}/);return p.getById(n)}):this};const R=function(){const e=new Map;return{use(t){const{observer:n,subscribers:r}=e.get(t),o=p(n.val()),s=n.subscribe(e=>o.set(e)),i=o.subscribe(e=>n.set(e));return o.destroy=()=>{s(),i(),o.cleanup()},r.add(o),o},follow(e){return this.use(e)},create(t,n){const r=p(n);return e.set(t,{observer:r,subscribers:new Set}),r},get(t){const n=e.get(t);return n?n.observer:null},getWithSubscribers:t=>e.get(t),delete(t){const n=e.get(t);n&&(n.observer.cleanup(),n.subscribers.forEach(e=>e.destroy()),n.observer.clear())}}}();const q=function(e,t,n=null){if(!u.isObservable(e))return r.warn("ShowIf","ShowIf : condition must be an Observable / "+n,e);const o=new w("Show if : "+(n||""));let s=null;const i=()=>s||(s="function"==typeof t?t():t,u.isStringOrObservable(s)&&(s=S(s)),s);return e.val()&&o.appendChild(i()),e.subscribe(e=>{e?o.appendChild(i()):o.remove()}),o},x=function(e,t){if(!u.isObservable(e))throw new s("Toggle : condition must be an Observable");const n=new w,r=new Map,o=function(e){if(r.has(e))return r.get(e);let n=t[e];return n?(u.isFunction(n)&&(n=n()),r.set(e,n),n):null},i=e.val(),a=o(i);return a&&n.appendChild(a),e.subscribe(e=>{const t=o(e);n.remove(),t&&n.appendChild(t)}),n},T=function(e,t,n){if(!u.isObservable(e))throw new s("Toggle : condition must be an Observable");return x(e,{true:t,false:n})},D=I("div"),j=I("span"),L=I("label"),B=I("p"),M=B,H=I("strong"),N=I("h1"),P=I("h2"),_=I("h3"),V=I("h4"),U=I("h5"),z=I("h6"),J=I("br"),W=I("a"),K=I("pre"),Q=I("code"),G=I("blockquote"),X=I("hr"),Y=I("em"),Z=I("small"),ee=I("mark"),te=I("del"),ne=I("ins"),re=I("sub"),oe=I("sup"),se=I("abbr"),ie=I("cite"),ae=I("q"),ue=I("dl"),ce=I("dt"),le=I("dd"),de=I("form",function(e){return e.submit=function(t){return"function"==typeof t?(e.on.submit(e=>{e.preventDefault(),t(e)}),e):(this.setAttribute("action",t),e)},e.multipartFormData=function(){return this.setAttribute("enctype","multipart/form-data"),e},e.post=function(t){return this.setAttribute("method","post"),this.setAttribute("action",t),e},e.get=function(e){this.setAttribute("method","get"),this.setAttribute("action",e)},e}),pe=I("input"),he=I("textarea"),fe=he,be=I("select"),me=I("fieldset"),ve=I("option"),ye=I("legend"),ge=I("datalist"),we=I("output"),Oe=I("progress"),Ce=I("meter"),Ee=I("button"),Se=I("main"),Ae=I("section"),Ie=I("article"),ke=I("aside"),$e=I("nav"),Fe=I("figure"),Re=I("figcaption"),qe=I("header"),xe=I("footer"),Te=I("img"),De=function(e,t){return Te({src:e,...t})},je=I("details"),Le=I("summary"),Be=I("dialog"),Me=I("menu"),He=I("ol"),Ne=I("ul"),Pe=I("li"),_e=I("audio"),Ve=I("video"),Ue=I("source"),ze=I("track"),Je=I("canvas"),We=I("svg"),Ke=I("time"),Qe=I("data"),Ge=I("address"),Xe=I("kbd"),Ye=I("samp"),Ze=I("var"),et=I("wbr"),tt=I("caption"),nt=I("table"),rt=I("thead"),ot=I("tfoot"),st=I("tbody"),it=I("tr"),at=it,ut=I("th"),ct=ut,lt=ut,dt=I("td"),pt=dt,ht=I("");var ft=Object.freeze({__proto__:null,Abbr:se,Address:Ge,Anchor:w,Article:Ie,Aside:ke,AsyncImg:function(e,t,n,r){const o=De(t||e,n),i=new Image;return i.onload=()=>{u.isFunction(r)&&r(null,o),o.src=e},i.onerror=()=>{u.isFunction(r)&&r(new s("Image not found"))},u.isObservable(e)&&e.subscribe(e=>{i.src=e}),i.src=e,o},Audio:_e,BaseImage:Te,Blockquote:G,Br:J,Button:Ee,Canvas:Je,Caption:tt,Checkbox:e=>pe({type:"checkbox",...e}),Cite:ie,Code:Q,ColorInput:e=>pe({type:"color",...e}),Data:Qe,Datalist:ge,DateInput:e=>pe({type:"date",...e}),DateTimeInput:e=>pe({type:"datetime-local",...e}),Dd:le,Del:te,Details:je,Dialog:Be,Div:D,Dl:ue,Dt:ce,Em:Y,EmailInput:e=>pe({type:"email",...e}),FieldSet:me,FigCaption:Re,Figure:Fe,FileInput:e=>pe({type:"file",...e}),Footer:xe,ForEach:function(e,t,n){const r=new w("ForEach"),o=r.endElement();let s=new Map;const i=(e,r)=>{const o=((e,t,n)=>{if(u.isFunction(n))return n(e,t);if(u.isObservable(e)){const r=e.val();return r&&n?r[n]:t}return e[n]??t})(e,r,n);if(s.has(o))s.get(o).indexObserver.set(r);else{const n=p(r);let i=t(e,n);u.isStringOrObservable(i)&&(i=S(i)),s.set(o,{child:i,indexObserver:n})}return o},a=new Set,c=()=>{const t=u.isObservable(e)?e.val():e,n=o.parentNode;if(!n)return;if(a.clear(),Array.isArray(t))t.forEach((e,t)=>a.add(i(e,t)));else for(const e in t)a.add(i(t[e],e));((e,t)=>{for(const[n,{child:r}]of e.entries())t.has(n)||r.remove()})(s,a);let r=o;for(const e of[...a].reverse()){const{child:t}=s.get(e);if(t){if(r&&r.previousSibling===t){r=t;continue}n.insertBefore(t,r),r=t}}};return c(),u.isObservable(e)&&e.subscribe(l((e,t)=>{c()},50,{debounce:!0})),r},Form:de,Fragment:ht,H1:N,H2:P,H3:_,H4:V,H5:U,H6:z,Header:qe,HiddenInput:e=>pe({type:"hidden",...e}),HideIf:function(e,t,n){const r=p(!e.val());return e.subscribe(e=>r.set(!e)),q(r,t,n)},HideIfNot:function(e,t,n){return q(e,t,n)},Hr:X,Img:De,Input:pe,Ins:ne,Kbd:Xe,Label:L,LazyImg:function(e,t){return De(e,{...t,loading:"lazy"})},Legend:ye,Link:W,ListItem:Pe,Main:Se,Mark:ee,Match:x,Menu:Me,Meter:Ce,MonthInput:e=>pe({type:"month",...e}),NativeDocumentFragment:w,Nav:$e,NumberInput:e=>pe({type:"number",...e}),Option:ve,OrderedList:He,Output:we,P:B,Paragraph:M,PasswordInput:e=>pe({type:"password",...e}),Pre:K,Progress:Oe,Quote:ae,Radio:e=>pe({type:"radio",...e}),RangeInput:e=>pe({type:"range",...e}),ReadonlyInput:e=>pe({readonly:!0,...e}),Samp:Ye,SearchInput:e=>pe({type:"search",...e}),Section:Ae,Select:be,ShowIf:q,SimpleButton:(e,t)=>Ee(e,{type:"button",...t}),Small:Z,Source:Ue,Span:j,Strong:H,Sub:re,SubmitButton:(e,t)=>Ee(e,{type:"submit",...t}),Summary:Le,Sup:oe,Svg:We,Switch:T,TBody:st,TBodyCell:pt,TFoot:ot,TFootCell:lt,THead:rt,THeadCell:ct,TRow:at,Table:nt,Td:dt,TelInput:e=>pe({type:"tel",...e}),TextArea:he,TextInput:fe,Th:ut,Time:Ke,TimeInput:e=>pe({type:"time",...e}),Tr:it,Track:ze,UnorderedList:Ne,UrlInput:e=>pe({type:"url",...e}),Var:Ze,Video:Ve,Wbr:et,WeekInput:e=>pe({type:"week",...e}),When:function(e){if(!u.isObservable(e))throw new s("When : condition must be an Observable");let t=null,n=null;return{show(e){return t=e,this},otherwise:r=>(n=r,T(e,t,n))}}});const bt={};function mt(e,t,n={}){e="/"+d(e,"/");let r=null,o=n.name||null;const s=n.middlewares||[],i=n.shouldRebuild||!1,a=n.with||{},u={},c=[],l=e=>{if(!e)return null;const[t,n]=e.split(":");let r=a[t];return!r&&n&&(r=bt[n]),r||(r="[^/]+"),r=r.replace("(","(?:"),{name:t,pattern:`(${r})`}},p=()=>{if(r)return r;const t=e.replace(/\{(.*?)}/gi,(e,t)=>{const n=l(t);return n&&n.pattern?(u[n.name]=n.pattern,c.push(n.name),n.pattern):e});return r=new RegExp("^"+t+"$"),r};this.name=()=>o,this.component=()=>t,this.middlewares=()=>s,this.shouldRebuild=()=>i,this.path=()=>e,this.match=function(e){e="/"+d(e,"/");if(!p().exec(e))return!1;const t={};return p().exec(e).forEach((e,n)=>{if(n<1)return;const r=c[n-1];t[r]=e}),t},this.url=function(t){const n=e.replace(/\{(.*?)}/gi,(e,n)=>{const r=l(n);if(t.params&&t.params[r.name])return t.params[r.name];throw new Error(`Missing parameter '${r.name}'`)}),r="object"==typeof t.query?new URLSearchParams(t.query).toString():null;return(t.basePath?t.basePath:"")+(r?`${n}?${r}`:n)}}class vt extends Error{constructor(e,t){super(e),this.context=t}}const yt=(e,t)=>{const n=[];return e.forEach(e=>{n.push(d(e.suffix,"/"))}),n.push(d(t,"/")),n.join("/")},gt=(e,t)=>{const n=[];return e.forEach(e=>{e.options.middlewares&&n.push(...e.options.middlewares)}),t&&n.push(...t),n},wt=(e,t)=>{const n=[];return e.forEach(e=>{e.options?.name&&n.push(e.options.name)}),t&&n.push(t),n.join(".")};function Ot(){const e=[];let t=0;const n=n=>{const o=t+n;if(!e[o])return;t=o;const{route:s,params:i,query:a,path:u}=e[o];r(u)},r=e=>{window.location.replace(`${window.location.pathname}${window.location.search}#${e}`)},o=()=>window.location.hash.slice(1);this.push=function(n){const{route:s,params:i,query:a,path:u}=this.resolve(n);u!==o()&&(e.splice(t+1),e.push({route:s,params:i,query:a,path:u}),t++,r(u))},this.replace=function(n){const{route:r,params:s,query:i,path:a}=this.resolve(n);a!==o()&&(e[t]={route:r,params:s,query:i,path:a})},this.forward=function(){return t<e.length-1&&n(1)},this.back=function(){return t>0&&n(-1)},this.init=function(n){window.addEventListener("hashchange",()=>{const{route:e,params:t,query:n,path:r}=this.resolve(o());this.handleRouteChange(e,t,n,r)});const{route:r,params:s,query:i,path:a}=this.resolve(n||o());e.push({route:r,params:s,query:i,path:a}),t=0,this.handleRouteChange(r,s,i,a)}}function Ct(){this.push=function(e){try{const{route:t,path:n,params:r,query:o}=this.resolve(e);if(window.history.state&&window.history.state.path===n)return;window.history.pushState({name:t.name(),params:r,path:n},t.name()||n,n),this.handleRouteChange(t,r,o,n)}catch(e){r.error("HistoryRouter","Error in pushState",e)}},this.replace=function(e){const{route:t,path:n,params:o}=this.resolve(e);try{window.history.replaceState({name:t.name(),params:o,path:n},t.name()||n,n),this.handleRouteChange(t,o,{},n)}catch(e){r.error("HistoryRouter","Error in replaceState",e)}},this.forward=function(){window.history.forward()},this.back=function(){window.history.back()},this.init=function(e){window.addEventListener("popstate",e=>{try{if(!e.state||!e.state.path)return;const t=e.state.path,{route:n,params:r,query:o,path:s}=this.resolve(t);if(!n)return;this.handleRouteChange(n,r,o,s)}catch(e){r.error("HistoryRouter","Error in popstate event",e)}});const{route:t,params:n,query:o,path:s}=this.resolve(e||window.location.pathname+window.location.search);this.handleRouteChange(t,n,o,s)}}function Et(){const e=[];let t=0;const n=n=>{const r=t+n;if(!e[r])return;t=r;const{route:o,params:s,query:i,path:a}=e[r];this.handleRouteChange(o,s,i,a)};this.push=function(n){const{route:r,params:o,query:s,path:i}=this.resolve(n);e[t]&&e[t].path===i||(e.splice(t+1),e.push({route:r,params:o,query:s,path:i}),t++,this.handleRouteChange(r,o,s,i))},this.replace=function(n){const{route:r,params:o,query:s,path:i}=this.resolve(n);e[t]={route:r,params:o,query:s,path:i},this.handleRouteChange(r,o,s,i)},this.forward=function(){return t<e.length-1&&n(1)},this.back=function(){return t>0&&n(-1)},this.init=function(n){const r=n||window.location.pathname+window.location.search,{route:o,params:s,query:i,path:a}=this.resolve(r);e.push({route:o,params:s,query:i,path:a}),t=0,this.handleRouteChange(o,s,i,a)}}const St="default";function At(e={}){const t=[],n={},o=[],s=[],i={route:null,params:null,query:null,path:null,hash:null};if("hash"===e.mode)Ot.apply(this,[]);else if("history"===e.mode)Ct.apply(this,[]);else{if("memory"!==e.mode)throw new vt("Invalid router mode "+e.mode);Et.apply(this,[])}const a=function(e,t){for(const n of s)try{n(e),t&&t(e)}catch(e){r.warn("Route Listener","Error in listener:",e)}};this.routes=()=>[...t],this.currentState=()=>({...i}),this.add=function(e,r,s){const i=new mt(yt(o,e),r,{...s,middlewares:gt(o,s?.middlewares||[]),name:s?.name?wt(o,s.name):null});return t.push(i),i.name()&&(n[i.name()]=i),this},this.group=function(e,t,n){if(!u.isFunction(n))throw new vt("Callback must be a function");return o.push({suffix:e,options:t}),n(),o.pop(),this},this.generateUrl=function(e,t={},r={}){const o=n[e];if(!o)throw new vt(`Route not found for name: ${e}`);return o.url({params:t,query:r})},this.resolve=function(e){if(u.isJson(e)){const t=n[e.name];if(!t)throw new vt(`Route not found for name: ${e.name}`);return{route:t,params:e.params,query:e.query,path:t.url({...e})}}const[r,o]=e.split("?"),s="/"+d(r,"/");let i,a=null;for(const e of t)if(i=e.match(s),i){a=e;break}if(!a)throw new vt(`Route not found for url: ${r}`);const c={};if(o){const e=new URLSearchParams(o).entries();for(const[t,n]of e)c[t]=n}return{route:a,params:i,query:c,path:e}},this.subscribe=function(e){if(!u.isFunction(e))throw new vt("Listener must be a function");return s.push(e),()=>{s.splice(s.indexOf(e),1)}},this.handleRouteChange=function(e,t,n,r){i.route=e,i.params=t,i.query=n,i.path=r;const o=[...e.middlewares(),a];let s=0;const u={...i},c=e=>{if(s++,!(s>=o.length))return o[s](e||u,c)};return o[s](u,c)}}function It(e,t){const{to:n,href:r,...o}=e,s=n||r;if(u.isString(s)){const e=At.get();return W({...o,href:s},t).nd.on.prevent.click(()=>{e.push(s)})}const i=s.router||St,a=At.get(i);if(console.log(i),!a)throw new vt('Router not found "'+i+'" for link "'+s.name+'"');const c=a.generateUrl(s.name,s.params,s.query);return W({...o,href:c},t).nd.on.prevent.click(()=>{a.push(c)})}At.routers={},At.create=function(t,n){if(!u.isFunction(n))throw r.error("Router","Callback must be a function",e),new vt("Callback must be a function");const o=new At(t);return At.routers[t.name||St]=o,n(o),o.init(t.entry),o.mount=function(e){if(u.isString(e)){const t=document.querySelector(e);if(!t)throw new vt(`Container not found for selector: ${e}`);e=t}else if(!u.isElement(e))throw new vt("Container must be a string or an Element");return function(e,t){const n=new Map,r=function(e){t.innerHTML="",t.appendChild(e)},o=function(e){if(!e.route)return;const{route:t,params:o,query:s,path:i}=e;if(n.has(i)){const e=n.get(i);return void r(e)}const a=t.component()({params:o,query:s});n.set(i,a),r(a)};return e.subscribe(o),o(e.currentState()),t}(o,e)},o},At.get=function(e){const t=At.routers[e||St];if(!t)throw new vt(`Router not found for name: ${e}`);return t},At.push=function(e,t=null){return At.get(t).push(e)},At.replace=function(e,t=null){return At.get(t).replace(e)},At.forward=function(e=null){return At.get(e).forward()},At.back=function(e=null){return At.get(e).back()},It.blank=function(e,t){return W({...e,target:"_blank"},t)};var kt=Object.freeze({__proto__:null,Link:It,RouteParamPatterns:bt,Router:At});return t.ArgTypes=$,t.ElementCreator=A,t.HtmlElementWrapper=I,t.Observable=p,t.Store=R,t.elements=ft,t.router=kt,t.withValidation=F,t}({});
1
+ var NativeDocument=function(t){"use strict";function n(e,t,n){return e.addEventListener(t,n),e}const r={enabled:!1,enable(){this.enabled=!0,console.log("🔍 NativeDocument Debug Mode enabled")},disable(){this.enabled=!1},log(e,t,n){this.enabled&&(console.group(`🔍 [${e}] ${t}`),n&&console.log(n),console.trace(),console.groupEnd())},warn(e,t,n){this.enabled&&console.warn(`⚠️ [${e}] ${t}`,n)},error(e,t,n){console.error(`❌ [${e}] ${t}`,n)}},o=function(){let e=0;const t=new Map;let n=null;try{n=new FinalizationRegistry(e=>{r.log("MemoryManager","🧹 Auto-cleanup observable:",e),e.listeners.splice(0)})}catch(e){r.warn("MemoryManager","FinalizationRegistry not supported, observables will not be cleaned automatically")}return{register(r,o){const s=++e,i={id:s,listeners:o};return n&&n.register(r,i),t.set(s,new WeakRef(r)),s},getObservableById:e=>t.get(e)?.deref(),cleanup(){for(const[e,n]of t){const e=n.deref();e&&e.cleanup()}t.clear()},cleanObservables(e){if(t.size<e)return;let n=0;for(const[e,r]of t)r.deref()||(t.delete(e),n++);n>0&&r.log("Memory Auto Clean",`🧹 Cleaned ${n} orphaned observables`)}}}();class s extends Error{constructor(e,t={}){super(e),this.name="NativeDocumentError",this.context=t,this.timestamp=(new Date).toISOString()}}function i(e,t){this.observable=e,this.checker=t;const n=[];this.subscribe=function(r){const o=e.subscribe(e=>{r&&r(t(e))});return n.push(o),o},this.val=function(){return t&&t(e.val())},this.check=function(t){return e.check(()=>t(this.val()))},this.set=function(t){return e.set(t)},this.trigger=function(){return e.trigger()},this.cleanup=function(){n.forEach(e=>e())}}function a(e){if(void 0===e)throw new s("ObservableItem requires an initial value");if(e instanceof a)throw new s("ObservableItem cannot be an Observable");const t="object"==typeof e?JSON.parse(JSON.stringify(e)):e;let n=e,u=e,c=!1;const l=[],d=o.register(this,l);this.trigger=()=>{l.forEach(e=>{try{e(u,n)}catch(t){r.error("Listener Undefined","Error in observable listener:",t),this.unsubscribe(e)}})},this.originalValue=()=>t,this.set=e=>{const t="function"==typeof e?e(u):e;u!==t&&(n=u,u=t,this.trigger())},this.val=()=>u,this.cleanup=function(){l.splice(0),c=!0},this.subscribe=e=>{if(c)return r.warn("Observable subscription","⚠️ Attempted to subscribe to a cleaned up observable."),()=>{};if("function"!=typeof e)throw new s("Callback must be a function");return l.push(e),()=>this.unsubscribe(e)},this.unsubscribe=e=>{const t=l.indexOf(e);t>-1&&l.splice(t,1)},this.check=function(e){return new i(this,e)};const h=this;Object.defineProperty(h,"$value",{get:()=>h.val(),set:e=>(h.set(e),h)}),this.toString=function(){return"{{#ObItem::("+d+")}}"}}const u={isObservable:e=>e instanceof a||e instanceof i,isProxy:e=>e?.__isProxy__,isObservableChecker:e=>e instanceof i,isArray:e=>Array.isArray(e),isString:e=>"string"==typeof e,isNumber:e=>"number"==typeof e,isBoolean:e=>"boolean"==typeof e,isFunction:e=>"function"==typeof e,isAsyncFunction:e=>"function"==typeof e&&"AsyncFunction"===e.constructor.name,isObject:e=>"object"==typeof e,isJson:e=>"object"==typeof e&&null!==e&&"Object"===e.constructor.name&&!Array.isArray(e),isElement:e=>e instanceof HTMLElement||e instanceof DocumentFragment||e instanceof Text,isFragment:e=>e instanceof DocumentFragment,isStringOrObservable(e){return this.isString(e)||this.isObservable(e)},isValidChild(e){return null===e||this.isElement(e)||this.isObservable(e)||["string","number","boolean"].includes(typeof e)},isValidChildren(e){Array.isArray(e)||(e=[e]);return 0===e.filter(e=>!this.isValidChild(e)).length},validateChildren(e){Array.isArray(e)||(e=[e]);const t=e.filter(e=>!this.isValidChild(e));if(t.length>0)throw new s(`Invalid children detected: ${t.map(e=>typeof e).join(", ")}`);return e},containsObservables:e=>!!e&&(u.isObject(e)&&Object.values(e).some(e=>u.isObservable(e))),containsObservableReference:e=>!(!e||"string"!=typeof e)&&/\{\{#ObItem::\([0-9]+\)\}\}/.test(e),validateAttributes(e){if(!e||"object"!=typeof e)return e;const t=[],n=Object.keys(e).filter(e=>t.includes(e));return n.length>0&&r.warn("Validator",`Reserved attributes found: ${n.join(", ")}`),e},validateEventCallback(e){if("function"!=typeof e)throw new s("Event callback must be a function")}},c=["checked","selected","disabled","readonly","required","autofocus","multiple","autocomplete","hidden","contenteditable","spellcheck","translate","draggable","async","defer","autoplay","controls","loop","muted","download","reversed","open","default","formnovalidate","novalidate","scoped","itemscope","allowfullscreen","allowpaymentrequest","playsinline"],l=function(e,t){return e.replace(new RegExp(`^[${t}]+|[${t}]+$`,"g"),"")};function d(e){return new a(e)}d.computed=function(e,t=[]){const n=new a(e()),r=()=>n.set(e());if(u.isFunction(t)){if(!u.isObservable(t.$observer))throw new s("Observable.computed : dependencies must be valid batch function");return t.$observer.subscribe(r),n}return t.forEach(e=>e.subscribe(r)),n},d.batch=function(e){const t=d(0),n=function(){if(u.isAsyncFunction(e))return e(...arguments).then(()=>{t.trigger()}).catch(e=>{throw e});e(...arguments),t.trigger()};return n.$observer=t,n},d.getById=function(e){const t=o.getObservableById(parseInt(e));if(!t)throw new s("Observable.getById : No observable found with id "+e);return t},d.cleanup=function(e){e.cleanup()},d.value=function(e){if(u.isObservable(e))return e.val();if(u.isProxy(e))return e.$val();if(u.isArray(e)){const t=[];return e.forEach(e=>{t.push(d.value(e))}),t}return e},d.init=function(e){const t={};for(const n in e){const r=e[n];u.isJson(r)?t[n]=d.init(r):u.isArray(r)?t[n]=d.array(r):t[n]=d(r)}const n=function(){const e={};for(const n in t){const r=t[n];u.isObservable(r)?e[n]=r.val():u.isProxy(r)?e[n]=r.$val():e[n]=r}return e},r=function(){};return new Proxy(t,{get:(e,t)=>"__isProxy__"===t||("$val"===t?n:"$clone"===t?r:void 0!==e[t]?e[t]:void 0),set(e,t,n){void 0!==e[t]&&e[t].set(n)}})},d.object=d.init,d.json=d.init,d.update=function(e,t){for(const n in t){const r=e[n],o=t[n];if(u.isObservable(r)){if(u.isArray(o)){d.update(r,o);continue}r.set(o)}else u.isProxy(r)?d.update(r,o):e[n]=o}},d.array=function(e){if(!Array.isArray(e))throw new s("Observable.array : target must be an array");const t=d(e);["push","pop","shift","unshift","reverse","sort","splice"].forEach(e=>{t[e]=function(...n){const r=t.val(),o=r[e].apply(r,arguments);return t.trigger(),o}});return["map","filter","reduce","some","every","find","findIndex"].forEach(e=>{t[e]=function(n){return t.val()[e](n)}}),t},d.autoCleanup=function(e=!1,t={}){if(!e)return;const{interval:n=6e4,threshold:r=100}=t;window.addEventListener("beforeunload",()=>{o.cleanup()}),setInterval(()=>o.cleanObservables(r),n)};const h=function(e,t,n){n?e.classList.add(t):e.classList.remove(t)};function p(e,t){for(let n in t){const r=t[n];u.isObservable(r)?(h(e,n,r.val()),r.subscribe(t=>h(e,n,t))):h(e,n,r)}}function f(e,t){for(let n in t){const r=t[n];u.isObservable(r)?(e.style[n]=r.val(),r.subscribe(t=>{e.style[n]=t})):e.style[n]=r}}function b(e,t,n){const r=u.isObservable(n)?n.val():n;u.isBoolean(r)?e[t]=r:e[t]=r===e.value,u.isObservable(n)&&(["checked"].includes(t)&&e.addEventListener("input",()=>{u.isBoolean(r)?n.set(e[t]):n.set(e.value)}),n.subscribe(n=>{u.isBoolean(n)?e[t]=n:e[t]=n===e.value}))}function m(e,t,n){const r=n=>{"value"!==t?e.setAttribute(t,n):e.value=n};n.subscribe(r),r(n.val()),"value"===t&&e.addEventListener("input",()=>n.set(e.value))}const v={elements:new Map,observer:null,checkMutation:function(e,t,n={}){let r=null,o=0;const{leading:s=!0,trailing:i=!0,debounce:a=!1}=n;return function(...n){const u=Date.now();if(a)return clearTimeout(r),void(r=setTimeout(()=>e.apply(this,n),t));s&&u-o>=t&&(e.apply(this,n),o=u),i&&!r&&(r=setTimeout(()=>{e.apply(this,n),o=Date.now(),r=null},t-(u-o)))}}(function(){for(const[e,t]of v.elements.entries()){const n=document.body.contains(e);n&&!t.inDom?(t.inDom=!0,t.mounted.forEach(t=>t(e))):!n&&t.inDom&&(t.inDom=!1,t.unmounted.forEach(t=>t(e)))}},10,{debounce:!0}),watch:function(e){let t={};if(v.elements.has(e))t=v.elements.get(e);else{const n=document.body.contains(e);t={inDom:n,mounted:new Set,unmounted:new Set},v.elements.set(e,t)}return{watch:()=>v.elements.set(e,t),disconnect:()=>v.elements.delete(e),mounted:e=>t.mounted.add(e),unmounted:e=>t.unmounted.add(e)}}};v.observer=new MutationObserver(v.checkMutation),v.observer.observe(document.body,{childList:!0,subtree:!0});const y=e=>u.isFunction(e)?y(e()):u.isElement(e)?e:E(e);function g(e){const t=document.createDocumentFragment(),n=document.createComment("Anchor Start : "+e),o=document.createComment("/ Anchor End "+e);t.appendChild(n),t.appendChild(o),t.nativeInsertBefore=t.insertBefore,t.nativeAppendChild=t.appendChild;const s=function(e,n,r){e!==t?e.insertBefore(y(n),r):e.nativeInsertBefore(y(n),r)};return t.appendChild=function(e,n=null){const i=o.parentNode;if(i){if(n=n??o,u.isArray(e))return e.forEach(e=>{s(i,e,n)}),t;s(i,e,n)}else r.error("Anchor","Anchor : parent not found",e)},t.remove=function(e){if(o.parentNode===t)return;let r,s=n.nextSibling;for(;s!==o;)r=s.nextSibling,e?s.remove():t.nativeAppendChild(s),s=r;e&&(o.remove(),n.remove())},t.insertBefore=function(e,n=null){t.appendChild(e,n)},t.clear=function(){t.remove()},t.endElement=function(){return o},t.startElement=function(){return n},t}const w=function(){const e=[];return{list:()=>e,add:t=>e.push(t)}}(),O=function(e,t){const n=document.createTextNode("");return t.subscribe(e=>n.textContent=String(e)),n.textContent=t.val(),e&&e.appendChild(n),n},C=function(e,t){const n=document.createTextNode("");return n.textContent=String(t),e&&e.appendChild(n),n},E=function(e){return u.isObservable(e)?O(null,e):C(null,e)},S={createElement:e=>e?document.createElement(e):new g("Fragment"),processChildren(e,t){if(null===e)return;(Array.isArray(e)?e:[e]).forEach(e=>{null!==e&&(u.isString(e)&&u.isFunction(e.resolveObservableTemplate)&&(e=e.resolveObservableTemplate()),u.isFunction(e)?this.processChildren(e(),t):u.isArray(e)?this.processChildren(e,t):u.isElement(e)?t.appendChild(e):u.isObservable(e)?O(t,e):e&&C(t,e))})},processAttributes(e,t){u.isFragment(e)||t&&function(e,t){if(u.validateAttributes(t),!u.isObject(t))throw new s("Attributes must be an object");for(let n in t){const r=n.toLowerCase();let o=t[r];if(u.isString(o)&&u.isFunction(o.resolveObservableTemplate)&&(o=o.resolveObservableTemplate(),u.isArray(o))){const e=o.filter(e=>u.isObservable(e));o=d.computed(()=>o.map(e=>u.isObservable(e)?e.val():e).join(" ")||" ",e)}c.includes(r)?b(e,r,o):u.isObservable(o)?m(e,r,o):"class"===r&&u.isJson(o)?p(e,o):"style"===r&&u.isJson(o)?f(e,o):e.setAttribute(r,o)}}(e,t)},setup(e,t,r){e.nd={},function(e){e.nd||(e.nd={}),e.nd.on=function(t){for(const r in t){const o=t[r];n(e,r,o)}return e},e.nd.on.prevent=function(t){for(const r in t){const o=t[r];n(e,r,t=>(t.preventDefault(),o&&o(t),e))}return e};const t={click:t=>n(e,"click",t),focus:t=>n(e,"focus",t),blur:t=>n(e,"blur",t),input:t=>n(e,"input",t),change:t=>n(e,"change",t),keyup:t=>n(e,"keyup",t),keydown:t=>n(e,"keydown",t),beforeInput:t=>n(e,"beforeinput",t),mouseOver:t=>n(e,"mouseover",t),mouseOut:t=>n(e,"mouseout",t),mouseDown:t=>n(e,"mousedown",t),mouseUp:t=>n(e,"mouseup",t),mouseMove:t=>n(e,"mousemove",t),hover:(t,n)=>{e.addEventListener("mouseover",t),e.addEventListener("mouseout",n)},dropped:t=>n(e,"drop",t),submit:t=>n(e,"submit",t),dragEnd:t=>n(e,"dragend",t),dragStart:t=>n(e,"dragstart",t),drop:t=>n(e,"drop",t),dragOver:t=>n(e,"dragover",t),dragEnter:t=>n(e,"dragenter",t),dragLeave:t=>n(e,"dragleave",t)};for(let r in t)e.nd.on[r]=t[r],e.nd.on.prevent[r]=function(t){return n(e,r.toLowerCase(),e=>{e.preventDefault(),t&&t(e)}),e}}(e);const o="function"==typeof r?r(e):e;return function(e){e.nd.wrap=t=>{if(!u.isFunction(t))throw new s("Callback must be a function");return t&&t(e),e},e.nd.ref=(t,n)=>(t[n]=e,e);let t=null;e.nd.appendChild=function(t){u.isArray(t)?S.processChildren(t,e):(u.isFunction(t)&&(t=t(),S.processChildren(t(),e)),u.isElement(t)&&S.processChildren(t,e))},e.nd.lifecycle=function(n){return t=t||v.watch(e),n.mounted&&t.mounted(n.mounted),n.unmounted&&t.unmounted(n.unmounted),e},e.nd.mounted=n=>(t=t||v.watch(e),t.mounted(n),e),e.nd.unmounted=n=>(t=t||v.watch(e),t.unmounted(n),e)}(o),w.list().forEach(e=>{e?.element?.setup&&e.element.setup(o,t)}),o}};function A(e,t){const n=e.toLowerCase().trim(),o=function(e,o=null){try{if(u.isValidChildren(e)){const t=o;o=e,e=t}const r=S.createElement(n);return S.processAttributes(r,e),S.processChildren(o,r),S.setup(r,e,t)}catch(e){r.error("ElementCreation",`Error creating ${n}`,e)}};return o.hold=(e,t)=>()=>o(e,t),o}class I extends Error{constructor(e,t){super(`${e}\n\n${t.join("\n")}\n\n`)}}const k={string:e=>({name:e,type:"string",validate:e=>u.isString(e)}),number:e=>({name:e,type:"number",validate:e=>u.isNumber(e)}),boolean:e=>({name:e,type:"boolean",validate:e=>u.isBoolean(e)}),observable:e=>({name:e,type:"observable",validate:e=>u.isObservable(e)}),element:e=>({name:e,type:"element",validate:e=>u.isElement(e)}),function:e=>({name:e,type:"function",validate:e=>u.isFunction(e)}),object:e=>({name:e,type:"object",validate:e=>u.isObject(e)}),objectNotNull:e=>({name:e,type:"object",validate:e=>u.isObject(e)&&null!==e}),children:e=>({name:e,type:"children",validate:e=>u.validateChildren(e)}),attributes:e=>({name:e,type:"attributes",validate:e=>u.validateAttributes(e)}),optional:e=>({...e,optional:!0}),oneOf:(e,...t)=>({name:e,type:"oneOf",types:t,validate:e=>t.some(t=>t.validate(e))})},$=(e,t,n="Function")=>{if(!u.isArray(t))throw new s("withValidation : argSchema must be an array");return function(...r){return((e,t,n="Function")=>{if(!t)return;const r=[],o=t.filter(e=>!e.optional).length;if(e.length<o&&r.push(`${n}: Expected at least ${o} arguments, got ${e.length}`),t.forEach((t,o)=>{const s=o+1,i=e[o];if(void 0!==i){if(!t.validate(i)){const e=i?.constructor?.name||typeof i;r.push(`${n}: Invalid argument '${t.name}' at position ${s}, expected ${t.type}, got ${e}`)}}else t.optional||r.push(`${n}: Missing required argument '${t.name}' at position ${s}`)}),r.length>0)throw new I("Argument validation failed",r)})(r,t,e.name||n),e.apply(this,r)}};Function.prototype.args=function(...e){return $(this,e)},Function.prototype.errorBoundary=function(e){return(...t)=>{try{return this.apply(this,t)}catch(t){return e(t)}}},String.prototype.use=function(e){const t=this;return d.computed(()=>t.replace(/\$\{(.*?)}/g,(t,n)=>{const r=e[n];return u.isObservable(r)?r.val():r}),Object.values(e))},String.prototype.resolveObservableTemplate=function(){return u.containsObservableReference(this)?this.split(/(\{\{#ObItem::\([0-9]+\)\}\})/g).filter(Boolean).map(e=>{if(!u.containsObservableReference(e))return e;const[t,n]=e.match(/\{\{#ObItem::\(([0-9]+)\)\}\}/);return d.getById(n)}):this};const F=function(){const e=new Map;return{use(t){const{observer:n,subscribers:r}=e.get(t),o=d(n.val()),s=n.subscribe(e=>o.set(e)),i=o.subscribe(e=>n.set(e));return o.destroy=()=>{s(),i(),o.cleanup()},r.add(o),o},follow(e){return this.use(e)},create(t,n){const r=d(n);return e.set(t,{observer:r,subscribers:new Set}),r},get(t){const n=e.get(t);return n?n.observer:null},getWithSubscribers:t=>e.get(t),delete(t){const n=e.get(t);n&&(n.observer.cleanup(),n.subscribers.forEach(e=>e.destroy()),n.observer.clear())}}}();const x=function(e,t,n=null){if(!u.isObservable(e))return r.warn("ShowIf","ShowIf : condition must be an Observable / "+n,e);const o=new g("Show if : "+(n||""));let s=null;const i=()=>s||(s="function"==typeof t?t():t,u.isStringOrObservable(s)&&(s=E(s)),s);return e.val()&&o.appendChild(i()),e.subscribe(e=>{e?o.appendChild(i()):o.remove()}),o},R=function(e,t){if(!u.isObservable(e))throw new s("Toggle : condition must be an Observable");const n=new g,r=new Map,o=function(e){if(r.has(e))return r.get(e);let n=t[e];return n?(u.isFunction(n)&&(n=n()),r.set(e,n),n):null},i=e.val(),a=o(i);return a&&n.appendChild(a),e.subscribe(e=>{const t=o(e);n.remove(),t&&n.appendChild(t)}),n},q=function(e,t,n){if(!u.isObservable(e))throw new s("Toggle : condition must be an Observable");return R(e,{true:t,false:n})},T=A("div"),D=A("span"),j=A("label"),L=A("p"),B=L,M=A("strong"),N=A("h1"),H=A("h2"),P=A("h3"),_=A("h4"),V=A("h5"),U=A("h6"),z=A("br"),J=A("a"),W=A("pre"),K=A("code"),Q=A("blockquote"),G=A("hr"),X=A("em"),Y=A("small"),Z=A("mark"),ee=A("del"),te=A("ins"),ne=A("sub"),re=A("sup"),oe=A("abbr"),se=A("cite"),ie=A("q"),ae=A("dl"),ue=A("dt"),ce=A("dd"),le=A("form",function(e){return e.submit=function(t){return"function"==typeof t?(e.on.submit(e=>{e.preventDefault(),t(e)}),e):(this.setAttribute("action",t),e)},e.multipartFormData=function(){return this.setAttribute("enctype","multipart/form-data"),e},e.post=function(t){return this.setAttribute("method","post"),this.setAttribute("action",t),e},e.get=function(e){this.setAttribute("method","get"),this.setAttribute("action",e)},e}),de=A("input"),he=A("textarea"),pe=he,fe=A("select"),be=A("fieldset"),me=A("option"),ve=A("legend"),ye=A("datalist"),ge=A("output"),we=A("progress"),Oe=A("meter"),Ce=A("button"),Ee=A("main"),Se=A("section"),Ae=A("article"),Ie=A("aside"),ke=A("nav"),$e=A("figure"),Fe=A("figcaption"),xe=A("header"),Re=A("footer"),qe=A("img"),Te=function(e,t){return qe({src:e,...t})},De=A("details"),je=A("summary"),Le=A("dialog"),Be=A("menu"),Me=A("ol"),Ne=A("ul"),He=A("li"),Pe=A("audio"),_e=A("video"),Ve=A("source"),Ue=A("track"),ze=A("canvas"),Je=A("svg"),We=A("time"),Ke=A("data"),Qe=A("address"),Ge=A("kbd"),Xe=A("samp"),Ye=A("var"),Ze=A("wbr"),et=A("caption"),tt=A("table"),nt=A("thead"),rt=A("tfoot"),ot=A("tbody"),st=A("tr"),it=st,at=A("th"),ut=at,ct=at,lt=A("td"),dt=lt,ht=A("");var pt=Object.freeze({__proto__:null,Abbr:oe,Address:Qe,Anchor:g,Article:Ae,Aside:Ie,AsyncImg:function(e,t,n,r){const o=Te(t||e,n),i=new Image;return i.onload=()=>{u.isFunction(r)&&r(null,o),o.src=e},i.onerror=()=>{u.isFunction(r)&&r(new s("Image not found"))},u.isObservable(e)&&e.subscribe(e=>{i.src=e}),i.src=e,o},Audio:Pe,BaseImage:qe,Blockquote:Q,Br:z,Button:Ce,Canvas:ze,Caption:et,Checkbox:e=>de({type:"checkbox",...e}),Cite:se,Code:K,ColorInput:e=>de({type:"color",...e}),Data:Ke,Datalist:ye,DateInput:e=>de({type:"date",...e}),DateTimeInput:e=>de({type:"datetime-local",...e}),Dd:ce,Del:ee,Details:De,Dialog:Le,Div:T,Dl:ae,Dt:ue,Em:X,EmailInput:e=>de({type:"email",...e}),FieldSet:be,FigCaption:Fe,Figure:$e,FileInput:e=>de({type:"file",...e}),Footer:Re,ForEach:function(e,t,n){const o=new g("ForEach"),s=o.endElement(),i=o.startElement();let a=new Map;const c=new Set,l=(e,o)=>{const s=((e,t,n)=>{if(u.isFunction(n))return n(e,t);if(u.isObservable(e)){const r=e.val();return r&&n?r[n]:t}return e[n]??t})(e,o,n);if(a.has(s)){const e=a.get(s);e.indexObserver.set(o),e.isNew=!1}else try{const n=d(o);let r=t(e,n);u.isStringOrObservable(r)&&(r=E(r)),a.set(s,{isNew:!0,child:r,indexObserver:n})}catch(e){throw r.error("ForEach",`Error creating element for key ${s}`,e),e}return s},h=()=>{const t=u.isObservable(e)?e.val():e;if(c.clear(),Array.isArray(t))t.forEach((e,t)=>c.add(l(e,t)));else for(const e in t)c.add(l(t[e],e));((e,t)=>{const n=[];for(const[r,o]of e.entries())t.has(r)||n.push({key:r,cacheItem:o});0!==n.length&&n.forEach(({key:t,cacheItem:n})=>{n.child.remove(),n.indexObserver.cleanup(),e.delete(t)})})(a,c),(()=>{const e=s.parentNode;if(!e)return;let t=i;const n=[],r=[];let u=null,l=e=>{u&&(n.push({child:u,before:e}),u=null)};const d=Array.from(c);for(let e=0;e<d.length;e++){const n=d[e],o=a.get(n);if(!o)continue;if(t&&t.nextSibling===o.child){t=o.child,l(o.child);continue}if(o.isNew){u=u||document.createDocumentFragment(),u.append(o.child),o.isNew=!1;continue}l(o.child);const s=a.get(d[e+1])?.child;s&&o.child.nextSibling!==s&&r.push({child:o.child,before:s}),t=o.child}l(s),n.forEach(({child:t,before:n})=>{n?e.insertBefore(t,n):o.appendChild(t)}),r.forEach(({child:t,before:n})=>{e.insertBefore(t,n)}),l=null})()};return h(),u.isObservable(e)&&e.subscribe(h),o},Form:le,Fragment:ht,H1:N,H2:H,H3:P,H4:_,H5:V,H6:U,Header:xe,HiddenInput:e=>de({type:"hidden",...e}),HideIf:function(e,t,n){const r=d(!e.val());return e.subscribe(e=>r.set(!e)),x(r,t,n)},HideIfNot:function(e,t,n){return x(e,t,n)},Hr:G,Img:Te,Input:de,Ins:te,Kbd:Ge,Label:j,LazyImg:function(e,t){return Te(e,{...t,loading:"lazy"})},Legend:ve,Link:J,ListItem:He,Main:Ee,Mark:Z,Match:R,Menu:Be,Meter:Oe,MonthInput:e=>de({type:"month",...e}),NativeDocumentFragment:g,Nav:ke,NumberInput:e=>de({type:"number",...e}),Option:me,OrderedList:Me,Output:ge,P:L,Paragraph:B,PasswordInput:e=>de({type:"password",...e}),Pre:W,Progress:we,Quote:ie,Radio:e=>de({type:"radio",...e}),RangeInput:e=>de({type:"range",...e}),ReadonlyInput:e=>de({readonly:!0,...e}),Samp:Xe,SearchInput:e=>de({type:"search",...e}),Section:Se,Select:fe,ShowIf:x,SimpleButton:(e,t)=>Ce(e,{type:"button",...t}),Small:Y,Source:Ve,Span:D,Strong:M,Sub:ne,SubmitButton:(e,t)=>Ce(e,{type:"submit",...t}),Summary:je,Sup:re,Svg:Je,Switch:q,TBody:ot,TBodyCell:dt,TFoot:rt,TFootCell:ct,THead:nt,THeadCell:ut,TRow:it,Table:tt,Td:lt,TelInput:e=>de({type:"tel",...e}),TextArea:he,TextInput:pe,Th:at,Time:We,TimeInput:e=>de({type:"time",...e}),Tr:st,Track:Ue,UnorderedList:Ne,UrlInput:e=>de({type:"url",...e}),Var:Ye,Video:_e,Wbr:Ze,WeekInput:e=>de({type:"week",...e}),When:function(e){if(!u.isObservable(e))throw new s("When : condition must be an Observable");let t=null,n=null;return{show(e){return t=e,this},otherwise:r=>(n=r,q(e,t,n))}}});const ft={};function bt(e,t,n={}){e="/"+l(e,"/");let r=null,o=n.name||null;const s=n.middlewares||[],i=n.shouldRebuild||!1,a=n.with||{},u={},c=[],d=e=>{if(!e)return null;const[t,n]=e.split(":");let r=a[t];return!r&&n&&(r=ft[n]),r||(r="[^/]+"),r=r.replace("(","(?:"),{name:t,pattern:`(${r})`}},h=()=>{if(r)return r;const t=e.replace(/\{(.*?)}/gi,(e,t)=>{const n=d(t);return n&&n.pattern?(u[n.name]=n.pattern,c.push(n.name),n.pattern):e});return r=new RegExp("^"+t+"$"),r};this.name=()=>o,this.component=()=>t,this.middlewares=()=>s,this.shouldRebuild=()=>i,this.path=()=>e,this.match=function(e){e="/"+l(e,"/");if(!h().exec(e))return!1;const t={};return h().exec(e).forEach((e,n)=>{if(n<1)return;const r=c[n-1];t[r]=e}),t},this.url=function(t){const n=e.replace(/\{(.*?)}/gi,(e,n)=>{const r=d(n);if(t.params&&t.params[r.name])return t.params[r.name];throw new Error(`Missing parameter '${r.name}'`)}),r="object"==typeof t.query?new URLSearchParams(t.query).toString():null;return(t.basePath?t.basePath:"")+(r?`${n}?${r}`:n)}}class mt extends Error{constructor(e,t){super(e),this.context=t}}const vt=(e,t)=>{const n=[];return e.forEach(e=>{n.push(l(e.suffix,"/"))}),n.push(l(t,"/")),n.join("/")},yt=(e,t)=>{const n=[];return e.forEach(e=>{e.options.middlewares&&n.push(...e.options.middlewares)}),t&&n.push(...t),n},gt=(e,t)=>{const n=[];return e.forEach(e=>{e.options?.name&&n.push(e.options.name)}),t&&n.push(t),n.join(".")};function wt(){const e=[];let t=0;const n=n=>{const o=t+n;if(!e[o])return;t=o;const{route:s,params:i,query:a,path:u}=e[o];r(u)},r=e=>{window.location.replace(`${window.location.pathname}${window.location.search}#${e}`)},o=()=>window.location.hash.slice(1);this.push=function(n){const{route:s,params:i,query:a,path:u}=this.resolve(n);u!==o()&&(e.splice(t+1),e.push({route:s,params:i,query:a,path:u}),t++,r(u))},this.replace=function(n){const{route:r,params:s,query:i,path:a}=this.resolve(n);a!==o()&&(e[t]={route:r,params:s,query:i,path:a})},this.forward=function(){return t<e.length-1&&n(1)},this.back=function(){return t>0&&n(-1)},this.init=function(n){window.addEventListener("hashchange",()=>{const{route:e,params:t,query:n,path:r}=this.resolve(o());this.handleRouteChange(e,t,n,r)});const{route:r,params:s,query:i,path:a}=this.resolve(n||o());e.push({route:r,params:s,query:i,path:a}),t=0,this.handleRouteChange(r,s,i,a)}}function Ot(){this.push=function(e){try{const{route:t,path:n,params:r,query:o}=this.resolve(e);if(window.history.state&&window.history.state.path===n)return;window.history.pushState({name:t.name(),params:r,path:n},t.name()||n,n),this.handleRouteChange(t,r,o,n)}catch(e){r.error("HistoryRouter","Error in pushState",e)}},this.replace=function(e){const{route:t,path:n,params:o}=this.resolve(e);try{window.history.replaceState({name:t.name(),params:o,path:n},t.name()||n,n),this.handleRouteChange(t,o,{},n)}catch(e){r.error("HistoryRouter","Error in replaceState",e)}},this.forward=function(){window.history.forward()},this.back=function(){window.history.back()},this.init=function(e){window.addEventListener("popstate",e=>{try{if(!e.state||!e.state.path)return;const t=e.state.path,{route:n,params:r,query:o,path:s}=this.resolve(t);if(!n)return;this.handleRouteChange(n,r,o,s)}catch(e){r.error("HistoryRouter","Error in popstate event",e)}});const{route:t,params:n,query:o,path:s}=this.resolve(e||window.location.pathname+window.location.search);this.handleRouteChange(t,n,o,s)}}function Ct(){const e=[];let t=0;const n=n=>{const r=t+n;if(!e[r])return;t=r;const{route:o,params:s,query:i,path:a}=e[r];this.handleRouteChange(o,s,i,a)};this.push=function(n){const{route:r,params:o,query:s,path:i}=this.resolve(n);e[t]&&e[t].path===i||(e.splice(t+1),e.push({route:r,params:o,query:s,path:i}),t++,this.handleRouteChange(r,o,s,i))},this.replace=function(n){const{route:r,params:o,query:s,path:i}=this.resolve(n);e[t]={route:r,params:o,query:s,path:i},this.handleRouteChange(r,o,s,i)},this.forward=function(){return t<e.length-1&&n(1)},this.back=function(){return t>0&&n(-1)},this.init=function(n){const r=n||window.location.pathname+window.location.search,{route:o,params:s,query:i,path:a}=this.resolve(r);e.push({route:o,params:s,query:i,path:a}),t=0,this.handleRouteChange(o,s,i,a)}}const Et="default";function St(e={}){const t=[],n={},o=[],s=[],i={route:null,params:null,query:null,path:null,hash:null};if("hash"===e.mode)wt.apply(this,[]);else if("history"===e.mode)Ot.apply(this,[]);else{if("memory"!==e.mode)throw new mt("Invalid router mode "+e.mode);Ct.apply(this,[])}const a=function(e,t){for(const n of s)try{n(e),t&&t(e)}catch(e){r.warn("Route Listener","Error in listener:",e)}};this.routes=()=>[...t],this.currentState=()=>({...i}),this.add=function(e,r,s){const i=new bt(vt(o,e),r,{...s,middlewares:yt(o,s?.middlewares||[]),name:s?.name?gt(o,s.name):null});return t.push(i),i.name()&&(n[i.name()]=i),this},this.group=function(e,t,n){if(!u.isFunction(n))throw new mt("Callback must be a function");return o.push({suffix:e,options:t}),n(),o.pop(),this},this.generateUrl=function(e,t={},r={}){const o=n[e];if(!o)throw new mt(`Route not found for name: ${e}`);return o.url({params:t,query:r})},this.resolve=function(e){if(u.isJson(e)){const t=n[e.name];if(!t)throw new mt(`Route not found for name: ${e.name}`);return{route:t,params:e.params,query:e.query,path:t.url({...e})}}const[r,o]=e.split("?"),s="/"+l(r,"/");let i,a=null;for(const e of t)if(i=e.match(s),i){a=e;break}if(!a)throw new mt(`Route not found for url: ${r}`);const c={};if(o){const e=new URLSearchParams(o).entries();for(const[t,n]of e)c[t]=n}return{route:a,params:i,query:c,path:e}},this.subscribe=function(e){if(!u.isFunction(e))throw new mt("Listener must be a function");return s.push(e),()=>{s.splice(s.indexOf(e),1)}},this.handleRouteChange=function(e,t,n,r){i.route=e,i.params=t,i.query=n,i.path=r;const o=[...e.middlewares(),a];let s=0;const u={...i},c=e=>{if(s++,!(s>=o.length))return o[s](e||u,c)};return o[s](u,c)}}function At(e,t){const{to:n,href:r,...o}=e,s=n||r;if(u.isString(s)){const e=St.get();return J({...o,href:s},t).nd.on.prevent.click(()=>{e.push(s)})}const i=s.router||Et,a=St.get(i);if(console.log(i),!a)throw new mt('Router not found "'+i+'" for link "'+s.name+'"');const c=a.generateUrl(s.name,s.params,s.query);return J({...o,href:c},t).nd.on.prevent.click(()=>{a.push(c)})}St.routers={},St.create=function(t,n){if(!u.isFunction(n))throw r.error("Router","Callback must be a function",e),new mt("Callback must be a function");const o=new St(t);return St.routers[t.name||Et]=o,n(o),o.init(t.entry),o.mount=function(e){if(u.isString(e)){const t=document.querySelector(e);if(!t)throw new mt(`Container not found for selector: ${e}`);e=t}else if(!u.isElement(e))throw new mt("Container must be a string or an Element");return function(e,t){const n=new Map,r=function(e){t.innerHTML="",t.appendChild(e)},o=function(e){if(!e.route)return;const{route:t,params:o,query:s,path:i}=e;if(n.has(i)){const e=n.get(i);return void r(e)}const a=t.component()({params:o,query:s});n.set(i,a),r(a)};return e.subscribe(o),o(e.currentState()),t}(o,e)},o},St.get=function(e){const t=St.routers[e||Et];if(!t)throw new mt(`Router not found for name: ${e}`);return t},St.push=function(e,t=null){return St.get(t).push(e)},St.replace=function(e,t=null){return St.get(t).replace(e)},St.forward=function(e=null){return St.get(e).forward()},St.back=function(e=null){return St.get(e).back()},At.blank=function(e,t){return J({...e,target:"_blank"},t)};var It=Object.freeze({__proto__:null,Link:At,RouteParamPatterns:ft,Router:St});return t.ArgTypes=k,t.ElementCreator=S,t.HtmlElementWrapper=A,t.Observable=d,t.Store=F,t.elements=pt,t.router=It,t.withValidation=$,t}({});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "native-document",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -203,7 +203,7 @@ Observable.array = function(target) {
203
203
  };
204
204
  });
205
205
 
206
- const overrideMethods = ['map', 'filter', 'reduce', 'some', 'every', 'find'];
206
+ const overrideMethods = ['map', 'filter', 'reduce', 'some', 'every', 'find', 'findIndex'];
207
207
  overrideMethods.forEach((method) => {
208
208
  observer[method] = function(callback) {
209
209
  return observer.val()[method](callback);
@@ -7,11 +7,15 @@
7
7
  export default function ObservableChecker($observable, $checker) {
8
8
  this.observable = $observable;
9
9
  this.checker = $checker;
10
+ const $unSubscriptions = [];
10
11
 
11
12
  this.subscribe = function(callback) {
12
- return $observable.subscribe((value) => {
13
+ const unSubscribe = $observable.subscribe((value) => {
13
14
  callback && callback($checker(value));
14
15
  });
16
+ $unSubscriptions.push(unSubscribe);
17
+
18
+ return unSubscribe;
15
19
  };
16
20
 
17
21
  this.val = function() {
@@ -26,9 +30,9 @@ export default function ObservableChecker($observable, $checker) {
26
30
  };
27
31
  this.trigger = function() {
28
32
  return $observable.trigger();
29
- }
33
+ };
30
34
 
31
35
  this.cleanup = function() {
32
- return $observable.cleanup();
33
- }
36
+ $unSubscriptions.forEach(unSubscription => unSubscription());
37
+ };
34
38
  }
@@ -4,6 +4,7 @@ import {createTextNode} from "../../wrappers/HtmlElementWrapper";
4
4
  import Validator from "../../utils/validator";
5
5
  import {throttle} from "../../utils/helpers.js";
6
6
  import Anchor from "../anchor";
7
+ import DebugManager from "../../utils/debug-manager";
7
8
 
8
9
 
9
10
  /**
@@ -28,12 +29,21 @@ const getKey = (item, defaultKey, key) => {
28
29
  * @param {Set} keyIds
29
30
  */
30
31
  const cleanBlockByCache = (cache, keyIds) => {
31
- for(const [key, {child}] of cache.entries()) {
32
+ const toRemove = [];
33
+ for(const [key, cacheItem] of cache.entries()) {
32
34
  if(keyIds.has(key)) {
33
35
  continue;
34
36
  }
35
- child.remove();
37
+ toRemove.push({ key, cacheItem });
36
38
  }
39
+ if(toRemove.length === 0) {
40
+ return;
41
+ }
42
+ toRemove.forEach(({ key, cacheItem }) => {
43
+ cacheItem.child.remove();
44
+ cacheItem.indexObserver.cleanup();
45
+ cache.delete(key);
46
+ });
37
47
  }
38
48
 
39
49
  /**
@@ -46,33 +56,102 @@ const cleanBlockByCache = (cache, keyIds) => {
46
56
  export function ForEach(data, callback, key) {
47
57
  const element = new Anchor('ForEach');
48
58
  const blockEnd = element.endElement();
59
+ const blockStart = element.startElement();
49
60
 
50
61
  let cache = new Map();
62
+ const keyIds = new Set();
51
63
 
52
64
  const handleContentItem = (item, indexKey) => {
53
65
  const keyId = getKey(item, indexKey, key);
54
66
 
55
67
  if(cache.has(keyId)) {
56
- cache.get(keyId).indexObserver.set(indexKey);
68
+ const cacheItem = cache.get(keyId);
69
+ cacheItem.indexObserver.set(indexKey);
70
+ cacheItem.isNew = false;
57
71
  }
58
72
  else {
59
- const indexObserver = Observable(indexKey);
60
- let child = callback(item, indexObserver);
61
- if(Validator.isStringOrObservable(child)) {
62
- child = createTextNode(child);
73
+
74
+ try {
75
+ const indexObserver = Observable(indexKey);
76
+ let child = callback(item, indexObserver);
77
+ if(Validator.isStringOrObservable(child)) {
78
+ child = createTextNode(child);
79
+ }
80
+ cache.set(keyId, { isNew: true, child, indexObserver});
81
+ } catch (e) {
82
+ DebugManager.error('ForEach', `Error creating element for key ${keyId}` , e);
83
+ throw e;
63
84
  }
64
- cache.set(keyId, { child, indexObserver});
65
85
  }
66
86
  return keyId;
67
- }
68
- const keyIds = new Set();
87
+ };
69
88
 
70
- const buildContent = () => {
71
- const items = (Validator.isObservable(data)) ? data.val() : data;
89
+ const batchDOMUpdates = () => {
72
90
  const parent = blockEnd.parentNode;
73
91
  if(!parent) {
74
92
  return;
75
93
  }
94
+
95
+ let previousElementSibling = blockStart;
96
+ const elementsToInsert = [];
97
+ const elementsToMove = [];
98
+ let fragment = null;
99
+
100
+ let saveFragment = (beforeTarget) => {
101
+ if(fragment) {
102
+ elementsToInsert.push({ child: fragment, before: beforeTarget });
103
+ fragment = null;
104
+ }
105
+ };
106
+
107
+ const keyIdsArray = Array.from(keyIds);
108
+ for(let i = 0; i < keyIdsArray.length; i++) {
109
+ const itemKey = keyIdsArray[i];
110
+ const cacheItem = cache.get(itemKey);
111
+ if(!cacheItem) {
112
+ continue;
113
+ }
114
+
115
+ if(previousElementSibling && previousElementSibling.nextSibling === cacheItem.child) {
116
+ previousElementSibling = cacheItem.child;
117
+ saveFragment(cacheItem.child);
118
+ continue;
119
+ }
120
+ if(cacheItem.isNew) {
121
+ fragment = fragment || document.createDocumentFragment();
122
+ fragment.append(cacheItem.child);
123
+ cacheItem.isNew = false;
124
+ continue;
125
+ }
126
+ saveFragment(cacheItem.child);
127
+ const nextChild = cache.get(keyIdsArray[i + 1])?.child;
128
+ if(nextChild) {
129
+ if(cacheItem.child.nextSibling !== nextChild) {
130
+ elementsToMove.push({ child: cacheItem.child, before: nextChild });
131
+ }
132
+ }
133
+
134
+ previousElementSibling = cacheItem.child;
135
+ }
136
+ saveFragment(blockEnd);
137
+
138
+ elementsToInsert.forEach(({ child, before }) => {
139
+ if(before) {
140
+ parent.insertBefore(child, before);
141
+ } else {
142
+ element.appendChild(child);
143
+ }
144
+ });
145
+
146
+ elementsToMove.forEach(({ child, before }) => {
147
+ parent.insertBefore(child, before);
148
+ })
149
+ saveFragment = null;
150
+
151
+ };
152
+
153
+ const buildContent = () => {
154
+ const items = (Validator.isObservable(data)) ? data.val() : data;
76
155
  keyIds.clear();
77
156
  if(Array.isArray(items)) {
78
157
  items.forEach((item, index) => keyIds.add(handleContentItem(item, index)));
@@ -83,25 +162,13 @@ export function ForEach(data, callback, key) {
83
162
  }
84
163
 
85
164
  cleanBlockByCache(cache, keyIds);
86
- let nextElementSibling = blockEnd;
87
- for(const item of [...keyIds].reverse()) {
88
- const { child } = cache.get(item);
89
- if(child) {
90
- if(nextElementSibling && nextElementSibling.previousSibling === child) {
91
- nextElementSibling = child;
92
- continue;
93
- }
94
- parent.insertBefore(child, nextElementSibling);
95
- nextElementSibling = child;
96
- }
97
- }
165
+
166
+ batchDOMUpdates();
98
167
  };
99
168
 
100
169
  buildContent();
101
170
  if(Validator.isObservable(data)) {
102
- data.subscribe(throttle((newValue, oldValue) => {
103
- buildContent(newValue, oldValue);
104
- }, 50, { debounce: true }))
171
+ data.subscribe(buildContent)
105
172
  }
106
173
  return element;
107
174
  }