@twobirds/microcomponents 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -34
- package/dist/MC.min.js +1 -1
- package/dist/autoload.min.js +1 -1
- package/dist/cli/create.d.ts +53 -0
- package/dist/cli/create.d.ts.map +1 -0
- package/dist/cli/create.js +419 -0
- package/dist/cli/dispatch.d.ts +43 -0
- package/dist/cli/dispatch.d.ts.map +1 -0
- package/dist/cli/dispatch.js +287 -0
- package/dist/cli/index.d.ts +12 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +12 -0
- package/dist/cli/scaffold.d.ts +68 -0
- package/dist/cli/scaffold.d.ts.map +1 -0
- package/dist/cli/scaffold.js +109 -0
- package/dist/cli/writeScaffold.d.ts +66 -0
- package/dist/cli/writeScaffold.d.ts.map +1 -0
- package/dist/cli/writeScaffold.js +114 -0
- package/dist/core/MC.d.ts +50 -9
- package/dist/core/MC.d.ts.map +1 -1
- package/dist/core/MC.js +78 -33
- package/dist/core/elements.d.ts +11 -8
- package/dist/core/elements.d.ts.map +1 -1
- package/dist/core/elements.js +12 -7
- package/dist/core/mcGuards.d.ts +2 -2
- package/dist/elements.min.js +1 -1
- package/dist/formValues.min.js +1 -1
- package/dist/microcomponents.min.js +1 -1
- package/dist/observables.min.js +1 -1
- package/dist/state/formValues.d.ts +11 -5
- package/dist/state/formValues.d.ts.map +1 -1
- package/dist/state/formValues.js +18 -11
- package/dist/state/observables.d.ts +30 -13
- package/dist/state/observables.d.ts.map +1 -1
- package/dist/state/observables.js +64 -35
- package/dist/state/placeholders.d.ts.map +1 -1
- package/dist/state/placeholders.js +16 -11
- package/dist/types/mcTypes.d.ts +16 -7
- package/dist/types/mcTypes.d.ts.map +1 -1
- package/dist/utils/autoload.d.ts +6 -3
- package/dist/utils/autoload.d.ts.map +1 -1
- package/dist/utils/autoload.js +2 -2
- package/dist/utils/events.d.ts +21 -28
- package/dist/utils/events.d.ts.map +1 -1
- package/dist/utils/events.js +23 -29
- package/dist/utils/helpers.d.ts +19 -19
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/utils/helpers.js +19 -19
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -2
- package/dist/utils/resolveComponentPath.d.ts +36 -0
- package/dist/utils/resolveComponentPath.d.ts.map +1 -0
- package/dist/utils/resolveComponentPath.js +39 -0
- package/package.json +19 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e){return`_mc`+e[0].toUpperCase()+e.substring(1)}function t(e,t){let n=t.toLowerCase();return`on`+n in e?n:`_mc`+t[0].toUpperCase()+t.substring(1)}function n(e,r,i){if(e){if(typeof e==`string`){document.querySelectorAll(e).forEach(e=>n(e,r,i));return}e.removeEventListener(t(e,r),i)}}function r(e,n,i,a=!1){if(e){if(typeof e==`string`){document.querySelectorAll(e).forEach(e=>r(e,n,i));return}return e.addEventListener(t(e,n),i,{capture:!1,once:a}),i}}function i(e,t,n){if(e){if(typeof e==`string`){document.querySelectorAll(e).forEach(e=>i(e,t,n));return}return r(e,t,n,!0),n}}var a=class{stopped=!1;constructor(){}stop(){this.stopped=!0}};function o(e,n,r={},i=`l`,s){if(!e)return;if(typeof e==`string`){document.querySelectorAll(e).forEach(e=>o(e,n,r,i));return}let c=/^_mc/.test(n)?n:t(e,n),l=s||new a,u=new CustomEvent(c,{detail:{data:r,control:l},bubbles:!1});l.stopped||/l/.test(i)&&(e.dispatchEvent(u),l.stopped)||/[ud]/.test(i)&&queueMicrotask(()=>{if(i.indexOf(`u`)>-1&&o(e.parentElement,c,r,`lu`,l),i.indexOf(`d`)>-1)for(let t of e.children)o(t,c,r,`ld`)})}function s(){return typeof window<`u`&&window.document!==void 0}function c(e){return typeof e==`object`&&!!e&&e.constructor===Object}function l(e){let t={},n=Object.keys(e).sort();for(let r=0;r<n.length;r++){let i=n[r],a=e[i];c(a)?t[i]=l(a):t[i]=a}return t}function u(e,t=!0){let n={},r=e,i=Object.getOwnPropertyNames(e);for(let e=0;e<i.length;e++){let t=i[e],a=r[t];if(a instanceof Object){let e=u(a,!1);for(let r in e)n[t+`.`+r]=e[r]}else n[t]=a}return t?l(n):n}function d(e,t){if(e===t||e!==e&&t!==t)return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t||e.constructor!==t.constructor)return!1;if(e instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp)return e.toString()===t.toString();if(Array.isArray(e)){let n=t;if(e.length!==n.length)return!1;for(let t=0;t<e.length;t++)if(!d(e[t],n[t]))return!1;return!0}let n=e,r=t,i=Object.keys(n);if(i.length!==Object.keys(r).length)return!1;for(let e=0;e<i.length;e++){let t=i[e];if(!Object.prototype.hasOwnProperty.call(r,t)||!d(n[t],r[t]))return!1}return!0}function f(e,t={}){let n=t,r=typeof e==`string`?e.split(`.`):e;if(!(!n||!r[0]||!n[r[0]])){if(r.length>1){let e=n[r[0]];return c(e)?f(r.slice(1),e):void 0}return n[r[0]]}}function p(e,t,...n){let r=[e,t,...n];if(r.length>2){for(;r.length>1;)r[0]=p(r[0],r[1]),r.splice(1,1);return r[0]}if(typeof e==`string`){let n=e;return e.match(/\{[^\{\}]*\}/g)?.forEach(e=>{let r=f(e.substring(1,e.length-1),t);r!==void 0&&(n=n.replace(e,String(r)))}),n}else if(c(e)){let n=e;Object.keys(n).forEach(e=>{Object.prototype.hasOwnProperty.call(n,e)&&(n[e]=p(n[e],t))})}return e}function m(e){return e.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``)}function h(e,t){let n;return(...r)=>{clearTimeout(n),n=setTimeout(()=>{e(...r)},t)}}function ee(e){let t=document.createElement(`template`);return e=e.replace(/<([A-Za-z0-9\-]*)([^>\/]*)(\/>)/gi,`<$1$2></$1>`),t.innerHTML=e,t.content.normalize(),Array.from(t.content.childNodes)}function g(e,t){let n=Object.getOwnPropertyDescriptors(e);for(let[e,r]of Object.entries(n))(`get`in r||`set`in r)&&Object.defineProperty(t,e,r)}var _=new WeakMap;function v(e,t){let n=_.get(e)??new Set;if(n.has(t))return e.adoptedStyleSheets[0];n.add(t),_.set(e,n);let r=new CSSStyleSheet;return r.replaceSync(t),e.adoptedStyleSheets.push(r),r}function y(e,t){let n=e.target,r=n.shadowRoot;!r&&Object.keys(t).some(e=>e.indexOf(`shadow`)===0)&&(r=n.attachShadow({mode:`open`})),Object.keys(t).forEach(i=>{switch(i){case`css`:v(document,t[i]);break;case`targetCss`:v(document,t[i]);break;case`shadowCss`:v(r,t[i]);break;case`shadowHtml`:r.innerHTML=t[i],x(r,e);break;case`targetHtml`:n.innerHTML=t[i],x(n,e);break}})}function b(e,t){let n=t=>{let n=t.match(/^([a-z]+)([A-Z][a-z]*)$/);return n?`./${e.replace(/-/g,`/`)}.${n[1]}.${n[2].toLowerCase()}`:`./${e.replace(/-/g,`/`)}.${t.toLowerCase()}`};return Promise.all(t.map(async e=>{let t=n(e);try{let n=await fetch(t);if(!n.ok)return`file not found: ${t}`;if(t.endsWith(`json`)){let r=await n.text();try{return JSON.parse(r)}catch{return console.error(`could not JSON.parse() asset '${e}' from ${t}:\n`,r),null}}return n.text()}catch{return`file not found: ${t}`}}))}function x(e,t){let n=[...e.querySelectorAll(`*`)];for(let e of n){if(!(e instanceof HTMLElement))continue;let n=[...e.attributes];for(let i of n){let n=i.name.toLowerCase();if(!(`on`+n in e))continue;let a=i.value.trim().split(`|`);if(a.length<2)continue;let[s,c,l]=a;e.removeAttribute(i.name);let u;if(l)try{u=JSON.parse(l)}catch{u=l}s===`this`||s===``?r(e,n,()=>t.trigger(c,u)):r(e,n,()=>o(s,c,u))}}}function S(e,t){return typeof HTMLElement<`u`&&e instanceof HTMLElement&&`_mc`in e&&(t===void 0||t in e._mc)}function C(e,t,n={}){let r=e;`_mc`in e||(r._mc=new k(e));let i=r._mc;return t.length&&!i[t]&&(i[t]=n,e instanceof HTMLElement&&!e.getAttribute(`data-mc`)&&e.setAttribute(`data-mc`,``)),r}function w(e,t){if(!t)return;let n=e._mc;n&&(n[t]&&delete n[t],!Object.keys(n).length&&e instanceof HTMLElement&&e.hasAttribute(`data-mc`)&&e.removeAttribute(`data-mc`))}function te(e){queueMicrotask(()=>{e.trigger(`Init`,null)})}function T(e){let t=e.target,n=Object.getPrototypeOf(e),i=e,a=Object.getOwnPropertyNames(n).filter(e=>/^(on[A-Z]|one[A-Z])/.test(e)&&typeof n[e]==`function`);for(let e of a){let n=/^one/.test(e);r(t,e.replace(/^one?/,``),t=>i[e](t),n)}}function E(e){return Array.from(e.querySelectorAll(`[data-mc]:not(:scope [data-mc] [data-mc])`)).filter(e=>e instanceof HTMLElement&&`_mc`in e).map(e=>e._mc)}function D(e,t){let n=e.parentElement?.closest(`[data-mc]`);for(;n instanceof HTMLElement;){if(`_mc`in n){let e=n._mc;if(t===void 0||t in e)return e}n=n.parentElement?.closest(`[data-mc]`)}return null}var O=class{_target;constructor(e){if(this._target=new WeakRef(e||{}),this instanceof k&&this.constructor!==k){T(this);let e=this.constructor.tag;(e===void 0||e.toUpperCase()===this.target.tagName)&&te(this)}}get target(){return this._target.deref()}},ne=class extends O{constructor(e){super(e)}},k=class e extends O{static tag;static _assets={};static assets=[];static attributes={};constructor(t){super(t);let n=this.constructor;if(n===e)return;let r=this.target.tagName.toLowerCase();if(n.tag!==void 0&&r!==n.tag&&n.tag!==``){let t=document.createElement(n.tag);t.classList.add(r),n._originalTag=r,e.add(t,n.name,new n(t)),delete n._originalTag,r.includes(`-`)&&!this.target.isConnected?this.on(`connected`,()=>this.target.replaceWith(t)):this.target.replaceWith(t);return}let i=n.attributes;n.attributes&&Object.keys(n.attributes).forEach(e=>{this.target.setAttribute(e,i[e])});let a=n.assets.filter(e=>!n._assets[e]),o=this;if(n.hasOwnProperty(`_assets`)?y(this,n._assets):n.assets.length&&!n.hasOwnProperty(`_assets`)&&(n._assets={}),a.length?b(n._originalTag||r,a).then(e=>{let t={};a.forEach((n,r)=>{t[n]=e[r]}),y(this,t),n._assets=Object.assign({},n._assets,t);for(let e of[`css`,`targetCss`])t[e]!==void 0&&delete n._assets[e];n.assets=n.assets.filter(e=>e!==`css`&&e!==`targetCss`),o.trigger(`assets`,n._assets)}):[...Object.keys(n._assets)].length&&queueMicrotask(()=>o.trigger(`assets`,n._assets)),n.tag===``){this.target.remove();return}}getAssets(){return this.constructor._assets||{}}static add(e,t,n={}){return C(e,t,n)}static remove(e,t){w(e,t)}static get(e,t,n){if(!S(e))return;let r=e._mc[t];return r instanceof n?r:void 0}off(e,t){n(this.target,e,t)}on(e,t){return r(this.target,e,t)}one(e,t){return i(this.target,e,t)}trigger(e,t={},n=`l`,r){o(this.target,e,t,n,r)}ancestors(e){let t=[],n=D(this.target,e);for(;n;)t.push(n),n=D(n.target,e);return t}closest(e){return D(this.target,e)}children(e){let t=E(this.target);return e===void 0?t:t.filter(t=>e in t)}descendants(e){return Array.from(this.target.querySelectorAll(`[data-mc]`)).filter(e=>e instanceof HTMLElement&&`_mc`in e).map(e=>e._mc).filter(t=>e===void 0||e in t)}},A=new Set;function j(e){return()=>{let t=Array.from(document.querySelectorAll(`[data-mc*="${e}"]`)).filter(e=>e instanceof HTMLElement);if(t.length===0)return;let n=customElements.get(e);for(let r of t){try{k.add(r,n.name,new n(r))}catch{if(`create`in n&&typeof n.create==`function`){let e=n.create(r);if(!S(e))throw`create() of Class ${n.name} did not return a McHost.`;e.setAttribute(`data-mc`,r.getAttribute(`data-mc`)??``),r.replaceWith(e),r=e}else throw`Class ${n.name} doesn't have a callable constructor AND class doesn't have a static .create() method.`}let t=r.getAttribute(`data-mc`).split(` `).filter(t=>t!==e&&t!==``).join(` `).trim();r.setAttribute(`data-mc`,t)}}}function M(e){if(A.has(e))return;A.add(e);let t=`./`+e.split(`-`).join(`/`)+`.js`,n=document.createElement(`script`);n.setAttribute(`src`,t),n.setAttribute(`blocking`,`render`),n.async=!0,n.setAttribute(`type`,`module`),n.setAttribute(`data-name`,e),n.setAttribute(`loading`,``),customElements.whenDefined(e).then(j(e)),n.addEventListener(`load`,t=>{A.delete(e),document.head.querySelector(`script[data-name="${e}"]`)?.remove()}),n.addEventListener(`error`,e=>{console.error(`could not load DC code from`,t)}),document.head.append(n)}function N(){[...document.querySelectorAll(`:not(:defined)`)].filter(e=>!!e&&!customElements.get(e.tagName.toLowerCase())&&!A.has(e.tagName.toLowerCase())).forEach(e=>{M(e.tagName.toLowerCase())}),[...document.querySelectorAll(`[data-mc]:not([data-mc=""]`)].filter(e=>!!e).forEach(e=>{(e.getAttribute(`data-mc`)?.split(` `).filter(e=>e!==``))?.forEach(e=>{let t=customElements.get(e);!A.has(e)&&!t?M(e):t&&j(e)()})})}var P=null;function F(e=!0){return e?P?!0:(P=new MutationObserver(N),setTimeout(()=>{P.observe(document.body,{childList:!0,subtree:!0}),N()},5),window.autoload??=F,!0):(P&&=(P.disconnect(),null),!1)}F.state=A;function re(e,t){return Object.defineProperty(t,"name",{value:e})}function ie(e){return class extends e{constructor(...e){super(...e)}}}function I(e,t,n=[],r){if(customElements.get(e)){console.warn(`IGNORED: Custom element "${e}" is already defined!`);return}if(!e.includes(`-`))throw Error(`createCustomElement: tagName must contain at least one hyphen ("-").`);let i=HTMLElement;r&&(i=document.createElement(r).constructor);let a=m(e);if(!(t.prototype instanceof O))return customElements.define(e,t),t;let o=re(a,class extends ie(i){constructor(e){super(),k.add(this,a,new t(this,e))}connectedCallback(){this.dispatchEvent(new CustomEvent(`_mcConnected`))}connectedMoveCallback(){this.dispatchEvent(new CustomEvent(`_mcConnectedMove`))}disconnectedCallback(){this.dispatchEvent(new CustomEvent(`_mcDisconnected`))}adoptedCallback(){this.dispatchEvent(new CustomEvent(`_mcAdopted`))}attributeChangedCallback(e,t,n){this.dispatchEvent(new CustomEvent(`_mcAttributeChanged`,{detail:{name:e,oldValue:t,newValue:n}}))}formResetCallback(){this.dispatchEvent(new CustomEvent(`_mcFormReset`))}static get observedAttributes(){return[...n]}});return customElements.define(e,o,{extends:r}),I.list||=[],I.list.push(e),o}function L(e){return customElements.get(e)}function R(){return I.list??[]}function z(e){let t=new Set,n=/\{[^\{\}]*\}/g;return(e.getAttributeNames?e.getAttributeNames():[]).filter(t=>e.getAttribute(t)?.match(n)).forEach(r=>{new Set(e.getAttribute(r)?.match(n)).forEach(e=>t.add(e.replace(/[\{\}]/g,``)))}),[...e.childNodes].filter(e=>e.nodeType===3&&(e.nodeValue||``).match(n)).forEach(e=>{(e?.nodeValue||``).match(n).forEach(e=>t.add(e.replace(/[\{\}]/g,``)))}),[...t]}var B=[`INPUT`,`SELECT`,`TEXTAREA`],V=class extends k{data={};oldDisplay=``;constructor(e){super(e),z(e).forEach(e=>this.data[e]=``),Y(this),this.#e()}#e(){let e=this.target,t=!1;(e.getAttributeNames?e.getAttributeNames():[]).filter(t=>e.getAttribute(t)?.match(/\{[^\{\}]*\}/g)).forEach(t=>{let n=new Set(e.getAttribute(t)?.match(/\{[^\{\}]*\}/g));this.data.subscribe((r=>i=>{let a=r;n.forEach(e=>{a=a.replace(e,String(i[e.replace(/[\{\}]/g,``)]))}),e.setAttribute(t,a)})(e.getAttribute(t)??``))}),[...e.childNodes].filter(e=>e.nodeType===3&&(e.nodeValue||``).match(/\{[^\{\}]*\}/g)).forEach(n=>{t=!0;let r=new Set((n.nodeValue??``).match(/\{[^\{\}]*\}/g));this.data.subscribe((t=>i=>{let a=t;r.forEach(e=>{a=a.replace(e,String(i[e.replace(/[\{\}]/g,``)]))}),this.oldDisplay?e.style=this.oldDisplay:e.removeAttribute(`style`),delete this.oldDisplay,n.nodeValue=a})(n.nodeValue??``)),this.oldDisplay=e.getAttribute(`style`)||``,t&&!B.includes(e.tagName)&&e.tagName!==`FIELDSET`&&(e.style.display=`none`)})}onData(e){let t={};Object.keys(e.detail.data).forEach(n=>{this.data.hasOwnProperty(n)&&(t[n]=e.detail.data[n])}),JSON.stringify(t)!==JSON.stringify(this.data)&&Object.assign(this.data,t)}};function H(e){return[e,...e.querySelectorAll(`*`)].filter(e=>!!z(e).length).filter(e=>e?.tagName!==`STYLE`).reverse()}function U(e){H(e).forEach(e=>{e?._mc?._placeholders||k.add(e,`_placeholders`,new V(e))})}function W(e){return typeof e==`object`&&!!e}var G={};function K(e){let t=e.constructor,n=t.name,r=class extends t{#e=!0;#t=[];constructor(e){super(e);let t=this.constructor;t.callbacks=[],W(e)&&Object.getOwnPropertyNames(e).forEach(t=>{this[t]=e[t]})}get callbacks(){return this.#t}set callbacks(e){this.#t=e}[Symbol.toPrimitive](e){let t=this.valueOf();return e===`string`?String(t):e===`number`?Number(t):t}subscribe(e){return this.#t.push(e),this}unsubscribe(e){return this.#t=this.#t.filter(t=>t!==e),this}bind(e){if(s()){if(W(this.valueOf())){U(e);let t=[e,...e.querySelectorAll(`[data-mc]`)].filter(e=>!!e?._mc?._placeholders);this.#t.push(function(e){let n=u(e);t.forEach(e=>{e&&o(e,`data`,n)})}),this.notify()}else console.warn(`IGNORED - cannot bind a non-Object to the dom, IS:`,typeof this.valueOf(),this);return this}}notify(e){let t=W(this.valueOf())&&!(this.valueOf()instanceof Array)?structuredClone(Object.assign({},this)):this.valueOf();return e!==void 0&&(this.#e=e),this.#e&&this.#t.forEach(e=>{e(t)}),this}};return G[n]=r,r}function q(e){return G[e.constructor.name]||K(e)}function J(e){return(typeof e==`object`||typeof e==`function`)&&e!==null&&`subscribe`in e}function Y(e,t){let n=e;return(t?[t]:[...Object.getOwnPropertyNames(e)]).forEach(t=>{let r=n[t];if(Object.prototype.hasOwnProperty.call(e,t)&&typeof r!=`function`&&!J(r)){if(t[0]===`_`||r===void 0)return;let i=r,a=new(q(i))(i),o=function(){queueMicrotask(function(){a.notify()})};Object.defineProperty(e,t,{enumerable:!0,get(){if(W(a.valueOf())){let e=structuredClone(Object.assign({},a));queueMicrotask(function(){d(structuredClone(Object.assign({},a)),e)||o()})}return a},set(e){if(typeof e==typeof a.valueOf())if(W(a.valueOf())&&!(a.valueOf()instanceof Array))J(a)||(a=new(q(e))(structuredClone(Object.assign({},e))),g(e,a)),Object.assign(a,e),a.notify();else{let t=a.valueOf(),n=a.callbacks;e!==t&&(a=new(q(e))(e),a.callbacks=n,o())}else console.warn(`IGNORED - cannot change observable types, IS:`,typeof a.valueOf(),a,`- CANNOT BECOME:`,typeof e)}}),n[t]=i}}),e}function X(e){let t=Object.getPrototypeOf(e.prototype);function n(e,t){let n=e[t];J(n)||Y(e,t)}Object.hasOwn(t,`notify`)||Object.assign(t,{notify:function(e){return n(this,e),this[e].notify(),this},subscribe:function(e,t){return n(this,e),this[e].subscribe(t),this},bind:function(e,t){return n(this,e),this[e].bind(t),this}})}X(k);var ae=e=>e.tagName.toLowerCase(),Z=class{constructor(e){}},oe=class extends Z{#e;constructor(e){super(e),this.#e=e}get val(){return this.#e.form?new FormData(this.#e.form).get(this.#e.name)??null:null}set val(e){let t=[...this.#e.form?.querySelectorAll(`input[type="radio"][name="${this.#e.name}"]`)??[]];t.filter(t=>t.getAttribute(`value`)===e).shift().checked=!0}},se=class extends Z{#e;constructor(e){super(e),this.#e=e}get val(){return this.#e.checked}set val(e){this.#e.checked=e}},Q=class extends Z{#e;constructor(e){super(e),this.#e=e}get val(){return this.#e.value}set val(e){this.#e.value=e}},ce=class extends Z{#e;#t=!1;constructor(e){super(e),this.#e=e,this.#t=e.multiple}get val(){let e=[];return[...this.#e.querySelectorAll(`option`)].filter(e=>e.selected).forEach(t=>{e.push(t.value)}),this.#t?e:e[0]}set val(e){e=typeof e==`string`?[e]:e,[...this.#e.querySelectorAll(`option`)].forEach(t=>{e.indexOf(t.value)>-1?t.selected=!0:t.selected=!1})}},le=class extends Z{#e;constructor(e){super(e),this.#e=e}get val(){return this.#e.value||``}set val(e){this.#e.value=e}},ue=e=>{let t=[...(e||document).querySelectorAll(`input,select,textarea`)],n={};return t.forEach(e=>{let t=e.getAttribute(`name`);if(t){let r=!1;switch(ae(e)){case`input`:switch(e.type){case`radio`:r=new oe(e);break;case`checkbox`:r=new se(e);break;default:r=new Q(e)}break;case`select`:r=new ce(e);break;case`textarea`:r=new le(e);break}if(r){let i=r;k.add(e,t,i),Object.defineProperty(n,t,{enumerable:!0,configurable:!0,get:()=>i.val,set:e=>{i.val!==e&&(i.val=e)}})}}}),n};function $(e,t,n){if(!s())return;let r=ue(n),i=e;i[t]=Object.assign({},r),Y(e,t);let a=i[t];g(r,a),[...n.querySelectorAll(`input, textarea, select`)].forEach(e=>{e.addEventListener(`input`,()=>{a.notify()})})}function de(e){let t=Object.getPrototypeOf(e.prototype);Object.hasOwn(t,`formValues`)||Object.assign(t,{formValues:function(e,t){return $(this,t,e),this}})}export{a as BubbleController,k as DC,ne as MC,O as McBase,F as autoload,x as bindTemplateEvents,g as copyGettersSetters,h as debounce,d as deepEqual,I as defineCE,u as flattenObject,de as formValuePlugin,$ as formValues,L as getCE,e as getMcEventName,ee as htmlToElements,v as injectCSS,J as isAlreadyObserved,s as isBrowser,S as isMcHost,c as isNativeObject,m as kebabToPascal,R as listCE,b as loadAssets,f as nameSpace,Y as observe,X as observePlugin,n as off,r as on,i as one,p as parse,y as processAssets,l as sortObject,o as trigger,t as trueEventName};
|
|
1
|
+
function e(e){return`_mc`+e[0].toUpperCase()+e.substring(1)}function t(e,t){let n=t.toLowerCase();return`on`+n in e?n:`_mc`+t[0].toUpperCase()+t.substring(1)}function n(e,r,i){if(e){if(typeof e==`string`){document.querySelectorAll(e).forEach(e=>n(e,r,i));return}e.removeEventListener(t(e,r),i)}}function r(e,n,i,a=!1){if(e){if(typeof e==`string`){document.querySelectorAll(e).forEach(e=>r(e,n,i));return}return e.addEventListener(t(e,n),i,{capture:!1,once:a}),i}}function i(e,t,n){if(e){if(typeof e==`string`){document.querySelectorAll(e).forEach(e=>i(e,t,n));return}return r(e,t,n,!0),n}}var a=class{stopped=!1;constructor(){}stop(){this.stopped=!0}};function o(e,n,r={},i=`l`,s){if(!e)return;if(typeof e==`string`){document.querySelectorAll(e).forEach(e=>o(e,n,r,i));return}let c=/^_mc/.test(n)?n:t(e,n),l=s||new a,u=new CustomEvent(c,{detail:{data:r,control:l},bubbles:!1});l.stopped||/l/.test(i)&&(e.dispatchEvent(u),l.stopped)||/[ud]/.test(i)&&queueMicrotask(()=>{if(i.indexOf(`u`)>-1&&o(e.parentElement,c,r,`lu`,l),i.indexOf(`d`)>-1)for(let t of e.children)o(t,c,r,`ld`)})}function s(){return typeof window<`u`&&window.document!==void 0}function c(e){return typeof e==`object`&&!!e&&e.constructor===Object}function l(e){let t={},n=Object.keys(e).sort();for(let r=0;r<n.length;r++){let i=n[r],a=e[i];c(a)?t[i]=l(a):t[i]=a}return t}function u(e,t=!0){let n={},r=e,i=Object.getOwnPropertyNames(e);for(let e=0;e<i.length;e++){let t=i[e],a=r[t];if(a instanceof Object){let e=u(a,!1);for(let r in e)n[t+`.`+r]=e[r]}else n[t]=a}return t?l(n):n}function d(e,t){if(e===t||e!==e&&t!==t)return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t||e.constructor!==t.constructor)return!1;if(e instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp)return e.toString()===t.toString();if(Array.isArray(e)){let n=t;if(e.length!==n.length)return!1;for(let t=0;t<e.length;t++)if(!d(e[t],n[t]))return!1;return!0}let n=e,r=t,i=Object.keys(n);if(i.length!==Object.keys(r).length)return!1;for(let e=0;e<i.length;e++){let t=i[e];if(!Object.prototype.hasOwnProperty.call(r,t)||!d(n[t],r[t]))return!1}return!0}function f(e,t={}){let n=t,r=typeof e==`string`?e.split(`.`):e;if(!(!n||!r[0]||!n[r[0]])){if(r.length>1){let e=n[r[0]];return c(e)?f(r.slice(1),e):void 0}return n[r[0]]}}function p(e,t,...n){let r=[e,t,...n];if(r.length>2){for(;r.length>1;)r[0]=p(r[0],r[1]),r.splice(1,1);return r[0]}if(typeof e==`string`){let n=e;return e.match(/\{[^\{\}]*\}/g)?.forEach(e=>{let r=f(e.substring(1,e.length-1),t);r!==void 0&&(n=n.replace(e,String(r)))}),n}else if(c(e)){let n=e;Object.keys(n).forEach(e=>{Object.prototype.hasOwnProperty.call(n,e)&&(n[e]=p(n[e],t))})}return e}function m(e){return e.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``)}function h(e,t){let n;return(...r)=>{clearTimeout(n),n=setTimeout(()=>{e(...r)},t)}}function ee(e){let t=document.createElement(`template`);return e=e.replace(/<([A-Za-z0-9\-]*)([^>\/]*)(\/>)/gi,`<$1$2></$1>`),t.innerHTML=e,t.content.normalize(),Array.from(t.content.childNodes)}function g(e,t){let n=Object.getOwnPropertyDescriptors(e);for(let[e,r]of Object.entries(n))(`get`in r||`set`in r)&&Object.defineProperty(t,e,r)}var _=new WeakMap;function v(e,t){let n=_.get(e)??new Set;if(n.has(t))return e.adoptedStyleSheets[0];n.add(t),_.set(e,n);let r=new CSSStyleSheet;return r.replaceSync(t),e.adoptedStyleSheets.push(r),r}function y(e,t){let n=e.target,r=n.shadowRoot;!r&&Object.keys(t).some(e=>e.indexOf(`shadow`)===0)&&(r=n.attachShadow({mode:`open`})),Object.keys(t).forEach(i=>{switch(i){case`css`:v(document,t[i]);break;case`targetCss`:v(document,t[i]);break;case`shadowCss`:v(r,t[i]);break;case`shadowHtml`:r.innerHTML=t[i],x(r,e);break;case`targetHtml`:n.innerHTML=t[i],x(n,e);break}})}function b(e,t){let n=t=>{let n=t.match(/^([a-z]+)([A-Z][a-z]*)$/);return n?`./${e.replace(/-/g,`/`)}.${n[1]}.${n[2].toLowerCase()}`:`./${e.replace(/-/g,`/`)}.${t.toLowerCase()}`};return Promise.all(t.map(async e=>{let t=n(e);try{let n=await fetch(t);if(!n.ok)return`file not found: ${t}`;if(t.endsWith(`json`)){let r=await n.text();try{return JSON.parse(r)}catch{return console.error(`could not JSON.parse() asset '${e}' from ${t}:\n`,r),null}}return n.text()}catch{return`file not found: ${t}`}}))}function x(e,t){let n=[...e.querySelectorAll(`*`)];for(let e of n){if(!(e instanceof HTMLElement))continue;let n=[...e.attributes];for(let i of n){let n=i.name.toLowerCase();if(!(`on`+n in e))continue;let a=i.value.trim().split(`|`);if(a.length<2)continue;let[s,c,l]=a;e.removeAttribute(i.name);let u;if(l)try{u=JSON.parse(l)}catch{u=l}s===`this`||s===``?r(e,n,()=>t.trigger(c,u)):r(e,n,()=>o(s,c,u))}}}function S(e,t){return typeof HTMLElement<`u`&&e instanceof HTMLElement&&`_mc`in e&&(t===void 0||t in e._mc)}function C(e,t,n={}){let r=e;`_mc`in e||(r._mc=new O(e));let i=r._mc;return t.length&&!i[t]&&(i[t]=n,e instanceof HTMLElement&&!e.getAttribute(`data-mc`)&&e.setAttribute(`data-mc`,``)),r}function te(e,t){if(!t)return;let n=e._mc;n&&(n[t]&&delete n[t],!Object.keys(n).length&&e instanceof HTMLElement&&e.hasAttribute(`data-mc`)&&e.removeAttribute(`data-mc`))}function ne(e){queueMicrotask(()=>{e.trigger(`Init`,null)})}function w(e){let t=e.target,n=Object.getPrototypeOf(e),i=e,a=Object.getOwnPropertyNames(n).filter(e=>/^(on[A-Z]|one[A-Z])/.test(e)&&typeof n[e]==`function`);for(let e of a){let n=/^one/.test(e);r(t,e.replace(/^one?/,``),t=>i[e](t),n)}}function T(e){return Array.from(e.querySelectorAll(`[data-mc]:not(:scope [data-mc] [data-mc])`)).filter(e=>e instanceof HTMLElement&&`_mc`in e).map(e=>e._mc)}function E(e,t){let n=e.parentElement?.closest(`[data-mc]`);for(;n instanceof HTMLElement;){if(`_mc`in n){let e=n._mc;if(t===void 0||t in e)return e}n=n.parentElement?.closest(`[data-mc]`)}return null}var D=class{_target;constructor(e){if(this._target=new WeakRef(e||{}),this instanceof O&&this.constructor!==O){w(this);let e=this.constructor.tag;(e===void 0||e.toUpperCase()===this.target.tagName)&&ne(this)}}get target(){return this._target.deref()}},re=class extends D{constructor(e){super(e)}},O=class e extends D{static tag;static _assets={};static assets=[];static _assetsPromise;static attributes={};constructor(t){super(t);let n=this.constructor;if(n===e)return;let r=this.target.tagName.toLowerCase();if(n.tag!==void 0&&r!==n.tag&&n.tag!==``){let t=document.createElement(n.tag);t.classList.add(r),n._originalTag=r,e.add(t,n.name,new n(t)),delete n._originalTag,r.includes(`-`)&&!this.target.isConnected?this.on(`connected`,()=>this.target.replaceWith(t)):this.target.replaceWith(t);return}let i=n.attributes;n.attributes&&Object.keys(n.attributes).forEach(e=>{this.target.setAttribute(e,i[e])});let a=this,o=n.assets.filter(e=>!n._assets[e]);if(Object.keys(n._assets).length&&y(this,n._assets),o.length?(n._assetsPromise||=b(n._originalTag||r,o).then(e=>{let t={};o.forEach((n,r)=>{t[n]=e[r]}),n._assets=Object.assign({},n._assets,t);for(let e of[`css`,`targetCss`])t[e]!==void 0&&delete n._assets[e];return n.assets=n.assets.filter(e=>e!==`css`&&e!==`targetCss`),t}),n._assetsPromise.then(e=>{y(this,e),a.trigger(`assets`,n._assets)})):[...Object.keys(n._assets)].length&&queueMicrotask(()=>a.trigger(`assets`,n._assets)),n.tag===``){this.target.remove();return}}getAssets(){return this.constructor._assets||{}}static add(e,t,n={}){return C(e,t,n)}static remove(e,t){te(e,t)}static get(e,t,n){if(!S(e))return;let r=e._mc[t];return r instanceof n?r:void 0}off(e,t){n(this.target,e,t)}on(e,t){return r(this.target,e,t)}one(e,t){return i(this.target,e,t)}trigger(e,t={},n=`l`,r){o(this.target,e,t,n,r)}ancestors(e){let t=[],n=E(this.target,e);for(;n;)t.push(n),n=E(n.target,e);return t}closest(e){return E(this.target,e)}children(e){let t=T(this.target);return e===void 0?t:t.filter(t=>e in t)}descendants(e){return Array.from(this.target.querySelectorAll(`[data-mc]`)).filter(e=>e instanceof HTMLElement&&`_mc`in e).map(e=>e._mc).filter(t=>e===void 0||e in t)}};function k(e){return e.split(`-`).join(`/`)}function A(e){return`./`+k(e)+`.js`}var j=new Set;function M(e){return()=>{let t=Array.from(document.querySelectorAll(`[data-mc*="${e}"]`)).filter(e=>e instanceof HTMLElement);if(t.length===0)return;let n=customElements.get(e);for(let r of t){try{O.add(r,n.name,new n(r))}catch{if(`create`in n&&typeof n.create==`function`){let e=n.create(r);if(!S(e))throw`create() of Class ${n.name} did not return a McHost.`;e.setAttribute(`data-mc`,r.getAttribute(`data-mc`)??``),r.replaceWith(e),r=e}else throw`Class ${n.name} doesn't have a callable constructor AND class doesn't have a static .create() method.`}let t=r.getAttribute(`data-mc`).split(` `).filter(t=>t!==e&&t!==``).join(` `).trim();r.setAttribute(`data-mc`,t)}}}function N(e){if(j.has(e))return;j.add(e);let t=A(e),n=document.createElement(`script`);n.setAttribute(`src`,t),n.setAttribute(`blocking`,`render`),n.async=!0,n.setAttribute(`type`,`module`),n.setAttribute(`data-name`,e),n.setAttribute(`loading`,``),customElements.whenDefined(e).then(M(e)),n.addEventListener(`load`,t=>{j.delete(e),document.head.querySelector(`script[data-name="${e}"]`)?.remove()}),n.addEventListener(`error`,e=>{console.error(`could not load DC code from`,t)}),document.head.append(n)}function P(){[...document.querySelectorAll(`:not(:defined)`)].filter(e=>!!e&&!customElements.get(e.tagName.toLowerCase())&&!j.has(e.tagName.toLowerCase())).forEach(e=>{N(e.tagName.toLowerCase())}),[...document.querySelectorAll(`[data-mc]:not([data-mc=""]`)].filter(e=>!!e).forEach(e=>{(e.getAttribute(`data-mc`)?.split(` `).filter(e=>e!==``))?.forEach(e=>{let t=customElements.get(e);!j.has(e)&&!t?N(e):t&&M(e)()})})}var F=null;function I(e=!0){return e?F?!0:(F=new MutationObserver(P),setTimeout(()=>{F.observe(document.body,{childList:!0,subtree:!0}),P()},5),window.autoload??=I,!0):(F&&=(F.disconnect(),null),!1)}I.state=j;function ie(e,t){return Object.defineProperty(t,"name",{value:e})}function ae(e){return class extends e{constructor(...e){super(...e)}}}function L(e,t,n=[],r){if(customElements.get(e)){console.warn(`IGNORED: Custom element "${e}" is already defined!`);return}if(!e.includes(`-`))throw Error(`createCustomElement: tagName must contain at least one hyphen ("-").`);let i=HTMLElement;r&&(i=document.createElement(r).constructor);let a=m(e);if(!(t.prototype instanceof D))return customElements.define(e,t),t;let o=ie(a,class extends ae(i){constructor(e){super(),O.add(this,a,new t(this,e))}connectedCallback(){this.dispatchEvent(new CustomEvent(`_mcConnected`))}connectedMoveCallback(){this.dispatchEvent(new CustomEvent(`_mcConnectedMove`))}disconnectedCallback(){this.dispatchEvent(new CustomEvent(`_mcDisconnected`))}adoptedCallback(){this.dispatchEvent(new CustomEvent(`_mcAdopted`))}attributeChangedCallback(e,t,n){this.dispatchEvent(new CustomEvent(`_mcAttributeChanged`,{detail:{name:e,oldValue:t,newValue:n}}))}formResetCallback(){this.dispatchEvent(new CustomEvent(`_mcFormReset`))}static get observedAttributes(){return[...n]}});return customElements.define(e,o,{extends:r}),L.list||=[],L.list.push(e),o}function R(e){return customElements.get(e)}function z(){return L.list??[]}function B(e){let t=new Set,n=/\{[^\{\}]*\}/g;return(e.getAttributeNames?e.getAttributeNames():[]).filter(t=>e.getAttribute(t)?.match(n)).forEach(r=>{new Set(e.getAttribute(r)?.match(n)).forEach(e=>t.add(e.replace(/[\{\}]/g,``)))}),[...e.childNodes].filter(e=>e.nodeType===3&&(e.nodeValue||``).match(n)).forEach(e=>{(e?.nodeValue||``).match(n).forEach(e=>t.add(e.replace(/[\{\}]/g,``)))}),[...t]}var V=[`INPUT`,`SELECT`,`TEXTAREA`],H=class extends O{data={};oldDisplay=``;constructor(e){super(e),B(e).forEach(e=>this.data[e]=``),X(this),this.#e()}#e(){let e=this.target,t=!1;(e.getAttributeNames?e.getAttributeNames():[]).filter(t=>e.getAttribute(t)?.match(/\{[^\{\}]*\}/g)).forEach(t=>{let n=new Set(e.getAttribute(t)?.match(/\{[^\{\}]*\}/g)),r=e.getAttribute(t)??``;this.data.subscribe((r=>i=>{let a=r;n.forEach(e=>{a=a.replace(e,String(i[e.replace(/[\{\}]/g,``)]))}),e.setAttribute(t,a)})(r))}),[...e.childNodes].filter(e=>e.nodeType===3&&(e.nodeValue||``).match(/\{[^\{\}]*\}/g)).forEach(n=>{t=!0;let r=n.nodeValue??``,i=new Set(r.match(/\{[^\{\}]*\}/g));this.data.subscribe((t=>r=>{let a=t;i.forEach(e=>{a=a.replace(e,String(r[e.replace(/[\{\}]/g,``)]))}),this.oldDisplay?e.style=this.oldDisplay:e.removeAttribute(`style`),delete this.oldDisplay,n.nodeValue=a})(r)),this.oldDisplay=e.getAttribute(`style`)||``,t&&!V.includes(e.tagName)&&e.tagName!==`FIELDSET`&&(e.style.display=`none`)})}onData(e){let t={};Object.keys(e.detail.data).forEach(n=>{this.data.hasOwnProperty(n)&&(t[n]=e.detail.data[n])}),JSON.stringify(t)!==JSON.stringify(this.data)&&Object.assign(this.data,t)}};function U(e){return[e,...e.querySelectorAll(`*`)].filter(e=>!!B(e).length).filter(e=>e?.tagName!==`STYLE`).reverse()}function W(e){U(e).forEach(e=>{e?._mc?._placeholders||O.add(e,`_placeholders`,new H(e))})}function G(e){return typeof e==`object`&&!!e}var K={};function q(e){let t=e.constructor,n=t.name,r=class extends t{#e=!0;#t=[];constructor(e){super(e);let t=this.constructor;t.callbacks=[],G(e)&&Object.getOwnPropertyNames(e).forEach(t=>{this[t]=e[t]})}get callbacks(){return this.#t}set callbacks(e){this.#t=e}[Symbol.toPrimitive](e){let t=this.valueOf();return e===`string`?String(t):e===`number`?Number(t):t}subscribe(e){return this.#t.push(e),this}unsubscribe(e){return this.#t=this.#t.filter(t=>t!==e),this}bind(e){if(s()){if(G(this.valueOf())){W(e);let t=[e,...e.querySelectorAll(`[data-mc]`)].filter(e=>!!e?._mc?._placeholders);this.#t.push(function(e){let n=u(e);t.forEach(e=>{e&&o(e,`data`,n)})}),this.notify()}else console.warn(`IGNORED - cannot bind a non-Object to the dom, IS:`,typeof this.valueOf(),this);return this}}notify(e){let t=G(this.valueOf())&&!(this.valueOf()instanceof Array)?structuredClone(Object.assign({},this)):this.valueOf();return e!==void 0&&(this.#e=e),this.#e&&this.#t.forEach(e=>{e(t)}),this}};return K[n]=r,r}function J(e){return K[e.constructor.name]||q(e)}function Y(e){return(typeof e==`object`||typeof e==`function`)&&e!==null&&`subscribe`in e}function X(e,t){let n=e;return(t?[t]:[...Object.getOwnPropertyNames(e)]).forEach(t=>{let r=n[t];if(Object.prototype.hasOwnProperty.call(e,t)&&typeof r!=`function`&&!Y(r)){if(t[0]===`_`||r===void 0)return;let i=r,a=new(J(i))(i),o=function(){queueMicrotask(function(){a.notify()})};Object.defineProperty(e,t,{enumerable:!0,get(){if(G(a.valueOf())){let e=structuredClone(Object.assign({},a));queueMicrotask(function(){d(structuredClone(Object.assign({},a)),e)||o()})}return a},set(e){if(typeof e==typeof a.valueOf())if(G(a.valueOf())&&!(a.valueOf()instanceof Array))Y(a)||(a=new(J(e))(structuredClone(Object.assign({},e))),g(e,a)),Object.assign(a,e),a.notify();else{let t=a.valueOf(),n=a.callbacks;e!==t&&(a=new(J(e))(e),a.callbacks=n,o())}else console.warn(`IGNORED - cannot change observable types, IS:`,typeof a.valueOf(),a,`- CANNOT BECOME:`,typeof e)}}),n[t]=i}}),e}function Z(e){let t=Object.getPrototypeOf(e.prototype);function n(e,t){let n=e[t];Y(n)||X(e,t)}Object.hasOwn(t,`notify`)||Object.assign(t,{notify:function(e){return n(this,e),this[e].notify(),this},subscribe:function(e,t){return n(this,e),this[e].subscribe(t),this},bind:function(e,t){return n(this,e),this[e].bind(t),this}})}Z(O);var oe=e=>e.tagName.toLowerCase(),Q=class{constructor(e){}},se=class extends Q{#e;constructor(e){super(e),this.#e=e}get val(){return this.#e.form?new FormData(this.#e.form).get(this.#e.name)??null:null}set val(e){let t=[...this.#e.form?.querySelectorAll(`input[type="radio"][name="${this.#e.name}"]`)??[]];t.filter(t=>t.getAttribute(`value`)===e).shift().checked=!0}},ce=class extends Q{#e;constructor(e){super(e),this.#e=e}get val(){return this.#e.checked}set val(e){this.#e.checked=e}},le=class extends Q{#e;constructor(e){super(e),this.#e=e}get val(){return this.#e.value}set val(e){this.#e.value=e}},ue=class extends Q{#e;#t=!1;constructor(e){super(e),this.#e=e,this.#t=e.multiple}get val(){let e=[];return[...this.#e.querySelectorAll(`option`)].filter(e=>e.selected).forEach(t=>{e.push(t.value)}),this.#t?e:e[0]}set val(e){e=typeof e==`string`?[e]:e,[...this.#e.querySelectorAll(`option`)].forEach(t=>{e.indexOf(t.value)>-1?t.selected=!0:t.selected=!1})}},de=class extends Q{#e;constructor(e){super(e),this.#e=e}get val(){return this.#e.value||``}set val(e){this.#e.value=e}},fe=e=>{let t=[...(e||document).querySelectorAll(`input,select,textarea`)],n={};return t.forEach(e=>{let t=e.getAttribute(`name`);if(t){let r=!1;switch(oe(e)){case`input`:switch(e.type){case`radio`:r=new se(e);break;case`checkbox`:r=new ce(e);break;default:r=new le(e)}break;case`select`:r=new ue(e);break;case`textarea`:r=new de(e);break}if(r){let i=r;O.add(e,t,i),Object.defineProperty(n,t,{enumerable:!0,configurable:!0,get:()=>i.val,set:e=>{i.val!==e&&(i.val=e)}})}}}),n};function $(e,t,n){if(!s())return;let r=fe(n),i=e;i[t]=Object.assign({},r),X(e,t);let a=i[t];g(r,a),[...n.querySelectorAll(`input, textarea, select`)].forEach(e=>{e.addEventListener(`input`,()=>{a.notify()})})}function pe(e){let t=Object.getPrototypeOf(e.prototype);Object.hasOwn(t,`formValues`)||Object.assign(t,{formValues:function(e,t){return $(this,t,e),this}})}export{a as BubbleController,O as DC,re as MC,D as McBase,I as autoload,x as bindTemplateEvents,g as copyGettersSetters,h as debounce,d as deepEqual,L as defineCE,u as flattenObject,pe as formValuePlugin,$ as formValues,R as getCE,e as getMcEventName,ee as htmlToElements,v as injectCSS,Y as isAlreadyObserved,s as isBrowser,S as isMcHost,c as isNativeObject,m as kebabToPascal,z as listCE,b as loadAssets,f as nameSpace,X as observe,Z as observePlugin,n as off,r as on,i as one,p as parse,y as processAssets,l as sortObject,o as trigger,t as trueEventName};
|
package/dist/observables.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e,t){let n=t.toLowerCase();return`on`+n in e?n:`_mc`+t[0].toUpperCase()+t.substring(1)}function t(n,r,i){if(n){if(typeof n==`string`){document.querySelectorAll(n).forEach(e=>t(e,r,i));return}n.removeEventListener(e(n,r),i)}}function n(t,r,i,a=!1){if(t){if(typeof t==`string`){document.querySelectorAll(t).forEach(e=>n(e,r,i));return}return t.addEventListener(e(t,r),i,{capture:!1,once:a}),i}}function r(e,t,i){if(e){if(typeof e==`string`){document.querySelectorAll(e).forEach(e=>r(e,t,i));return}return n(e,t,i,!0),i}}var i=class{stopped=!1;constructor(){}stop(){this.stopped=!0}};function a(t,n,r={},o=`l`,s){if(!t)return;if(typeof t==`string`){document.querySelectorAll(t).forEach(e=>a(e,n,r,o));return}let c=/^_mc/.test(n)?n:e(t,n),l=s||new i,u=new CustomEvent(c,{detail:{data:r,control:l},bubbles:!1});l.stopped||/l/.test(o)&&(t.dispatchEvent(u),l.stopped)||/[ud]/.test(o)&&queueMicrotask(()=>{if(o.indexOf(`u`)>-1&&a(t.parentElement,c,r,`lu`,l),o.indexOf(`d`)>-1)for(let e of t.children)a(e,c,r,`ld`)})}function o(){return typeof window<`u`&&window.document!==void 0}function s(e){return typeof e==`object`&&!!e&&e.constructor===Object}function c(e){let t={},n=Object.keys(e).sort();for(let r=0;r<n.length;r++){let i=n[r],a=e[i];s(a)?t[i]=c(a):t[i]=a}return t}function l(e,t=!0){let n={},r=e,i=Object.getOwnPropertyNames(e);for(let e=0;e<i.length;e++){let t=i[e],a=r[t];if(a instanceof Object){let e=l(a,!1);for(let r in e)n[t+`.`+r]=e[r]}else n[t]=a}return t?c(n):n}function u(e,t){if(e===t||e!==e&&t!==t)return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t||e.constructor!==t.constructor)return!1;if(e instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp)return e.toString()===t.toString();if(Array.isArray(e)){let n=t;if(e.length!==n.length)return!1;for(let t=0;t<e.length;t++)if(!u(e[t],n[t]))return!1;return!0}let n=e,r=t,i=Object.keys(n);if(i.length!==Object.keys(r).length)return!1;for(let e=0;e<i.length;e++){let t=i[e];if(!Object.prototype.hasOwnProperty.call(r,t)||!u(n[t],r[t]))return!1}return!0}function d(e,t){let n=Object.getOwnPropertyDescriptors(e);for(let[e,r]of Object.entries(n))(`get`in r||`set`in r)&&Object.defineProperty(t,e,r)}var f=new WeakMap;function p(e,t){let n=f.get(e)??new Set;if(n.has(t))return e.adoptedStyleSheets[0];n.add(t),f.set(e,n);let r=new CSSStyleSheet;return r.replaceSync(t),e.adoptedStyleSheets.push(r),r}function m(e,t){let n=e.target,r=n.shadowRoot;!r&&Object.keys(t).some(e=>e.indexOf(`shadow`)===0)&&(r=n.attachShadow({mode:`open`})),Object.keys(t).forEach(i=>{switch(i){case`css`:p(document,t[i]);break;case`targetCss`:p(document,t[i]);break;case`shadowCss`:p(r,t[i]);break;case`shadowHtml`:r.innerHTML=t[i],g(r,e);break;case`targetHtml`:n.innerHTML=t[i],g(n,e);break}})}function h(e,t){let n=t=>{let n=t.match(/^([a-z]+)([A-Z][a-z]*)$/);return n?`./${e.replace(/-/g,`/`)}.${n[1]}.${n[2].toLowerCase()}`:`./${e.replace(/-/g,`/`)}.${t.toLowerCase()}`};return Promise.all(t.map(async e=>{let t=n(e);try{let n=await fetch(t);if(!n.ok)return`file not found: ${t}`;if(t.endsWith(`json`)){let r=await n.text();try{return JSON.parse(r)}catch{return console.error(`could not JSON.parse() asset '${e}' from ${t}:\n`,r),null}}return n.text()}catch{return`file not found: ${t}`}}))}function g(e,t){let r=[...e.querySelectorAll(`*`)];for(let e of r){if(!(e instanceof HTMLElement))continue;let r=[...e.attributes];for(let i of r){let r=i.name.toLowerCase();if(!(`on`+r in e))continue;let o=i.value.trim().split(`|`);if(o.length<2)continue;let[s,c,l]=o;e.removeAttribute(i.name);let u;if(l)try{u=JSON.parse(l)}catch{u=l}s===`this`||s===``?n(e,r,()=>t.trigger(c,u)):n(e,r,()=>a(s,c,u))}}}function _(e,t){return typeof HTMLElement<`u`&&e instanceof HTMLElement&&`_mc`in e&&(t===void 0||t in e._mc)}function v(e,t,n={}){let r=e;`_mc`in e||(r._mc=new T(e));let i=r._mc;return t.length&&!i[t]&&(i[t]=n,e instanceof HTMLElement&&!e.getAttribute(`data-mc`)&&e.setAttribute(`data-mc`,``)),r}function y(e,t){if(!t)return;let n=e._mc;n&&(n[t]&&delete n[t],!Object.keys(n).length&&e instanceof HTMLElement&&e.hasAttribute(`data-mc`)&&e.removeAttribute(`data-mc`))}function b(e){queueMicrotask(()=>{e.trigger(`Init`,null)})}function x(e){let t=e.target,r=Object.getPrototypeOf(e),i=e,a=Object.getOwnPropertyNames(r).filter(e=>/^(on[A-Z]|one[A-Z])/.test(e)&&typeof r[e]==`function`);for(let e of a){let r=/^one/.test(e);n(t,e.replace(/^one?/,``),t=>i[e](t),r)}}function S(e){return Array.from(e.querySelectorAll(`[data-mc]:not(:scope [data-mc] [data-mc])`)).filter(e=>e instanceof HTMLElement&&`_mc`in e).map(e=>e._mc)}function C(e,t){let n=e.parentElement?.closest(`[data-mc]`);for(;n instanceof HTMLElement;){if(`_mc`in n){let e=n._mc;if(t===void 0||t in e)return e}n=n.parentElement?.closest(`[data-mc]`)}return null}var w=class{_target;constructor(e){if(this._target=new WeakRef(e||{}),this instanceof T&&this.constructor!==T){x(this);let e=this.constructor.tag;(e===void 0||e.toUpperCase()===this.target.tagName)&&b(this)}}get target(){return this._target.deref()}},T=class e extends w{static tag;static _assets={};static assets=[];static attributes={};constructor(t){super(t);let n=this.constructor;if(n===e)return;let r=this.target.tagName.toLowerCase();if(n.tag!==void 0&&r!==n.tag&&n.tag!==``){let t=document.createElement(n.tag);t.classList.add(r),n._originalTag=r,e.add(t,n.name,new n(t)),delete n._originalTag,r.includes(`-`)&&!this.target.isConnected?this.on(`connected`,()=>this.target.replaceWith(t)):this.target.replaceWith(t);return}let i=n.attributes;n.attributes&&Object.keys(n.attributes).forEach(e=>{this.target.setAttribute(e,i[e])});let a=n.assets.filter(e=>!n._assets[e]),o=this;if(n.hasOwnProperty(`_assets`)?m(this,n._assets):n.assets.length&&!n.hasOwnProperty(`_assets`)&&(n._assets={}),a.length?h(n._originalTag||r,a).then(e=>{let t={};a.forEach((n,r)=>{t[n]=e[r]}),m(this,t),n._assets=Object.assign({},n._assets,t);for(let e of[`css`,`targetCss`])t[e]!==void 0&&delete n._assets[e];n.assets=n.assets.filter(e=>e!==`css`&&e!==`targetCss`),o.trigger(`assets`,n._assets)}):[...Object.keys(n._assets)].length&&queueMicrotask(()=>o.trigger(`assets`,n._assets)),n.tag===``){this.target.remove();return}}getAssets(){return this.constructor._assets||{}}static add(e,t,n={}){return v(e,t,n)}static remove(e,t){y(e,t)}static get(e,t,n){if(!_(e))return;let r=e._mc[t];return r instanceof n?r:void 0}off(e,n){t(this.target,e,n)}on(e,t){return n(this.target,e,t)}one(e,t){return r(this.target,e,t)}trigger(e,t={},n=`l`,r){a(this.target,e,t,n,r)}ancestors(e){let t=[],n=C(this.target,e);for(;n;)t.push(n),n=C(n.target,e);return t}closest(e){return C(this.target,e)}children(e){let t=S(this.target);return e===void 0?t:t.filter(t=>e in t)}descendants(e){return Array.from(this.target.querySelectorAll(`[data-mc]`)).filter(e=>e instanceof HTMLElement&&`_mc`in e).map(e=>e._mc).filter(t=>e===void 0||e in t)}};function E(e){let t=new Set,n=/\{[^\{\}]*\}/g;return(e.getAttributeNames?e.getAttributeNames():[]).filter(t=>e.getAttribute(t)?.match(n)).forEach(r=>{new Set(e.getAttribute(r)?.match(n)).forEach(e=>t.add(e.replace(/[\{\}]/g,``)))}),[...e.childNodes].filter(e=>e.nodeType===3&&(e.nodeValue||``).match(n)).forEach(e=>{(e?.nodeValue||``).match(n).forEach(e=>t.add(e.replace(/[\{\}]/g,``)))}),[...t]}var D=[`INPUT`,`SELECT`,`TEXTAREA`],O=class extends T{data={};oldDisplay=``;constructor(e){super(e),E(e).forEach(e=>this.data[e]=``),I(this),this.#e()}#e(){let e=this.target,t=!1;(e.getAttributeNames?e.getAttributeNames():[]).filter(t=>e.getAttribute(t)?.match(/\{[^\{\}]*\}/g)).forEach(t=>{let n=new Set(e.getAttribute(t)?.match(/\{[^\{\}]*\}/g));this.data.subscribe((r=>i=>{let a=r;n.forEach(e=>{a=a.replace(e,String(i[e.replace(/[\{\}]/g,``)]))}),e.setAttribute(t,a)})(e.getAttribute(t)??``))}),[...e.childNodes].filter(e=>e.nodeType===3&&(e.nodeValue||``).match(/\{[^\{\}]*\}/g)).forEach(n=>{t=!0;let r=new Set((n.nodeValue??``).match(/\{[^\{\}]*\}/g));this.data.subscribe((t=>i=>{let a=t;r.forEach(e=>{a=a.replace(e,String(i[e.replace(/[\{\}]/g,``)]))}),this.oldDisplay?e.style=this.oldDisplay:e.removeAttribute(`style`),delete this.oldDisplay,n.nodeValue=a})(n.nodeValue??``)),this.oldDisplay=e.getAttribute(`style`)||``,t&&!D.includes(e.tagName)&&e.tagName!==`FIELDSET`&&(e.style.display=`none`)})}onData(e){let t={};Object.keys(e.detail.data).forEach(n=>{this.data.hasOwnProperty(n)&&(t[n]=e.detail.data[n])}),JSON.stringify(t)!==JSON.stringify(this.data)&&Object.assign(this.data,t)}};function k(e){return[e,...e.querySelectorAll(`*`)].filter(e=>!!E(e).length).filter(e=>e?.tagName!==`STYLE`).reverse()}function A(e){k(e).forEach(e=>{e?._mc?._placeholders||T.add(e,`_placeholders`,new O(e))})}function j(e){return typeof e==`object`&&!!e}var M={};function N(e){let t=e.constructor,n=t.name,r=class extends t{#e=!0;#t=[];constructor(e){super(e);let t=this.constructor;t.callbacks=[],j(e)&&Object.getOwnPropertyNames(e).forEach(t=>{this[t]=e[t]})}get callbacks(){return this.#t}set callbacks(e){this.#t=e}[Symbol.toPrimitive](e){let t=this.valueOf();return e===`string`?String(t):e===`number`?Number(t):t}subscribe(e){return this.#t.push(e),this}unsubscribe(e){return this.#t=this.#t.filter(t=>t!==e),this}bind(e){if(o()){if(j(this.valueOf())){A(e);let t=[e,...e.querySelectorAll(`[data-mc]`)].filter(e=>!!e?._mc?._placeholders);this.#t.push(function(e){let n=l(e);t.forEach(e=>{e&&a(e,`data`,n)})}),this.notify()}else console.warn(`IGNORED - cannot bind a non-Object to the dom, IS:`,typeof this.valueOf(),this);return this}}notify(e){let t=j(this.valueOf())&&!(this.valueOf()instanceof Array)?structuredClone(Object.assign({},this)):this.valueOf();return e!==void 0&&(this.#e=e),this.#e&&this.#t.forEach(e=>{e(t)}),this}};return M[n]=r,r}function P(e){return M[e.constructor.name]||N(e)}function F(e){return(typeof e==`object`||typeof e==`function`)&&e!==null&&`subscribe`in e}function I(e,t){let n=e;return(t?[t]:[...Object.getOwnPropertyNames(e)]).forEach(t=>{let r=n[t];if(Object.prototype.hasOwnProperty.call(e,t)&&typeof r!=`function`&&!F(r)){if(t[0]===`_`||r===void 0)return;let i=r,a=new(P(i))(i),o=function(){queueMicrotask(function(){a.notify()})};Object.defineProperty(e,t,{enumerable:!0,get(){if(j(a.valueOf())){let e=structuredClone(Object.assign({},a));queueMicrotask(function(){u(structuredClone(Object.assign({},a)),e)||o()})}return a},set(e){if(typeof e==typeof a.valueOf())if(j(a.valueOf())&&!(a.valueOf()instanceof Array))F(a)||(a=new(P(e))(structuredClone(Object.assign({},e))),d(e,a)),Object.assign(a,e),a.notify();else{let t=a.valueOf(),n=a.callbacks;e!==t&&(a=new(P(e))(e),a.callbacks=n,o())}else console.warn(`IGNORED - cannot change observable types, IS:`,typeof a.valueOf(),a,`- CANNOT BECOME:`,typeof e)}}),n[t]=i}}),e}function L(e){let t=Object.getPrototypeOf(e.prototype);function n(e,t){let n=e[t];F(n)||I(e,t)}Object.hasOwn(t,`notify`)||Object.assign(t,{notify:function(e){return n(this,e),this[e].notify(),this},subscribe:function(e,t){return n(this,e),this[e].subscribe(t),this},bind:function(e,t){return n(this,e),this[e].bind(t),this}})}export{F as isAlreadyObserved,I as observe,L as observePlugin};
|
|
1
|
+
function e(e,t){let n=t.toLowerCase();return`on`+n in e?n:`_mc`+t[0].toUpperCase()+t.substring(1)}function t(n,r,i){if(n){if(typeof n==`string`){document.querySelectorAll(n).forEach(e=>t(e,r,i));return}n.removeEventListener(e(n,r),i)}}function n(t,r,i,a=!1){if(t){if(typeof t==`string`){document.querySelectorAll(t).forEach(e=>n(e,r,i));return}return t.addEventListener(e(t,r),i,{capture:!1,once:a}),i}}function r(e,t,i){if(e){if(typeof e==`string`){document.querySelectorAll(e).forEach(e=>r(e,t,i));return}return n(e,t,i,!0),i}}var i=class{stopped=!1;constructor(){}stop(){this.stopped=!0}};function a(t,n,r={},o=`l`,s){if(!t)return;if(typeof t==`string`){document.querySelectorAll(t).forEach(e=>a(e,n,r,o));return}let c=/^_mc/.test(n)?n:e(t,n),l=s||new i,u=new CustomEvent(c,{detail:{data:r,control:l},bubbles:!1});l.stopped||/l/.test(o)&&(t.dispatchEvent(u),l.stopped)||/[ud]/.test(o)&&queueMicrotask(()=>{if(o.indexOf(`u`)>-1&&a(t.parentElement,c,r,`lu`,l),o.indexOf(`d`)>-1)for(let e of t.children)a(e,c,r,`ld`)})}function o(){return typeof window<`u`&&window.document!==void 0}function s(e){return typeof e==`object`&&!!e&&e.constructor===Object}function c(e){let t={},n=Object.keys(e).sort();for(let r=0;r<n.length;r++){let i=n[r],a=e[i];s(a)?t[i]=c(a):t[i]=a}return t}function l(e,t=!0){let n={},r=e,i=Object.getOwnPropertyNames(e);for(let e=0;e<i.length;e++){let t=i[e],a=r[t];if(a instanceof Object){let e=l(a,!1);for(let r in e)n[t+`.`+r]=e[r]}else n[t]=a}return t?c(n):n}function u(e,t){if(e===t||e!==e&&t!==t)return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t||e.constructor!==t.constructor)return!1;if(e instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp)return e.toString()===t.toString();if(Array.isArray(e)){let n=t;if(e.length!==n.length)return!1;for(let t=0;t<e.length;t++)if(!u(e[t],n[t]))return!1;return!0}let n=e,r=t,i=Object.keys(n);if(i.length!==Object.keys(r).length)return!1;for(let e=0;e<i.length;e++){let t=i[e];if(!Object.prototype.hasOwnProperty.call(r,t)||!u(n[t],r[t]))return!1}return!0}function d(e,t){let n=Object.getOwnPropertyDescriptors(e);for(let[e,r]of Object.entries(n))(`get`in r||`set`in r)&&Object.defineProperty(t,e,r)}var f=new WeakMap;function p(e,t){let n=f.get(e)??new Set;if(n.has(t))return e.adoptedStyleSheets[0];n.add(t),f.set(e,n);let r=new CSSStyleSheet;return r.replaceSync(t),e.adoptedStyleSheets.push(r),r}function m(e,t){let n=e.target,r=n.shadowRoot;!r&&Object.keys(t).some(e=>e.indexOf(`shadow`)===0)&&(r=n.attachShadow({mode:`open`})),Object.keys(t).forEach(i=>{switch(i){case`css`:p(document,t[i]);break;case`targetCss`:p(document,t[i]);break;case`shadowCss`:p(r,t[i]);break;case`shadowHtml`:r.innerHTML=t[i],g(r,e);break;case`targetHtml`:n.innerHTML=t[i],g(n,e);break}})}function h(e,t){let n=t=>{let n=t.match(/^([a-z]+)([A-Z][a-z]*)$/);return n?`./${e.replace(/-/g,`/`)}.${n[1]}.${n[2].toLowerCase()}`:`./${e.replace(/-/g,`/`)}.${t.toLowerCase()}`};return Promise.all(t.map(async e=>{let t=n(e);try{let n=await fetch(t);if(!n.ok)return`file not found: ${t}`;if(t.endsWith(`json`)){let r=await n.text();try{return JSON.parse(r)}catch{return console.error(`could not JSON.parse() asset '${e}' from ${t}:\n`,r),null}}return n.text()}catch{return`file not found: ${t}`}}))}function g(e,t){let r=[...e.querySelectorAll(`*`)];for(let e of r){if(!(e instanceof HTMLElement))continue;let r=[...e.attributes];for(let i of r){let r=i.name.toLowerCase();if(!(`on`+r in e))continue;let o=i.value.trim().split(`|`);if(o.length<2)continue;let[s,c,l]=o;e.removeAttribute(i.name);let u;if(l)try{u=JSON.parse(l)}catch{u=l}s===`this`||s===``?n(e,r,()=>t.trigger(c,u)):n(e,r,()=>a(s,c,u))}}}function _(e,t){return typeof HTMLElement<`u`&&e instanceof HTMLElement&&`_mc`in e&&(t===void 0||t in e._mc)}function v(e,t,n={}){let r=e;`_mc`in e||(r._mc=new T(e));let i=r._mc;return t.length&&!i[t]&&(i[t]=n,e instanceof HTMLElement&&!e.getAttribute(`data-mc`)&&e.setAttribute(`data-mc`,``)),r}function y(e,t){if(!t)return;let n=e._mc;n&&(n[t]&&delete n[t],!Object.keys(n).length&&e instanceof HTMLElement&&e.hasAttribute(`data-mc`)&&e.removeAttribute(`data-mc`))}function b(e){queueMicrotask(()=>{e.trigger(`Init`,null)})}function x(e){let t=e.target,r=Object.getPrototypeOf(e),i=e,a=Object.getOwnPropertyNames(r).filter(e=>/^(on[A-Z]|one[A-Z])/.test(e)&&typeof r[e]==`function`);for(let e of a){let r=/^one/.test(e);n(t,e.replace(/^one?/,``),t=>i[e](t),r)}}function S(e){return Array.from(e.querySelectorAll(`[data-mc]:not(:scope [data-mc] [data-mc])`)).filter(e=>e instanceof HTMLElement&&`_mc`in e).map(e=>e._mc)}function C(e,t){let n=e.parentElement?.closest(`[data-mc]`);for(;n instanceof HTMLElement;){if(`_mc`in n){let e=n._mc;if(t===void 0||t in e)return e}n=n.parentElement?.closest(`[data-mc]`)}return null}var w=class{_target;constructor(e){if(this._target=new WeakRef(e||{}),this instanceof T&&this.constructor!==T){x(this);let e=this.constructor.tag;(e===void 0||e.toUpperCase()===this.target.tagName)&&b(this)}}get target(){return this._target.deref()}},T=class e extends w{static tag;static _assets={};static assets=[];static _assetsPromise;static attributes={};constructor(t){super(t);let n=this.constructor;if(n===e)return;let r=this.target.tagName.toLowerCase();if(n.tag!==void 0&&r!==n.tag&&n.tag!==``){let t=document.createElement(n.tag);t.classList.add(r),n._originalTag=r,e.add(t,n.name,new n(t)),delete n._originalTag,r.includes(`-`)&&!this.target.isConnected?this.on(`connected`,()=>this.target.replaceWith(t)):this.target.replaceWith(t);return}let i=n.attributes;n.attributes&&Object.keys(n.attributes).forEach(e=>{this.target.setAttribute(e,i[e])});let a=this,o=n.assets.filter(e=>!n._assets[e]);if(Object.keys(n._assets).length&&m(this,n._assets),o.length?(n._assetsPromise||=h(n._originalTag||r,o).then(e=>{let t={};o.forEach((n,r)=>{t[n]=e[r]}),n._assets=Object.assign({},n._assets,t);for(let e of[`css`,`targetCss`])t[e]!==void 0&&delete n._assets[e];return n.assets=n.assets.filter(e=>e!==`css`&&e!==`targetCss`),t}),n._assetsPromise.then(e=>{m(this,e),a.trigger(`assets`,n._assets)})):[...Object.keys(n._assets)].length&&queueMicrotask(()=>a.trigger(`assets`,n._assets)),n.tag===``){this.target.remove();return}}getAssets(){return this.constructor._assets||{}}static add(e,t,n={}){return v(e,t,n)}static remove(e,t){y(e,t)}static get(e,t,n){if(!_(e))return;let r=e._mc[t];return r instanceof n?r:void 0}off(e,n){t(this.target,e,n)}on(e,t){return n(this.target,e,t)}one(e,t){return r(this.target,e,t)}trigger(e,t={},n=`l`,r){a(this.target,e,t,n,r)}ancestors(e){let t=[],n=C(this.target,e);for(;n;)t.push(n),n=C(n.target,e);return t}closest(e){return C(this.target,e)}children(e){let t=S(this.target);return e===void 0?t:t.filter(t=>e in t)}descendants(e){return Array.from(this.target.querySelectorAll(`[data-mc]`)).filter(e=>e instanceof HTMLElement&&`_mc`in e).map(e=>e._mc).filter(t=>e===void 0||e in t)}};function E(e){let t=new Set,n=/\{[^\{\}]*\}/g;return(e.getAttributeNames?e.getAttributeNames():[]).filter(t=>e.getAttribute(t)?.match(n)).forEach(r=>{new Set(e.getAttribute(r)?.match(n)).forEach(e=>t.add(e.replace(/[\{\}]/g,``)))}),[...e.childNodes].filter(e=>e.nodeType===3&&(e.nodeValue||``).match(n)).forEach(e=>{(e?.nodeValue||``).match(n).forEach(e=>t.add(e.replace(/[\{\}]/g,``)))}),[...t]}var D=[`INPUT`,`SELECT`,`TEXTAREA`],O=class extends T{data={};oldDisplay=``;constructor(e){super(e),E(e).forEach(e=>this.data[e]=``),I(this),this.#e()}#e(){let e=this.target,t=!1;(e.getAttributeNames?e.getAttributeNames():[]).filter(t=>e.getAttribute(t)?.match(/\{[^\{\}]*\}/g)).forEach(t=>{let n=new Set(e.getAttribute(t)?.match(/\{[^\{\}]*\}/g)),r=e.getAttribute(t)??``;this.data.subscribe((r=>i=>{let a=r;n.forEach(e=>{a=a.replace(e,String(i[e.replace(/[\{\}]/g,``)]))}),e.setAttribute(t,a)})(r))}),[...e.childNodes].filter(e=>e.nodeType===3&&(e.nodeValue||``).match(/\{[^\{\}]*\}/g)).forEach(n=>{t=!0;let r=n.nodeValue??``,i=new Set(r.match(/\{[^\{\}]*\}/g));this.data.subscribe((t=>r=>{let a=t;i.forEach(e=>{a=a.replace(e,String(r[e.replace(/[\{\}]/g,``)]))}),this.oldDisplay?e.style=this.oldDisplay:e.removeAttribute(`style`),delete this.oldDisplay,n.nodeValue=a})(r)),this.oldDisplay=e.getAttribute(`style`)||``,t&&!D.includes(e.tagName)&&e.tagName!==`FIELDSET`&&(e.style.display=`none`)})}onData(e){let t={};Object.keys(e.detail.data).forEach(n=>{this.data.hasOwnProperty(n)&&(t[n]=e.detail.data[n])}),JSON.stringify(t)!==JSON.stringify(this.data)&&Object.assign(this.data,t)}};function k(e){return[e,...e.querySelectorAll(`*`)].filter(e=>!!E(e).length).filter(e=>e?.tagName!==`STYLE`).reverse()}function A(e){k(e).forEach(e=>{e?._mc?._placeholders||T.add(e,`_placeholders`,new O(e))})}function j(e){return typeof e==`object`&&!!e}var M={};function N(e){let t=e.constructor,n=t.name,r=class extends t{#e=!0;#t=[];constructor(e){super(e);let t=this.constructor;t.callbacks=[],j(e)&&Object.getOwnPropertyNames(e).forEach(t=>{this[t]=e[t]})}get callbacks(){return this.#t}set callbacks(e){this.#t=e}[Symbol.toPrimitive](e){let t=this.valueOf();return e===`string`?String(t):e===`number`?Number(t):t}subscribe(e){return this.#t.push(e),this}unsubscribe(e){return this.#t=this.#t.filter(t=>t!==e),this}bind(e){if(o()){if(j(this.valueOf())){A(e);let t=[e,...e.querySelectorAll(`[data-mc]`)].filter(e=>!!e?._mc?._placeholders);this.#t.push(function(e){let n=l(e);t.forEach(e=>{e&&a(e,`data`,n)})}),this.notify()}else console.warn(`IGNORED - cannot bind a non-Object to the dom, IS:`,typeof this.valueOf(),this);return this}}notify(e){let t=j(this.valueOf())&&!(this.valueOf()instanceof Array)?structuredClone(Object.assign({},this)):this.valueOf();return e!==void 0&&(this.#e=e),this.#e&&this.#t.forEach(e=>{e(t)}),this}};return M[n]=r,r}function P(e){return M[e.constructor.name]||N(e)}function F(e){return(typeof e==`object`||typeof e==`function`)&&e!==null&&`subscribe`in e}function I(e,t){let n=e;return(t?[t]:[...Object.getOwnPropertyNames(e)]).forEach(t=>{let r=n[t];if(Object.prototype.hasOwnProperty.call(e,t)&&typeof r!=`function`&&!F(r)){if(t[0]===`_`||r===void 0)return;let i=r,a=new(P(i))(i),o=function(){queueMicrotask(function(){a.notify()})};Object.defineProperty(e,t,{enumerable:!0,get(){if(j(a.valueOf())){let e=structuredClone(Object.assign({},a));queueMicrotask(function(){u(structuredClone(Object.assign({},a)),e)||o()})}return a},set(e){if(typeof e==typeof a.valueOf())if(j(a.valueOf())&&!(a.valueOf()instanceof Array))F(a)||(a=new(P(e))(structuredClone(Object.assign({},e))),d(e,a)),Object.assign(a,e),a.notify();else{let t=a.valueOf(),n=a.callbacks;e!==t&&(a=new(P(e))(e),a.callbacks=n,o())}else console.warn(`IGNORED - cannot change observable types, IS:`,typeof a.valueOf(),a,`- CANNOT BECOME:`,typeof e)}}),n[t]=i}}),e}function L(e){let t=Object.getPrototypeOf(e.prototype);function n(e,t){let n=e[t];F(n)||I(e,t)}Object.hasOwn(t,`notify`)||Object.assign(t,{notify:function(e){return n(this,e),this[e].notify(),this},subscribe:function(e,t){return n(this,e),this[e].subscribe(t),this},bind:function(e,t){return n(this,e),this[e].bind(t),this}})}export{F as isAlreadyObserved,I as observe,L as observePlugin};
|
|
@@ -42,9 +42,12 @@ import { formValues } from '@twobirds/microcomponents/formValues';
|
|
|
42
42
|
|
|
43
43
|
const state = {};
|
|
44
44
|
formValues(state, 'formData', document.getElementById('myForm'));
|
|
45
|
-
console.log(state.formData.username);
|
|
46
|
-
state.formData.role = 'admin';
|
|
45
|
+
console.log(state.formData.username);
|
|
46
|
+
state.formData.role = 'admin';
|
|
47
47
|
```
|
|
48
|
+
|
|
49
|
+
Reading `state.formData.username` reflects the live `<input name="username">` value;
|
|
50
|
+
assigning `state.formData.role` writes straight back to the `<select>` control.
|
|
48
51
|
*/
|
|
49
52
|
/**
|
|
50
53
|
@hidden
|
|
@@ -66,10 +69,13 @@ import { formValues } from '@twobirds/microcomponents/formValues';
|
|
|
66
69
|
|
|
67
70
|
const state = {};
|
|
68
71
|
formValues(state, 'formData', document.getElementById('myForm'));
|
|
69
|
-
console.log(state.formData.username);
|
|
70
|
-
state.formData.role = 'admin';
|
|
72
|
+
console.log(state.formData.username);
|
|
73
|
+
state.formData.role = 'admin';
|
|
71
74
|
```
|
|
72
75
|
|
|
76
|
+
Reading `state.formData.username` reflects the live `<input name="username">` value;
|
|
77
|
+
assigning `state.formData.role` writes straight back to the `<select>` control.
|
|
78
|
+
|
|
73
79
|
@example Subscribe to form changes inside a component
|
|
74
80
|
```ts
|
|
75
81
|
import { DC, defineCE, formValues } from '@twobirds/microcomponents';
|
|
@@ -122,7 +128,7 @@ defineCE('checkout-form', CheckoutForm);
|
|
|
122
128
|
export declare function formValuePlugin(Class: any): void;
|
|
123
129
|
declare module '../core/MC' {
|
|
124
130
|
interface McBase<TTarget extends object = object> {
|
|
125
|
-
formValues(target:
|
|
131
|
+
formValues<K extends keyof this & string>(target: HTMLElement | ShadowRoot, propName: K): this;
|
|
126
132
|
}
|
|
127
133
|
}
|
|
128
134
|
//# sourceMappingURL=formValues.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formValues.d.ts","sourceRoot":"","sources":["../../src/state/formValues.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"formValues.d.ts","sourceRoot":"","sources":["../../src/state/formValues.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkDE;AA8SF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0CE;AACF,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAC1C,YAAY,EAAE,CAAC,EACf,YAAY,EAAE,MAAM,CAAC,GAAG,MAAM,EAC9B,GAAG,EAAE,WAAW,GAAG,UAAU,QAuB7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BE;AACF,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,QAyBzC;AAID,OAAO,QAAQ,YAAY,CAAC;IAC3B,UAAiB,MAAM,CAAC,OAAO,SAAS,MAAM,GAAG,MAAM;QACtD,UAAU,CAAC,CAAC,SAAS,MAAM,IAAI,GAAG,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,UAAU,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC;KAC/F;CACD"}
|
package/dist/state/formValues.js
CHANGED
|
@@ -42,9 +42,12 @@ import { formValues } from '@twobirds/microcomponents/formValues';
|
|
|
42
42
|
|
|
43
43
|
const state = {};
|
|
44
44
|
formValues(state, 'formData', document.getElementById('myForm'));
|
|
45
|
-
console.log(state.formData.username);
|
|
46
|
-
state.formData.role = 'admin';
|
|
45
|
+
console.log(state.formData.username);
|
|
46
|
+
state.formData.role = 'admin';
|
|
47
47
|
```
|
|
48
|
+
|
|
49
|
+
Reading `state.formData.username` reflects the live `<input name="username">` value;
|
|
50
|
+
assigning `state.formData.role` writes straight back to the `<select>` control.
|
|
48
51
|
*/
|
|
49
52
|
import { DC } from '../core/MC.js';
|
|
50
53
|
import { copyGettersSetters, isBrowser } from '../utils/helpers.js';
|
|
@@ -315,10 +318,13 @@ import { formValues } from '@twobirds/microcomponents/formValues';
|
|
|
315
318
|
|
|
316
319
|
const state = {};
|
|
317
320
|
formValues(state, 'formData', document.getElementById('myForm'));
|
|
318
|
-
console.log(state.formData.username);
|
|
319
|
-
state.formData.role = 'admin';
|
|
321
|
+
console.log(state.formData.username);
|
|
322
|
+
state.formData.role = 'admin';
|
|
320
323
|
```
|
|
321
324
|
|
|
325
|
+
Reading `state.formData.username` reflects the live `<input name="username">` value;
|
|
326
|
+
assigning `state.formData.role` writes straight back to the `<select>` control.
|
|
327
|
+
|
|
322
328
|
@example Subscribe to form changes inside a component
|
|
323
329
|
```ts
|
|
324
330
|
import { DC, defineCE, formValues } from '@twobirds/microcomponents';
|
|
@@ -390,18 +396,19 @@ export function formValuePlugin(Class) {
|
|
|
390
396
|
if (!Object.hasOwn(McBaseProto, 'formValues')) {
|
|
391
397
|
Object.assign(McBaseProto, {
|
|
392
398
|
/**
|
|
393
|
-
* Bind all named form controls inside a DOM subtree to an observable property on this instance.
|
|
394
|
-
* Ensures the property becomes observable and stays in sync with input changes.
|
|
395
|
-
* @param target - HTMLElement or ShadowRoot containing the form controls.
|
|
396
|
-
* @param propName - The name of the property that will hold the bound form data.
|
|
397
|
-
* @returns This instance for chaining.
|
|
399
|
+
* Bind all named form controls inside a DOM subtree to an observable property on this instance.
|
|
400
|
+
* Ensures the property becomes observable and stays in sync with input changes.
|
|
401
|
+
* @param target - HTMLElement or ShadowRoot containing the form controls.
|
|
402
|
+
* @param propName - The name of the property that will hold the bound form data.
|
|
403
|
+
* @returns This instance for chaining.
|
|
398
404
|
|
|
399
405
|
@example
|
|
400
406
|
```ts
|
|
401
407
|
this.formValues(this.target, 'formData');
|
|
402
|
-
// now this.formData.username reflects <input name="username"> live
|
|
403
408
|
```
|
|
404
|
-
|
|
409
|
+
|
|
410
|
+
After this call, `this.formData.username` reflects the live `<input name="username">` value.
|
|
411
|
+
*/
|
|
405
412
|
formValues: function (target, propName) {
|
|
406
413
|
formValues(this, propName, target);
|
|
407
414
|
return this; // chainable
|
|
@@ -44,27 +44,33 @@ import { observe } from '@twobirds/microcomponents';
|
|
|
44
44
|
|
|
45
45
|
const state = observe({ count: 0, label: 'hi' });
|
|
46
46
|
state.count.subscribe((v) => console.log('count is now', v));
|
|
47
|
-
state.count++;
|
|
47
|
+
state.count++;
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
Incrementing `state.count` triggers the subscribed callback.
|
|
51
|
+
|
|
50
52
|
@example Deep change detection on a nested property
|
|
51
53
|
```ts
|
|
52
54
|
import { observe } from '@twobirds/microcomponents';
|
|
53
55
|
|
|
54
56
|
const state = observe({ data: { name: 'John', age: 30 } });
|
|
55
57
|
state.data.subscribe((d) => console.log('data changed:', d));
|
|
56
|
-
state.data.name = 'Jane';
|
|
58
|
+
state.data.name = 'Jane';
|
|
57
59
|
```
|
|
58
60
|
|
|
61
|
+
Writing into a nested property triggers the callback with the updated object.
|
|
62
|
+
|
|
59
63
|
@example DOM binding — only observable properties that hold objects can be bound
|
|
60
64
|
```ts
|
|
61
65
|
import { observe } from '@twobirds/microcomponents';
|
|
62
66
|
|
|
63
67
|
const state = observe({ user: { name: 'Alice', count: 0 } });
|
|
64
68
|
state.user.bind(document.querySelector('.model'));
|
|
65
|
-
// <span>{name}</span> and <span>{count}</span> update automatically
|
|
66
69
|
```
|
|
67
70
|
|
|
71
|
+
Inside the bound model, `<span>{name}</span>` and `<span>{count}</span>` update
|
|
72
|
+
automatically on every change.
|
|
73
|
+
|
|
68
74
|
*/
|
|
69
75
|
/**
|
|
70
76
|
@hidden
|
|
@@ -88,8 +94,10 @@ They can also be bound to a DOM target to automatically update placeholder value
|
|
|
88
94
|
```ts
|
|
89
95
|
const state = observe({ count: 0 });
|
|
90
96
|
state.count.subscribe((v) => console.log('count is now', v));
|
|
91
|
-
state.count++;
|
|
97
|
+
state.count++;
|
|
92
98
|
```
|
|
99
|
+
|
|
100
|
+
The subscription fires on the increment, logging `count is now 1`.
|
|
93
101
|
*/
|
|
94
102
|
export type Observable<T = unknown> = T & {
|
|
95
103
|
subscribe(callback: Callback<T>): Observable<T>;
|
|
@@ -123,8 +131,10 @@ Until then, use one of the supported write paths:
|
|
|
123
131
|
@example
|
|
124
132
|
```ts
|
|
125
133
|
type State = Observed<{ count: number; name: string }>;
|
|
126
|
-
// { count: Observable<number>, name: Observable<string> }
|
|
127
134
|
```
|
|
135
|
+
|
|
136
|
+
Every property is mapped to an observable: `State` is
|
|
137
|
+
`{ count: Observable<number>, name: Observable<string> }`.
|
|
128
138
|
*/
|
|
129
139
|
export type Observed<T> = {
|
|
130
140
|
[K in keyof T]: Observable<T[K]>;
|
|
@@ -137,8 +147,10 @@ Carries the same write limitation as {@link Observed} for the mapped key.
|
|
|
137
147
|
@example
|
|
138
148
|
```ts
|
|
139
149
|
type State = ObservedKey<{ count: number; label: string }, 'count'>;
|
|
140
|
-
// { count: Observable<number>, label: string }
|
|
141
150
|
```
|
|
151
|
+
|
|
152
|
+
Only `count` is mapped to an observable: `State` is
|
|
153
|
+
`{ count: Observable<number>, label: string }`.
|
|
142
154
|
*/
|
|
143
155
|
export type ObservedKey<T, K extends keyof T> = {
|
|
144
156
|
[P in keyof T]: P extends K ? Observable<T[P]> : T[P];
|
|
@@ -162,9 +174,12 @@ interface CounterState {
|
|
|
162
174
|
get count(): Observable<number>;
|
|
163
175
|
set count(v: number);
|
|
164
176
|
}
|
|
165
|
-
type Seed = Unobserved<CounterState>;
|
|
166
|
-
const state = observe<CounterState>({ count: 0 });
|
|
177
|
+
type Seed = Unobserved<CounterState>;
|
|
178
|
+
const state = observe<CounterState>({ count: 0 });
|
|
167
179
|
```
|
|
180
|
+
|
|
181
|
+
`Seed` strips the wrapper, yielding the plain seed shape `{ count: number }`. The
|
|
182
|
+
`observe<CounterState>()` overload validates the seed object against the schema.
|
|
168
183
|
*/
|
|
169
184
|
export type Unobserved<S> = {
|
|
170
185
|
[K in keyof S]: S[K] extends {
|
|
@@ -179,9 +194,11 @@ Used by {@link observe} to skip re-wrapping and to detect the "not yet observed"
|
|
|
179
194
|
@example
|
|
180
195
|
```ts
|
|
181
196
|
const state = observe({ count: 0 });
|
|
182
|
-
isAlreadyObserved(state.count);
|
|
183
|
-
isAlreadyObserved(42);
|
|
197
|
+
console.log(isAlreadyObserved(state.count));
|
|
198
|
+
console.log(isAlreadyObserved(42));
|
|
184
199
|
```
|
|
200
|
+
|
|
201
|
+
The wrapped property reports `true`, a plain primitive reports `false`.
|
|
185
202
|
*/
|
|
186
203
|
export declare function isAlreadyObserved(value: unknown): boolean;
|
|
187
204
|
export declare function observe<T extends object, K extends keyof T>(target: T, propertyName: K): ObservedKey<T, K>;
|
|
@@ -214,9 +231,9 @@ class Counter extends DC {
|
|
|
214
231
|
export declare function observePlugin(Class: any): void;
|
|
215
232
|
declare module '../core/MC' {
|
|
216
233
|
interface McBase<TTarget extends object = object> {
|
|
217
|
-
notify(propName:
|
|
218
|
-
subscribe(propName:
|
|
219
|
-
bind(propName:
|
|
234
|
+
notify<K extends keyof this & string>(propName: K): this;
|
|
235
|
+
subscribe<K extends keyof this & string>(propName: K, callback: (value: this[K]) => void): this;
|
|
236
|
+
bind<K extends keyof this & string>(propName: K, target: HTMLElement | DocumentFragment | ShadowRoot): this;
|
|
220
237
|
}
|
|
221
238
|
}
|
|
222
239
|
//# sourceMappingURL=observables.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observables.d.ts","sourceRoot":"","sources":["../../src/state/observables.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"observables.d.ts","sourceRoot":"","sources":["../../src/state/observables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyEE;AAkBF;;;;;;;;;EASE;AACF,MAAM,MAAM,QAAQ,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAEvD;;;;;;;;;;;;;;;EAeE;AACF,MAAM,MAAM,UAAU,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,GAAG;IACzC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAChD,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,gBAAgB,GAAG,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IACzE,cAAc;IACd,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;CAC3B,CAAC;AAuOF;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BE;AACF,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAE/D;;;;;;;;;;;;EAYE;AACF,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI;KAC9C,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;EAyBE;AACF,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;KAC1B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;QAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,GAAG,OAAO,CAAA;KAAE,GACpF,CAAC,GACD,CAAC,CAAC,CAAC,CAAC;CACP,CAAC;AAKF;;;;;;;;;;;;;EAaE;AACF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAMzD;AAED,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,EAC1D,MAAM,EAAE,CAAC,EACT,YAAY,EAAE,CAAC,GACb,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACrB,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;AAClE,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAgJpE;;;;;;;;;;;;;;;;;;;;;;;EAuBE;AACF,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,QAiEvC;AAOD,OAAO,QAAQ,YAAY,CAAC;IAC3B,UAAiB,MAAM,CAAC,OAAO,SAAS,MAAM,GAAG,MAAM;QACtD,MAAM,CAAC,CAAC,SAAS,MAAM,IAAI,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC;QACzD,SAAS,CAAC,CAAC,SAAS,MAAM,IAAI,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;QAChG,IAAI,CAAC,CAAC,SAAS,MAAM,IAAI,GAAG,MAAM,EACjC,QAAQ,EAAE,CAAC,EACX,MAAM,EAAE,WAAW,GAAG,gBAAgB,GAAG,UAAU,GACjD,IAAI,CAAC;KACR;CACD"}
|
|
@@ -44,27 +44,33 @@ import { observe } from '@twobirds/microcomponents';
|
|
|
44
44
|
|
|
45
45
|
const state = observe({ count: 0, label: 'hi' });
|
|
46
46
|
state.count.subscribe((v) => console.log('count is now', v));
|
|
47
|
-
state.count++;
|
|
47
|
+
state.count++;
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
Incrementing `state.count` triggers the subscribed callback.
|
|
51
|
+
|
|
50
52
|
@example Deep change detection on a nested property
|
|
51
53
|
```ts
|
|
52
54
|
import { observe } from '@twobirds/microcomponents';
|
|
53
55
|
|
|
54
56
|
const state = observe({ data: { name: 'John', age: 30 } });
|
|
55
57
|
state.data.subscribe((d) => console.log('data changed:', d));
|
|
56
|
-
state.data.name = 'Jane';
|
|
58
|
+
state.data.name = 'Jane';
|
|
57
59
|
```
|
|
58
60
|
|
|
61
|
+
Writing into a nested property triggers the callback with the updated object.
|
|
62
|
+
|
|
59
63
|
@example DOM binding — only observable properties that hold objects can be bound
|
|
60
64
|
```ts
|
|
61
65
|
import { observe } from '@twobirds/microcomponents';
|
|
62
66
|
|
|
63
67
|
const state = observe({ user: { name: 'Alice', count: 0 } });
|
|
64
68
|
state.user.bind(document.querySelector('.model'));
|
|
65
|
-
// <span>{name}</span> and <span>{count}</span> update automatically
|
|
66
69
|
```
|
|
67
70
|
|
|
71
|
+
Inside the bound model, `<span>{name}</span>` and `<span>{count}</span>` update
|
|
72
|
+
automatically on every change.
|
|
73
|
+
|
|
68
74
|
*/
|
|
69
75
|
import { flattenObject, deepEqual, copyGettersSetters, isBrowser } from '../utils/helpers.js';
|
|
70
76
|
import { makePlaceholders } from './placeholders.js';
|
|
@@ -126,10 +132,14 @@ function makeObservable(val) {
|
|
|
126
132
|
@example
|
|
127
133
|
```ts
|
|
128
134
|
const state = observe({ count: 42 });
|
|
129
|
-
console.log(state.count + 10);
|
|
130
|
-
console.log(`${state.count}`);
|
|
131
|
-
state.count.subscribe(v => console.log('changed to', v));
|
|
135
|
+
console.log(state.count + 10);
|
|
136
|
+
console.log(`${state.count}`);
|
|
137
|
+
state.count.subscribe((v) => console.log('changed to', v));
|
|
132
138
|
```
|
|
139
|
+
|
|
140
|
+
Arithmetic coerces with `hint === 'number'` (logs `52`), interpolation with
|
|
141
|
+
`hint === 'string'` (logs `"42"`), and `.subscribe()` stays callable on the
|
|
142
|
+
wrapper.
|
|
133
143
|
*/
|
|
134
144
|
[Symbol.toPrimitive](hint) {
|
|
135
145
|
const value = this.valueOf();
|
|
@@ -149,8 +159,10 @@ function makeObservable(val) {
|
|
|
149
159
|
```ts
|
|
150
160
|
const state = observe({ count: 0 });
|
|
151
161
|
state.count.subscribe((v) => console.log('count changed to', v));
|
|
152
|
-
state.count++;
|
|
162
|
+
state.count++;
|
|
153
163
|
```
|
|
164
|
+
|
|
165
|
+
The increment fires the callback, logging `count changed to 1`.
|
|
154
166
|
*/
|
|
155
167
|
subscribe(callback) {
|
|
156
168
|
this.#callbacks.push(callback);
|
|
@@ -171,8 +183,10 @@ function makeObservable(val) {
|
|
|
171
183
|
const state = observe({ count: 0 });
|
|
172
184
|
const log = (v) => console.log(v);
|
|
173
185
|
state.count.subscribe(log);
|
|
174
|
-
state.count.unsubscribe(log);
|
|
186
|
+
state.count.unsubscribe(log);
|
|
175
187
|
```
|
|
188
|
+
|
|
189
|
+
After `unsubscribe(log)`, the callback no longer fires on changes.
|
|
176
190
|
*/
|
|
177
191
|
unsubscribe(callback) {
|
|
178
192
|
this.#callbacks = this.#callbacks.filter((registered) => registered !== callback);
|
|
@@ -190,9 +204,12 @@ function makeObservable(val) {
|
|
|
190
204
|
|
|
191
205
|
@example
|
|
192
206
|
```ts
|
|
193
|
-
const state = observe({ name: 'Alice', count: 0 });
|
|
194
|
-
state.
|
|
207
|
+
const state = observe({ user: { name: 'Alice', count: 0 } });
|
|
208
|
+
state.user.bind(document.querySelector('.model'));
|
|
195
209
|
```
|
|
210
|
+
|
|
211
|
+
Only object-valued observables can be bound: inside the model, `{name}` and
|
|
212
|
+
`{count}` placeholders update on every change.
|
|
196
213
|
*/
|
|
197
214
|
bind(target) {
|
|
198
215
|
if (!isBrowser())
|
|
@@ -236,8 +253,11 @@ function makeObservable(val) {
|
|
|
236
253
|
```ts
|
|
237
254
|
const state = observe({ count: 0 });
|
|
238
255
|
state.count.subscribe((v) => console.log('notified:', v));
|
|
239
|
-
state.count.notify();
|
|
256
|
+
state.count.notify();
|
|
240
257
|
```
|
|
258
|
+
|
|
259
|
+
The manual `notify()` call pushes the current value to subscribers, logging
|
|
260
|
+
`notified: 0`.
|
|
241
261
|
*/
|
|
242
262
|
notify(notify) {
|
|
243
263
|
const data = isObservableObject(this.valueOf()) && this.valueOf() instanceof Array === false
|
|
@@ -276,9 +296,11 @@ Used by {@link observe} to skip re-wrapping and to detect the "not yet observed"
|
|
|
276
296
|
@example
|
|
277
297
|
```ts
|
|
278
298
|
const state = observe({ count: 0 });
|
|
279
|
-
isAlreadyObserved(state.count);
|
|
280
|
-
isAlreadyObserved(42);
|
|
299
|
+
console.log(isAlreadyObserved(state.count));
|
|
300
|
+
console.log(isAlreadyObserved(42));
|
|
281
301
|
```
|
|
302
|
+
|
|
303
|
+
The wrapped property reports `true`, a plain primitive reports `false`.
|
|
282
304
|
*/
|
|
283
305
|
export function isAlreadyObserved(value) {
|
|
284
306
|
return ((typeof value === 'object' || typeof value === 'function') &&
|
|
@@ -314,9 +336,11 @@ back as `Observable<PropertyType>`.
|
|
|
314
336
|
```ts
|
|
315
337
|
const state = observe({ count: 0, label: 'hi' });
|
|
316
338
|
state.count.subscribe((v) => console.log('count is now', v));
|
|
317
|
-
state.count++;
|
|
339
|
+
state.count++;
|
|
318
340
|
```
|
|
319
341
|
|
|
342
|
+
Incrementing `state.count` triggers the subscribed callback.
|
|
343
|
+
|
|
320
344
|
@example Declarative usage — typed class field with double cast:
|
|
321
345
|
```ts
|
|
322
346
|
class Counter {
|
|
@@ -327,11 +351,13 @@ class Counter {
|
|
|
327
351
|
}
|
|
328
352
|
|
|
329
353
|
bump() {
|
|
330
|
-
this.clicks++;
|
|
354
|
+
this.clicks++;
|
|
331
355
|
}
|
|
332
356
|
}
|
|
333
357
|
```
|
|
334
358
|
|
|
359
|
+
Plain arithmetic compiles because the declaration carries the observable type.
|
|
360
|
+
|
|
335
361
|
@example Schema-first usage — divergent read/write types via hand-declared interface:
|
|
336
362
|
```ts
|
|
337
363
|
interface CounterState {
|
|
@@ -339,10 +365,13 @@ interface CounterState {
|
|
|
339
365
|
set count(v: number);
|
|
340
366
|
}
|
|
341
367
|
|
|
342
|
-
const state = observe<CounterState>({ count: 0 });
|
|
343
|
-
state.count.subscribe((v) => console.log(v));
|
|
344
|
-
state.count = 5;
|
|
368
|
+
const state = observe<CounterState>({ count: 0 });
|
|
369
|
+
state.count.subscribe((v) => console.log(v));
|
|
370
|
+
state.count = 5;
|
|
345
371
|
```
|
|
372
|
+
|
|
373
|
+
The seed object is validated against the schema, the subscription callback is fully
|
|
374
|
+
typed, and plain assignment is legal because the declared setter type permits it.
|
|
346
375
|
*/
|
|
347
376
|
export function observe(target, propertyName) {
|
|
348
377
|
const source = target;
|
|
@@ -443,50 +472,50 @@ export function observePlugin(Class) {
|
|
|
443
472
|
if (!Object.hasOwn(McBaseProto, 'notify')) {
|
|
444
473
|
Object.assign(McBaseProto, {
|
|
445
474
|
/**
|
|
446
|
-
* Manually trigger a notification on an observable property.
|
|
447
|
-
* Ensures the property is observed first if it hasn't been yet.
|
|
448
|
-
* @param propName - The name of the observable property to notify.
|
|
449
|
-
* @returns This instance for chaining.
|
|
475
|
+
* Manually trigger a notification on an observable property.
|
|
476
|
+
* Ensures the property is observed first if it hasn't been yet.
|
|
477
|
+
* @param propName - The name of the observable property to notify.
|
|
478
|
+
* @returns This instance for chaining.
|
|
450
479
|
|
|
451
480
|
@example
|
|
452
481
|
```ts
|
|
453
482
|
this.notify('count');
|
|
454
483
|
```
|
|
455
|
-
|
|
484
|
+
*/
|
|
456
485
|
notify: function (propName) {
|
|
457
486
|
makePropObservable(this, propName);
|
|
458
487
|
this[propName].notify();
|
|
459
488
|
return this; // chainable
|
|
460
489
|
},
|
|
461
490
|
/**
|
|
462
|
-
* Subscribe a callback to changes on an observable property.
|
|
463
|
-
* Ensures the property is observed first if it hasn't been yet.
|
|
464
|
-
* @param propName - The name of the observable property.
|
|
465
|
-
* @param callback - Function invoked with the new value on every change.
|
|
466
|
-
* @returns This instance for chaining.
|
|
491
|
+
* Subscribe a callback to changes on an observable property.
|
|
492
|
+
* Ensures the property is observed first if it hasn't been yet.
|
|
493
|
+
* @param propName - The name of the observable property.
|
|
494
|
+
* @param callback - Function invoked with the new value on every change.
|
|
495
|
+
* @returns This instance for chaining.
|
|
467
496
|
|
|
468
497
|
@example
|
|
469
498
|
```ts
|
|
470
499
|
this.subscribe('count', (v) => console.log('count →', v));
|
|
471
500
|
```
|
|
472
|
-
|
|
501
|
+
*/
|
|
473
502
|
subscribe: function (propName, callback) {
|
|
474
503
|
makePropObservable(this, propName);
|
|
475
504
|
this[propName].subscribe(callback);
|
|
476
505
|
return this; // chainable
|
|
477
506
|
},
|
|
478
507
|
/**
|
|
479
|
-
* Bind an observable property to a DOM target so that `{placeholder}` tokens are updated live.
|
|
480
|
-
* Ensures the property is observed first if it hasn't been yet.
|
|
481
|
-
* @param propName - The name of the observable property.
|
|
482
|
-
* @param target - HTMLElement, ShadowRoot, or DocumentFragment containing placeholders.
|
|
483
|
-
* @returns This instance for chaining.
|
|
508
|
+
* Bind an observable property to a DOM target so that `{placeholder}` tokens are updated live.
|
|
509
|
+
* Ensures the property is observed first if it hasn't been yet.
|
|
510
|
+
* @param propName - The name of the observable property.
|
|
511
|
+
* @param target - HTMLElement, ShadowRoot, or DocumentFragment containing placeholders.
|
|
512
|
+
* @returns This instance for chaining.
|
|
484
513
|
|
|
485
514
|
@example
|
|
486
515
|
```ts
|
|
487
516
|
this.bind('data', this.target);
|
|
488
517
|
```
|
|
489
|
-
|
|
518
|
+
*/
|
|
490
519
|
bind: function (propName, target) {
|
|
491
520
|
makePropObservable(this, propName);
|
|
492
521
|
this[propName].bind(target);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"placeholders.d.ts","sourceRoot":"","sources":["../../src/state/placeholders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;EAUE;AAEF,OAAO,EAAE,EAAE,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAoD5D;;;;;;EAME;AACF,cAAM,YAAa,SAAQ,EAAE;;IAE5B,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAwD;IACjG,UAAU,CAAC,EAAE,MAAM,CAAM;IAEzB;;;;;;;;MAQE;gBACU,MAAM,EAAE,WAAW;
|
|
1
|
+
{"version":3,"file":"placeholders.d.ts","sourceRoot":"","sources":["../../src/state/placeholders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;EAUE;AAEF,OAAO,EAAE,EAAE,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAoD5D;;;;;;EAME;AACF,cAAM,YAAa,SAAQ,EAAE;;IAE5B,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAwD;IACjG,UAAU,CAAC,EAAE,MAAM,CAAM;IAEzB;;;;;;;;MAQE;gBACU,MAAM,EAAE,WAAW;IAuF/B;;;;;;;MAOE;IACF,MAAM,CAAC,EAAE,EAAE,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAOzD;AAmBD;;;;;;;EAOE;AACF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,gBAAgB,GAAG,UAAU,GAAG,IAAI,CAK3F;AAED;;;;EAIE;AACF,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,WAAW,EAAE;IAAE,aAAa,CAAC,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC"}
|