├── .gitignore ├── README.md ├── package.json ├── public ├── css │ ├── index.css │ └── my-counter.css ├── favicon.ico ├── index.html ├── js │ ├── index.js │ └── my-counter.js ├── node_modules │ ├── @ungap │ │ └── create-content │ │ │ └── esm │ │ │ └── index.js │ ├── uarray │ │ └── esm │ │ │ └── index.js │ ├── uce │ │ └── esm │ │ │ └── index.js │ ├── udomdiff │ │ └── esm │ │ │ └── index.js │ ├── uhandlers │ │ └── esm │ │ │ └── index.js │ ├── uhtml │ │ └── esm │ │ │ ├── handlers.js │ │ │ ├── index.js │ │ │ ├── node.js │ │ │ └── rabbit.js │ ├── umap │ │ └── esm │ │ │ └── index.js │ ├── uparser │ │ └── esm │ │ │ └── index.js │ └── uwire │ │ └── esm │ │ └── index.js ├── package.json └── u_modules │ ├── @ungap │ └── create-content │ │ └── esm │ │ └── index.js │ ├── uarray │ └── esm │ │ └── index.js │ ├── uce │ └── esm │ │ └── index.js │ ├── udomdiff │ └── esm │ │ └── index.js │ ├── uhandlers │ └── esm │ │ └── index.js │ ├── uhtml │ └── esm │ │ ├── handlers.js │ │ ├── index.js │ │ ├── node.js │ │ └── rabbit.js │ ├── umap │ └── esm │ │ └── index.js │ ├── uparser │ └── esm │ │ └── index.js │ └── uwire │ └── esm │ └── index.js └── src ├── css ├── index.css └── my-counter.css ├── favicon.ico ├── index.html ├── js ├── index.js └── my-counter.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | !public/node_modules 3 | cdn/ 4 | src/node_modules/ 5 | package-lock.json 6 | src/package-lock.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [µcompress](https://github.com/WebReflection/ucompress#readme) and [µcdn](https://github.com/WebReflection/ucdn#readme) basic example 2 | 3 | **[Live demo](https://webreflection.github.io/ucdn-test/public/)** 4 | 5 | ### How to test this project 6 | 7 | ```sh 8 | git clone https://github.com/WebReflection/ucdn-test.git 9 | cd ucdn-test 10 | npm i 11 | ``` 12 | 13 | ### How to build a `./public` folder with optimized assets 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | 19 | ## How does this work? 20 | 21 | Source code is in the `./src` folder. Once _ucdn_ starts, it creates a `./cdn` folder with all assets pre-optimized and pre-compressed. 22 | 23 | Whenever a file changes, and the browser requests it, it will be re-generated with a cache lasting 1 second. 24 | 25 | The cache can be increased or reduced via the `--cache-timeout XXXX` argument, where `XXXX` are milliseconds. 26 | 27 | To discover all flags available in both _ucdn_ and _ucompress_, feel free to run `npm run help:cdn` or `npm run help:compress`. 28 | 29 | 30 | ## Where are dependencies? 31 | 32 | While backend/processing dependencies should be defined in this project root, all front-end related dependencies should be defined in the `./src/package.json` file. This is necessary in order to pre-resolve paths within the root of the front-end folder, but don't worry, only files related to the project will be optimized, once published, and _JS_ files will automatically resolve to those dependencies as relative path, i.e. `../node_modules/uhtml/esm/index.js`. 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "ucdn-test", 4 | "author": "Andrea Giammarchi", 5 | "license": "ISC", 6 | "devDependencies": { 7 | "ucdn": "latest", 8 | "ucompress": "latest" 9 | }, 10 | "scripts": { 11 | "help:cdn": "ucdn --help", 12 | "help:compress": "ucompress --help", 13 | "build": "ucompress --source ./src --dest ./public && rm -rf public/package-lock.json", 14 | "test": "ucdn --port 8080 --source ./src --dest ./cdn --cache-timeout 1000 --with-source-map --verbose", 15 | "test:forks": "ucdn --forks 128 --port 8080 --source ./src --dest ./cdn --cache-timeout 1000 --with-source-map --verbose", 16 | "test:perf": "ucdn --forks 128 --port 8080 --source ./src --dest ./cdn", 17 | "postinstall": "cd src && npm i && cd .. && npm test" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /public/css/index.css: -------------------------------------------------------------------------------- 1 | *,::after,::before{box-sizing:border-box}body{font-family:sans-serif;display:flex;flex-direction:column;height:calc(100vh - 64px)}footer{position:fixed;bottom:0;width:100%;text-align:center;padding:32px;opacity:.7} -------------------------------------------------------------------------------- /public/css/my-counter.css: -------------------------------------------------------------------------------- 1 | my-counter{margin:auto;box-sizing:border-box}my-counter>*{font-size:200%}my-counter span{width:4rem;display:inline-block;text-align:center}my-counter button{width:64px;height:64px;border:0;border-radius:10px;background-color:#2e8b57;color:#fff} -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/ucdn-test/edc6a33c052c8e8394aef433aeac7f47e8dbf8ca/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MyCounter Custom Element via Micro CDN 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /public/js/index.js: -------------------------------------------------------------------------------- 1 | import{render as e,html as o}from"../u_modules/uhtml/esm/index.js";import"./my-counter.js";addEventListener("DOMContentLoaded",(()=>{e(document.body,o` 2 | 3 | 4 | `),fetch("package.json").then((e=>e.json())).then((({description:t,version:n})=>{e(document.querySelector("footer"),o` 5 | ${t} v${n} 6 | `)}))}),{once:!0}); -------------------------------------------------------------------------------- /public/js/my-counter.js: -------------------------------------------------------------------------------- 1 | import{define as t}from"../u_modules/uce/esm/index.js";t("my-counter",{init(){this.count=0,this.dec=()=>{this.count--,this.render()},this.inc=()=>{this.count++,this.render()},this.render()},render(){this.html` 2 | 3 | ${this.count} 4 | 5 | `}}); -------------------------------------------------------------------------------- /public/node_modules/@ungap/create-content/esm/index.js: -------------------------------------------------------------------------------- 1 | /*! (c) Andrea Giammarchi - ISC */ 2 | var t=function(t){var e="content"in r("template")?function(t){var e=r("template");return e.innerHTML=t,e.content}:function(t){var e=r("fragment"),o=r("template"),a=null;if(/^[^\S]*?<(col(?:group)?|t(?:head|body|foot|r|d|h))/i.test(t)){var l=RegExp.$1;o.innerHTML=""+t+"
",a=o.querySelectorAll(l)}else o.innerHTML=t,a=o.childNodes;return n(e,a),e};return function(t,n){return("svg"===n?o:e)(t)};function n(t,e){for(var n=e.length;n--;)t.appendChild(e[0])}function r(e){return"fragment"===e?t.createDocumentFragment():t.createElementNS("http://www.w3.org/1999/xhtml",e)}function o(t){var e=r("fragment"),o=r("div");return o.innerHTML=''+t+"",n(e,o.firstChild.childNodes),e}}(document);export default t; -------------------------------------------------------------------------------- /public/node_modules/uarray/esm/index.js: -------------------------------------------------------------------------------- 1 | const{isArray:r}=Array,{indexOf:e,slice:i}=[];export{r as isArray,e as indexOf,i as slice}; -------------------------------------------------------------------------------- /public/node_modules/uce/esm/index.js: -------------------------------------------------------------------------------- 1 | import{render as e,html as t,svg as n}from"../../uhtml/esm/index.js";const{define:s}=customElements,{create:o,defineProperties:a,getOwnPropertyDescriptor:l,keys:c}=Object,i=new WeakMap;export{e as render,t as html,n as svg};export const define=(e,t)=>{const{attachShadow:n,attributeChanged:p,connected:d,disconnected:h,handleEvent:u,init:b,observedAttributes:m}=t,v={},f={},y=[],w=o(null);for(let e=c(t),n=0,{length:s}=e;n"element"===e?HTMLElement:document.createElement(e).constructor)(k)){}a(C,v),a(C.prototype,f);const g=[e,C];function x(e){if(!i.has(e)){i.set(e,0),a(e,{html:{value:r.bind(n?e.attachShadow(n):e)}});for(let t=0;t{const n=t.length;let r=l.length,s=n,o=0,g=0,h=null;for(;of-g){const n=i(l[o],0);for(;ge=>{for(const r in e)t.setAttribute("role"===r?r:"aria-"+r,e[r])};export const attribute=(t,e)=>{let r,o=!0;const n=document.createAttributeNS(null,e);return e=>{r!==e&&(r=e,null==r?o||(t.removeAttributeNodeNS(n),o=!0):(n.value=e,o&&(t.setAttributeNodeNS(n),o=!1)))}};export const data=({dataset:t})=>e=>{for(const r in e)t[r]=e[r]};export const event=(e,r)=>{let o,n=r.slice(2);return!(r in e)&&r.toLowerCase()in e&&(n=n.toLowerCase()),r=>{const s=t(r)?r:[r,!1];o!==s[0]&&(o&&e.removeEventListener(n,o,s[1]),(o=s[0])&&e.addEventListener(n,o,s[1]))}};export const ref=t=>e=>{"function"==typeof e?e(t):e.current=t};export const setter=(t,e)=>r=>{t[e]=r};export const text=t=>{let e;return r=>{e!=r&&(e=r,t.textContent=null==r?"":r)}}; -------------------------------------------------------------------------------- /public/node_modules/uhtml/esm/handlers.js: -------------------------------------------------------------------------------- 1 | import{isArray as e,slice as t}from"../../uarray/esm/index.js";import r from"../../udomdiff/esm/index.js";import{aria as o,attribute as n,data as a,event as i,ref as c,setter as s,text as d}from"../../uhandlers/esm/index.js";import{diffable as f}from"../../uwire/esm/index.js";import{reducePath as m}from"./node.js";const l=(e,t,o)=>r(e.parentNode,t,o,f,e);export function handlers(r){const{type:f,path:p}=r,u=p.reduceRight(m,this);return"node"===f?(r=>{let o,n,a=[];const i=c=>{switch(typeof c){case"string":case"number":case"boolean":o!==c&&(o=c,n?n.textContent=c:n=document.createTextNode(c),a=l(r,a,[n]));break;case"object":case"undefined":if(null==c){o!=c&&(o=c,a=l(r,a,[]));break}if(e(c)){o=c,0===c.length?a=l(r,a,[]):"object"==typeof c[0]?a=l(r,a,c):i(String(c));break}"ELEMENT_NODE"in c&&o!==c&&(o=c,a=l(r,a,11===c.nodeType?t.call(c.childNodes):[c]))}};return i})(u):"attr"===f?((e,t)=>"ref"===t?c(e):"aria"===t?o(e):"data"===t?a(e):"."===t.slice(0,1)?s(e,t.slice(1)):"on"===t.slice(0,2)?i(e,t):n(e,t))(u,r.name):d(u)} -------------------------------------------------------------------------------- /public/node_modules/uhtml/esm/index.js: -------------------------------------------------------------------------------- 1 | import e from"../../umap/esm/index.js";import{Hole as t,createCache as n,unroll as r}from"./rabbit.js";const{create:o,defineProperties:a}=Object,p=e(new WeakMap),s=p=>{const s=e(new WeakMap);return a((e,...n)=>new t(p,e,n),{for:{value(e,t){const a=s.get(e)||s.set(e,o(null));return a[t]||(a[t]=(e=>(t,...n)=>r(e,{type:p,template:t,values:n}))(n()))}},node:{value:(e,...t)=>r(n(),{type:p,template:e,values:t}).valueOf()}})};export const html=s("html");export const svg=s("svg");export const render=(e,o)=>{const a="function"==typeof o?o():o,s=p.get(e)||p.set(e,n()),l=a instanceof t?r(s,a):a;return l!==s.wire&&(s.wire=l,e.textContent="",e.appendChild(l.valueOf())),e}; -------------------------------------------------------------------------------- /public/node_modules/uhtml/esm/node.js: -------------------------------------------------------------------------------- 1 | import e from"../../@ungap/create-content/esm/index.js";import{indexOf as t}from"../../uarray/esm/index.js";export const reducePath=({childNodes:e},t)=>e[t];export const createPath=e=>{const o=[];let{parentNode:r}=e;for(;r;)o.push(t.call(r.childNodes,e)),r=(e=r).parentNode;return o};const{createTreeWalker:o,importNode:r}=document;export{o as createTreeWalker,r as importNode};const c=1!=r.length;export const createFragment=c?(t,o)=>r.call(document,e(t,o),!0):e;export const createWalker=c?e=>o.call(document,e,129,null,!1):e=>o.call(document,e,129); -------------------------------------------------------------------------------- /public/node_modules/uhtml/esm/rabbit.js: -------------------------------------------------------------------------------- 1 | import t from"../../umap/esm/index.js";import e from"../../uparser/esm/index.js";import{isArray as n}from"../../uarray/esm/index.js";import{persistent as r}from"../../uwire/esm/index.js";import{handlers as o}from"./handlers.js";import{createFragment as s,createPath as l,createWalker as a,importNode as p}from"./node.js";const u=t(new WeakMap);export const createCache=()=>({stack:[],entry:null,wire:null});const i=(t,n)=>{const{content:r,nodes:i}=u.get(n)||u.set(n,((t,n)=>{const r=e(n,"isµ","svg"===t),o=s(r,t),p=a(o),u=[],i=n.length-1;let c=0,m="isµ"+c;for(;c{const{length:s}=o;c(t,o,s);let{entry:l}=t;l&&l.template===n&&l.type===e||(t.entry=l=((t,e)=>{const{content:n,updates:r}=i(t,e);return{type:t,template:e,content:n,updates:r,wire:null}})(e,n));const{content:a,updates:p,wire:u}=l;for(let t=0;t{for(let o=0;o({get:t=>e.get(t),set:(t,g)=>(e.set(t,g),g)}); -------------------------------------------------------------------------------- /public/node_modules/uparser/esm/index.js: -------------------------------------------------------------------------------- 1 | const e=/([^\s\\>"'=]+)\s*=\s*(['"]?)$/,t=/^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i,s=/<[a-z][^>]+$/i,$=/>[^<>]*$/,r=/<([a-z]+[a-z0-9:._-]*)([^>]*?)(\/>)/gi,a=/\s+$/,c=(e,t)=>0t.test(s)?e:`<${s}${$.replace(a,"")}>`;export default(t,s,$)=>{const a=[],{length:i}=t;for(let $=1;$`${s}${$-1}=${r||'"'}${t}${r?"":'"'}`):`${r}\x3c!--${s}${$-1}--\x3e`)}a.push(t[i-1]);const o=a.join("").trim();return $?o:o.replace(r,n)}; -------------------------------------------------------------------------------- /public/node_modules/uwire/esm/index.js: -------------------------------------------------------------------------------- 1 | import{slice as t}from"../../uarray/esm/index.js";export const diffable=(t,e)=>111===t.nodeType?1/e<0?e?(({firstChild:t,lastChild:e})=>{const r=document.createRange();return r.setStartAfter(t),r.setEndAfter(e),r.deleteContents(),t})(t):t.lastChild:e?t.valueOf():t.firstChild:t;export const persistent=e=>{const{childNodes:r}=e,{length:l}=r;if(l<2)return r[0];const n=t.call(r,0);return{ELEMENT_NODE:1,nodeType:111,firstChild:n[0],lastChild:n[l-1],valueOf(){if(r.length!==l){let t=0;for(;t"+n+"",u=l.querySelectorAll(a)}else l.innerHTML=n,u=l.childNodes;return o(r,u),r};return function(n,t){return("svg"===t?l:r)(n)};function o(n,t){for(var e=t.length;e--;)n.appendChild(t[0])}function i(e){return e===t?n.createDocumentFragment():n.createElementNS("http://www.w3.org/1999/xhtml",e)}function l(n){var e=i(t),r=i("div");return r.innerHTML=''+n+"",o(e,r.firstChild.childNodes),e}}(document);export default n; -------------------------------------------------------------------------------- /public/u_modules/uarray/esm/index.js: -------------------------------------------------------------------------------- 1 | const{isArray:r}=Array,{indexOf:e,slice:i}=[];export{r as isArray,e as indexOf,i as slice}; -------------------------------------------------------------------------------- /public/u_modules/uce/esm/index.js: -------------------------------------------------------------------------------- 1 | import{render as e,html as t,svg as n}from"../../uhtml/esm/index.js";import s from"../../umap/esm/index.js";const c=customElements,{define:a}=c,{create:o,defineProperties:l,getOwnPropertyDescriptor:i,keys:r}=Object,p=s(new Map([["element",{c:HTMLElement,e:"element"}]])),u=e=>p.get(e)||p.set(e,{c:document.createElement(e).constructor,e:e});export{e as render,t as html,n as svg};export const define=(e,t)=>{const{attachShadow:n,attributeChanged:s,connected:h,disconnected:m,handleEvent:b,init:f,observedAttributes:g,props:v}=t,y=new WeakMap,w={},k={},x=[],C=o(null);for(let e=r(t),n=0,{length:s}=e;n{const n=t.length;let r=l.length,s=n,o=0,g=0,h=null;for(;of-g){const n=i(l[o],0);for(;ge=>{for(const r in e)t.setAttribute("role"===r?r:"aria-"+r,e[r])};export const attribute=(t,e)=>{let r,o=!0;const n=document.createAttributeNS(null,e);return e=>{r!==e&&(r=e,null==r?o||(t.removeAttributeNode(n),o=!0):(n.value=e,o&&(t.setAttributeNodeNS(n),o=!1)))}};export const data=({dataset:t})=>e=>{for(const r in e)t[r]=e[r]};export const event=(e,r)=>{let o,n=r.slice(2);return!(r in e)&&r.toLowerCase()in e&&(n=n.toLowerCase()),r=>{const s=t(r)?r:[r,!1];o!==s[0]&&(o&&e.removeEventListener(n,o,s[1]),(o=s[0])&&e.addEventListener(n,o,s[1]))}};export const ref=t=>e=>{"function"==typeof e?e(t):e.current=t};export const setter=(t,e)=>r=>{t[e]=r};export const text=t=>{let e;return r=>{e!=r&&(e=r,t.textContent=null==r?"":r)}}; -------------------------------------------------------------------------------- /public/u_modules/uhtml/esm/handlers.js: -------------------------------------------------------------------------------- 1 | import{isArray as e,slice as t}from"../../uarray/esm/index.js";import r from"../../udomdiff/esm/index.js";import{aria as o,attribute as n,data as a,event as i,ref as c,setter as s,text as d}from"../../uhandlers/esm/index.js";import{diffable as f}from"../../uwire/esm/index.js";import{reducePath as m}from"./node.js";const l=(e,t,o)=>r(e.parentNode,t,o,f,e);export function handlers(r){const{type:f,path:p}=r,u=p.reduceRight(m,this);return"node"===f?(r=>{let o,n,a=[];const i=c=>{switch(typeof c){case"string":case"number":case"boolean":o!==c&&(o=c,n?n.textContent=c:n=document.createTextNode(c),a=l(r,a,[n]));break;case"object":case"undefined":if(null==c){o!=c&&(o=c,a=l(r,a,[]));break}if(e(c)){o=c,0===c.length?a=l(r,a,[]):"object"==typeof c[0]?a=l(r,a,c):i(String(c));break}"ELEMENT_NODE"in c&&o!==c&&(o=c,a=l(r,a,11===c.nodeType?t.call(c.childNodes):[c]))}};return i})(u):"attr"===f?((e,t)=>"ref"===t?c(e):"aria"===t?o(e):"data"===t?a(e):"."===t.slice(0,1)?s(e,t.slice(1)):"on"===t.slice(0,2)?i(e,t):n(e,t))(u,r.name):d(u)} -------------------------------------------------------------------------------- /public/u_modules/uhtml/esm/index.js: -------------------------------------------------------------------------------- 1 | import e from"../../umap/esm/index.js";import{Hole as t,createCache as n,unroll as r}from"./rabbit.js";const{create:o,defineProperties:a}=Object,p=e(new WeakMap),s=p=>{const s=e(new WeakMap);return a(((e,...n)=>new t(p,e,n)),{for:{value(e,t){const a=s.get(e)||s.set(e,o(null));return a[t]||(a[t]=(e=>(t,...n)=>r(e,{type:p,template:t,values:n}))(n()))}},node:{value:(e,...t)=>r(n(),{type:p,template:e,values:t}).valueOf()}})};export const html=s("html");export const svg=s("svg");export const render=(e,o)=>{const a="function"==typeof o?o():o,s=p.get(e)||p.set(e,n()),l=a instanceof t?r(s,a):a;return l!==s.wire&&(s.wire=l,e.textContent="",e.appendChild(l.valueOf())),e}; -------------------------------------------------------------------------------- /public/u_modules/uhtml/esm/node.js: -------------------------------------------------------------------------------- 1 | import e from"../../@ungap/create-content/esm/index.js";import{indexOf as t}from"../../uarray/esm/index.js";export const reducePath=({childNodes:e},t)=>e[t];export const createPath=e=>{const o=[];let{parentNode:r}=e;for(;r;)o.push(t.call(r.childNodes,e)),r=(e=r).parentNode;return o};const{createTreeWalker:o,importNode:r}=document;export{o as createTreeWalker,r as importNode};const c=1!=r.length;export const createFragment=c?(t,o)=>r.call(document,e(t,o),!0):e;export const createWalker=c?e=>o.call(document,e,129,null,!1):e=>o.call(document,e,129); -------------------------------------------------------------------------------- /public/u_modules/uhtml/esm/rabbit.js: -------------------------------------------------------------------------------- 1 | import t from"../../umap/esm/index.js";import e from"../../uparser/esm/index.js";import{isArray as n}from"../../uarray/esm/index.js";import{persistent as r}from"../../uwire/esm/index.js";import{handlers as o}from"./handlers.js";import{createFragment as s,createPath as l,createWalker as a,importNode as p}from"./node.js";const u=t(new WeakMap);export const createCache=()=>({stack:[],entry:null,wire:null});const i=(t,n)=>{const{content:r,nodes:i}=u.get(n)||u.set(n,((t,n)=>{const r=e(n,"isµ","svg"===t),o=s(r,t),p=a(o),u=[],i=n.length-1;let c=0,m="isµ"+c;for(;c{const{length:s}=o;c(t,o,s);let{entry:l}=t;l&&l.template===n&&l.type===e||(t.entry=l=((t,e)=>{const{content:n,updates:r}=i(t,e);return{type:t,template:e,content:n,updates:r,wire:null}})(e,n));const{content:a,updates:p,wire:u}=l;for(let t=0;t{for(let o=0;o({get:t=>e.get(t),set:(t,g)=>(e.set(t,g),g)}); -------------------------------------------------------------------------------- /public/u_modules/uparser/esm/index.js: -------------------------------------------------------------------------------- 1 | const e=/([^\s\\>"'=]+)\s*=\s*(['"]?)$/,t=/^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i,s=/<[a-z][^>]+$/i,$=/>[^<>]*$/,r=/<([a-z]+[a-z0-9:._-]*)([^>]*?)(\/>)/gi,a=/\s+$/,c=(e,t)=>0t.test(s)?e:`<${s}${$.replace(a,"")}>`;export default(t,s,$)=>{const a=[],{length:i}=t;for(let $=1;$`${s}${$-1}=${r||'"'}${t}${r?"":'"'}`)):`${r}\x3c!--${s}${$-1}--\x3e`)}a.push(t[i-1]);const o=a.join("").trim();return $?o:o.replace(r,n)}; -------------------------------------------------------------------------------- /public/u_modules/uwire/esm/index.js: -------------------------------------------------------------------------------- 1 | import{slice as t}from"../../uarray/esm/index.js";export const diffable=(t,e)=>111===t.nodeType?1/e<0?e?(({firstChild:t,lastChild:e})=>{const r=document.createRange();return r.setStartAfter(t),r.setEndAfter(e),r.deleteContents(),t})(t):t.lastChild:e?t.valueOf():t.firstChild:t;export const persistent=e=>{const{childNodes:r}=e,{length:l}=r;if(l<2)return r[0];const n=t.call(r,0);return{ELEMENT_NODE:1,nodeType:111,firstChild:n[0],lastChild:n[l-1],valueOf(){if(r.length!==l){let t=0;for(;t * { 6 | font-size: 200%; 7 | } 8 | my-counter span { 9 | width: 4rem; 10 | display: inline-block; 11 | text-align: center; 12 | } 13 | my-counter button { 14 | width: 64px; 15 | height: 64px; 16 | border: none; 17 | border-radius: 10px; 18 | background-color: seagreen; 19 | color: white; 20 | } 21 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebReflection/ucdn-test/edc6a33c052c8e8394aef433aeac7f47e8dbf8ca/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MyCounter Custom Element via Micro CDN 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/js/index.js: -------------------------------------------------------------------------------- 1 | import { render, html } from 'uhtml'; 2 | 3 | import './my-counter.js'; 4 | 5 | addEventListener( 6 | 'DOMContentLoaded', 7 | () => { 8 | 9 | // populate the body 10 | render(document.body, html` 11 | 12 |
13 | `); 14 | 15 | // fetch project details and populate the footer 16 | fetch('package.json') 17 | .then(_ => _.json()) 18 | .then(({description, version}) => { 19 | render(document.querySelector('footer'), html` 20 | ${description} v${version} 21 | `); 22 | }); 23 | }, 24 | {once: true} 25 | ); 26 | -------------------------------------------------------------------------------- /src/js/my-counter.js: -------------------------------------------------------------------------------- 1 | import { define } from 'uce'; 2 | 3 | define("my-counter", { 4 | init() { 5 | this.count = 0; 6 | this.dec = () => { 7 | this.count--; 8 | this.render(); 9 | }; 10 | this.inc = () => { 11 | this.count++; 12 | this.render(); 13 | }; 14 | this.render(); 15 | }, 16 | render() { 17 | this.html` 18 | 19 | ${this.count} 20 | 21 | `; 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "description": "My Counter", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "uce": "latest", 7 | "uhtml": "latest" 8 | } 9 | } 10 | --------------------------------------------------------------------------------