@k3000/ce 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,12 +16,20 @@
16
16
 
17
17
  ## 🚀 快速上手
18
18
 
19
- ### 1. 项目引入
19
+ ### 1. 全局安装
20
+ ```
21
+ .\> npm i @k3000/ce -g #全局安装使用ce命令
22
+ .\> cd demo #进入需要的目录
23
+ .\demo> ce copy #复制核心框架文件可以带参数,ce copy dist.js,将ce.mjs复制到当前目录,并改名为:dist.js
24
+ .\demo> ce demo #复制使用示例一共三个目录和一个数据文件:/app、/comm、/console、/info.json
25
+ ```
26
+
27
+ ### 2. 项目引入
20
28
  在 `index.html` 中通过 Script 标签引入核心框架:
21
29
 
22
30
  ```html
23
31
  <script type="module">
24
- import { config } from '../index.mjs'
32
+ import { config } from '../ce.mjs'
25
33
 
26
34
  config({
27
35
  dir: './console/components',
@@ -30,15 +38,13 @@
30
38
  </script>
31
39
  ```
32
40
 
33
- ### 2. 定义组件
41
+ ### 3. 定义组件
34
42
  每个组件为一个独立的 `.mjs` 文件。
35
43
 
36
44
  **示例: `my-counter.mjs`**
37
45
 
38
- **更多示例参照: `/app`,`/console`**
39
-
40
46
  ```javascript
41
- import { useWatch } from "../../index.mjs";
47
+ import { useWatch } from "../../ce.mjs";
42
48
 
43
49
  // 1. 定义 HTML 结构 (支持插值 {{ }})
44
50
  export const innerHTML = `
@@ -1,4 +1,4 @@
1
- import {useAttr, useRef} from "../../index.mjs";
1
+ import {useAttr, useRef} from "../../ce.mjs";
2
2
 
3
3
  export const shadowRoot = `
4
4
  <label>
@@ -1,4 +1,4 @@
1
- import {useEvent} from "../../index.mjs";
1
+ import {useEvent} from "../../ce.mjs";
2
2
 
3
3
  export const shadowRoot = `
4
4
  <style>
@@ -1,4 +1,4 @@
1
- import {useEvent} from "../../index.mjs";
1
+ import {useEvent} from "../../ce.mjs";
2
2
 
3
3
  export const shadowRoot = `
4
4
  <style>
@@ -1,4 +1,4 @@
1
- import {useEvent} from "../../index.mjs";
1
+ import {useEvent} from "../../ce.mjs";
2
2
 
3
3
  export const shadowRoot = `
4
4
  <style>
package/app/index.html CHANGED
@@ -6,7 +6,7 @@
6
6
  content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover"/>
7
7
  <title>demo</title>
8
8
  <script type="module">
9
- import { config } from '../index.mjs'
9
+ import { config } from '../ce.mjs'
10
10
 
11
11
  config({
12
12
  dir: './app/comp',
package/bin.mjs ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+ import {cpSync, existsSync, mkdirSync} from "node:fs";
3
+ import {resolve, dirname} from "node:path";
4
+
5
+ const [, , key, value] = process.argv
6
+
7
+ const path = import.meta.url.substring(process.platform === 'win32' ? 8 : 7)
8
+
9
+ const getDir = path => decodeURI(dirname(path));
10
+ /**
11
+ * 将本目录下的文件或者文件夹复制到项目运行目录
12
+ * @param {string} source 自动加上'/'
13
+ * @param {string} destination
14
+ * @param {boolean} force
15
+ * @example
16
+ * myCopyFn('source', 'destination')
17
+ */
18
+ const myCopyFn = (source, destination = source, force = false) => {
19
+
20
+ return cpSync( `${getDir(path)}/${source}`, destination, {recursive: true, force})
21
+ }
22
+
23
+ // console.log(`key: ${key}, value: ${value}, path: ${path}, getDir: ${getDir(path)}`);
24
+
25
+ switch (key) {
26
+
27
+ case 'copy':
28
+
29
+ let target = value || 'ce.mjs'
30
+
31
+ if (!target.endsWith('.mjs') && !target.endsWith('.js')) {
32
+
33
+ target += '.js'
34
+ }
35
+
36
+ myCopyFn('index.mjs', target, true)
37
+
38
+ break
39
+
40
+ case 'demo':
41
+
42
+ myCopyFn('app', 'app', !!value)
43
+ myCopyFn('comm', 'comm', !!value)
44
+ myCopyFn('console', 'console', !!value)
45
+ myCopyFn('info.json', 'info.json', !!value)
46
+
47
+ break
48
+ }
package/ce.mjs ADDED
@@ -0,0 +1 @@
1
+ let dir="./comp",ext="mjs",getVariables=e=>{const t=e.match(/\{\{.+?}}/g);if(!t)return new Set;const o=new Set,n=new Set(["true","false","null","undefined","this","new","typeof","in","instanceof"]);return t.forEach((e=>{const t=e.slice(2,-2).match(/\b[a-zA-Z_$][\w$]*(?:\s*\.\s*[a-zA-Z_$][\w$]*)*(?!\s*\()/g);t&&t.forEach((e=>{n.has(e)||o.add(e)}))})),o},createTmpNode=(e="")=>document.createTextNode(""),literalsCode=e=>`with (scope) {\n\treturn \`${e.replace(/{{(.*?)}}/g,((e,t)=>`\${${t}}`))}\` \n}`,functionCode=e=>`with (scope) {\n\treturn ${e} \n}`,handleArray=(e,t)=>{const o=e.ownerElement;if(e.nodeMap||(e.nodeMap=[],e.mark=createTmpNode("数组结束标记"),o.parentNode.replaceChild(e.mark,o),e.ownerElement=o.cloneNode(!0)),!Array.isArray(t))return e;const n=e.mark.parentNode;let r=0;for(;r<t.length;r++)if(void 0!==e.nodeMap[r]){if(e.nodeMap[r][0]!==t[r]){const s=o.cloneNode(!0);try{t[r]._=e.scope}catch(e){}bindNode(t[r],s,!0),n.replaceChild(s,e.nodeMap[r][1]),e.nodeMap[r]=[t[r],s]}}else{const s=o.cloneNode(!0);try{t[r]._=e.scope}catch(e){}bindNode(t[r],s,!0),n.insertBefore(s,e.mark),e.nodeMap[r]=[t[r],s]}const s=r;for(;r<e.nodeMap.length;r++)n.removeChild(e.nodeMap[r][1]);return e.nodeMap.splice(s,e.nodeMap.length-s),e};export const config=e=>{e.dir&&(dir=e.dir),e.ext&&(ext=e.ext),"function"==typeof e.getVariables&&(getVariables=e.getVariables),"function"==typeof e.createTmpNode&&(createTmpNode=e.createTmpNode),"function"==typeof e.literalsCode&&(literalsCode=e.literalsCode),"function"==typeof e.functionCode&&(functionCode=e.functionCode),"function"==typeof e.handleArray&&(handleArray=e.handleArray)};const getCEName=e=>e.tagName.includes("-")?e.tagName.toLowerCase():e.hasAttribute("is")?e.getAttribute("is"):void 0;export const throttle=(e,t=41)=>{let o;return(...n)=>{clearTimeout(o),o=setTimeout((()=>e(...n)),t)}};const objectPool=new WeakMap,importPool=new WeakSet,addListener=(e,t,o)=>{getVariables(t).forEach((t=>{let n="",r=e,s=0,a=t.split(".");for([s,n]of a.entries()){if(s===a.length-1)break;if(null===r||"object"!=typeof r||!Reflect.has(r,n))return;if(Array.isArray(r[n])&&s===a.length-2)break;r=r[n]}if(null!==r&&"object"==typeof r&&(!Object.getOwnPropertyDescriptor(r,n)||Object.getOwnPropertyDescriptor(r,n).configurable))if(objectPool.has(r)){const e=objectPool.get(r);if(e.has(n))e.get(n).add(o);else{const t=new Set([o]);e.set(n,t);let s=r[n];Object.defineProperty(r,n,{get:()=>s,set:e=>{s!==e&&(s=e,t.forEach((e=>e())))}})}}else{const e=new Set([o]);objectPool.set(r,new Map([[n,e]]));let t=r[n];Object.defineProperty(r,n,{get:()=>t,set:o=>{t!==o&&(t=o,e.forEach((e=>e())))}})}}))},ceMap=Object.create(null),disposeCE=(e,t)=>{if(e.querySelectorAll("*:not(:defined)").forEach((e=>importCE(e))),ceMap[t].shadowRoot&&(e.attachShadow({mode:"open"}),e.shadowRoot.appendChild(ceMap[t].shadowRoot.create(e))),ceMap[t].innerHTML||ceMap[t].outerHTML){const o=(ceMap[t].innerHTML||ceMap[t].outerHTML).create(e);if(!ceMap[t].shadowRoot){const t=Array.from(o.querySelectorAll("slot")),n=t.reduce(((e,t)=>(e[t.getAttribute("name")||""]=t,e)),{}),r=Array.from(e.childNodes);for(const e of r){const t="function"==typeof e.getAttribute&&e.getAttribute("slot")||"";n[t]&&n[t].parentNode.insertBefore(e,n[t])}for(const e of t)e.parentNode.removeChild(e)}if(ceMap[t].outerHTML){for(;o.firstChild;)e.parentElement.insertBefore(o.firstChild,e);e.parentElement.removeChild(e)}else e.appendChild(o)}"function"==typeof e.ready&&e.ready()};let tmp=null;const importCE=(e,t=void 0)=>{if(t=t??getCEName(e),importPool.has(e))return;if(importPool.add(e),void 0!==customElements.get(t))return void disposeCE(e,t);const o=e.nodeName.includes("-");let n=dir;if(e.attributes.dir&&e.attributes.dir.nodeValue){const t=e.attributes.dir.nodeValue;e.removeAttribute("dir"),n=t.startsWith("/")||t.startsWith("./")?t:`${n}/${t}`}import(`${n}/${t}.${ext}`).then((n=>{void 0===customElements.get(t)&&(ceMap[t]=Object.create(null),"string"==typeof n.innerHTML&&(ceMap[t].innerHTML=bind(n.innerHTML)),"string"==typeof n.outerHTML&&(ceMap[t].outerHTML=bind(n.outerHTML)),"string"==typeof n.shadowRoot&&(ceMap[t].shadowRoot=bind(n.shadowRoot)),o?customElements.define(t,n.default):customElements.define(t,n.default,{extends:e.nodeName.toLowerCase()})),disposeCE(e,t)})).catch((e=>{console.error(e)}))},disposeNode=(e,t)=>{const o=t.nodeValue;if(null===o.match(/{{(.*?)}}/))return;const n=new Function("scope",literalsCode(o));addListener(e,o,throttle((()=>t.nodeValue=n.call(t,e)))),t.nodeValue=n.call(t,e)},disposeAttrValue=(e,t,o,n)=>{if(!n.startsWith("{{")||!n.endsWith("}}")||n.slice(2).includes("{{")){const r=new Function("scope",literalsCode(n));return()=>o.nodeValue=r.call(t,e)}const r=new Function("scope",functionCode(n.slice(2,-2)));return()=>{const n=r.call(t,e);switch(n){case!0:o.nodeValue="",t.attributes.setNamedItem(o);break;case!1:t.removeAttribute(o.nodeName);break;default:o.nodeValue=n,t.attributes.setNamedItem(o)}}},disposeSpecialAttr=(e,t,o,n)=>{const r=t.ownerElement;let s=t.nodeName;if(s.startsWith("on")){if(r.removeAttribute(s),!o.includes("(")){const t=o.split(".");let n="",a=e,i=0;for([i,n]of t.entries()){if(i===t.length-1)break;if(null===a||"object"!=typeof a||!Reflect.has(a,n)){a={};break}a=a[n]}if("function"==typeof a[n])return r[s]=e=>a[n](e),!0}const t=new Function("scope","event",functionCode(o));return r[s]=o=>t.call(r,e,o),!0}if("connect"===s){r.removeAttribute(s);const n=new Function("scope",functionCode(o)),a=createTmpNode("节点断开重连的标记"),i=()=>{n(e)?a.parentNode?.replaceChild(r,a):r.parentNode?.replaceChild(a,r)};return addListener(e,t.nodeValue,throttle((()=>i()))),i(),!0}if("each"===s){r.removeAttribute(s);let n={ownerElement:r,scope:e};if(Reflect.has(e,o)){const r=()=>n=handleArray(n,e[o]);return addListener(e,t.nodeValue,throttle((()=>r()))),r(),!0}const a=new Function("scope",functionCode(o));return handleArray(n,a(e)),!0}if(n){r.removeAttribute(s);const n=new Function("scope",functionCode(o));s.includes("-")&&(s=s.split("-").map(((e,t)=>e&&t?e[0].toUpperCase()+e.slice(1):e)).join(""));const a=()=>{const t=n(e);r[s]="function"==typeof t?t.bind(e):t};return addListener(e,t.nodeValue,throttle((()=>a()))),a(),!0}return!1},disposeAttr=(e,t,o)=>{const n=t.nodeValue;if(null===n.match(/{{(.*?)}}/))return;if(n.startsWith("{{")&&n.endsWith("}}")&&disposeSpecialAttr(e,t,n.slice(2,-2),o))return;const r=disposeAttrValue(e,t.ownerElement,t,n);addListener(e,n,throttle((()=>r()))),r()};export const bindNode=(e,t,o)=>{const n=o?[t]:Array.from(t.childNodes);for(const o of n){if(o.attributes)for(const n of Array.from(o.attributes))if(disposeAttr(e,n,getCEName(o)),"each"===n.nodeName&&n.nodeValue.startsWith("{{")&&n.nodeValue.endsWith("}}"))return t;if(o.childNodes&&bindNode(e,o),3===o.nodeType&&null!==o.nodeValue&&disposeNode(e,o),1===o.nodeType){const e=getCEName(o);e&&importCE(o,e)}}return t};export const bind=e=>{const t=document.createElement("template");return t.innerHTML=e,{create:e=>bindNode(e,document.importNode(t.content,!0))}};const style=document.createElement("style");style.innerHTML="\n*:not(:defined) {\n display: none\n}\n",document.head.appendChild(style),addEventListener("DOMContentLoaded",(()=>document.querySelectorAll("*:not(:defined)").forEach((e=>importCE(e)))));class EventBus{value=void 0;targets=new Map;add(e,t=Object.create(null)){this.targets.set(e,t),t.preValue&&void 0!==this.value&&e(...this.value)}remove(e){this.targets.delete(e)}dispatch(...e){return this.value=e,Promise.allSettled(this.targets.entries().map((([t,{once:o}])=>(o&&this.targets.delete(t),t(...e)))))}}const eventBusObj=Object.create(null),eventBus=Object.defineProperties(Object.create(null),{add:{value:(e,t,o)=>{Reflect.has(eventBusObj,e)||(eventBusObj[e]=new EventBus),eventBusObj[e].add(t,o)}},remove:{value:(e,t)=>{Reflect.has(eventBusObj,e)&&eventBusObj[e].remove(t)}},dispatch:{value:(e,...t)=>(Reflect.has(eventBusObj,e)||(eventBusObj[e]=new EventBus),eventBusObj[e].dispatch(...t))}});export const useEvent=()=>eventBus;export const useRef=e=>{const t=Object.create(null);for(const o of e.querySelectorAll("[ref]"))t[o.attributes.ref.nodeValue]=o;return t};export const useAttr=e=>{const t=Object.create(null);for(const o of e.attributes)t[o.nodeName]=o.nodeValue;return t};export const useWatch=e=>(t,o=!1)=>{for(const[n,r]of Object.entries(t)){if("function"!=typeof r)continue;let t=e[n];Object.defineProperty(e,n,{get:()=>t,set:e=>{if(!1!==r(e,t))return t=e}}),o&&r(t,t)}};
@@ -1,4 +1,4 @@
1
- import {bindNode, useEvent} from "../index.mjs";
1
+ import {bindNode, useEvent} from "../ce.mjs";
2
2
 
3
3
  export default class RouterView extends HTMLElement {
4
4
 
@@ -1,4 +1,4 @@
1
- import {useAttr, useRef} from "../../index.mjs";
1
+ import {useAttr, useRef} from "../../ce.mjs";
2
2
 
3
3
  export const innerHTML = `
4
4
  <button data-action="{{action}}" data-id="{{id}}" class="p-2 text-gray-400 {{typeClass}} rounded-lg transition-colors" title="{{title}}">
@@ -1,4 +1,4 @@
1
- import {useAttr} from "../../index.mjs";
1
+ import {useAttr} from "../../ce.mjs";
2
2
 
3
3
  export const innerHTML = `
4
4
  <div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
@@ -1,4 +1,4 @@
1
- import { useAttr, useWatch } from "../../index.mjs";
1
+ import { useAttr, useWatch } from "../../ce.mjs";
2
2
 
3
3
  export const innerHTML = `
4
4
  <div class="space-y-1.5">
@@ -1,4 +1,4 @@
1
- import { useAttr } from "../../index.mjs";
1
+ import { useAttr } from "../../ce.mjs";
2
2
 
3
3
  export const innerHTML = `
4
4
  <style>
@@ -1,4 +1,4 @@
1
- import {throttle, useWatch} from "../../index.mjs";
1
+ import {throttle, useWatch} from "../../ce.mjs";
2
2
 
3
3
  export const innerHTML = `
4
4
  <div class="px-6 py-4 border-t border-white/20 dark:border-white/5 bg-white/30 dark:bg-white/5 backdrop-blur-md flex items-center justify-between">
@@ -1,4 +1,4 @@
1
- import { useAttr } from "../../index.mjs";
1
+ import { useAttr } from "../../ce.mjs";
2
2
 
3
3
  export const outerHTML = `
4
4
  <div class="relative group">
@@ -1,4 +1,4 @@
1
- import { useEvent, bind } from "../../index.mjs";
1
+ import { useEvent, bind } from "../../ce.mjs";
2
2
 
3
3
  export default class extends HTMLElement {
4
4
 
@@ -30,7 +30,7 @@
30
30
  }
31
31
  </script>
32
32
  <script type="module">
33
- import { config } from '../index.mjs'
33
+ import { config } from '../ce.mjs'
34
34
 
35
35
  config({
36
36
  dir: './console/components',
package/index.mjs CHANGED
@@ -178,7 +178,7 @@ let handleArray = (data, array) => {
178
178
  * 调用该方法完成可配置参数合方法的初始化
179
179
  * @param options
180
180
  * @example
181
- * import { config } from '../index.mjs'
181
+ * import { config } from '../ce.mjs'
182
182
  * config({
183
183
  * dir: './app/comp',
184
184
  * getVariables: () => {...}
package/package.json CHANGED
@@ -1,6 +1,12 @@
1
1
  {
2
2
  "name": "@k3000/ce",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "",
5
- "main": "index.mjs"
5
+ "main": "index.mjs",
6
+ "scripts": {
7
+ "sync": "npm link"
8
+ },
9
+ "bin": {
10
+ "ce": "bin.mjs"
11
+ }
6
12
  }
@@ -1,26 +0,0 @@
1
- import {useAttr} from "../../index.mjs";
2
-
3
- export const innerHTML = `
4
- <div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
5
- <div>
6
- <h1 class="text-2xl font-bold text-gray-800 dark:text-white tracking-tight">{{title}}</h1>
7
- <p class="text-sm text-gray-500 dark:text-gray-400 mt-1">{{description}}</p>
8
- </div>
9
- <div class="flex items-center gap-3">
10
- <slot></slot>
11
- </div>
12
- </div>
13
- `
14
-
15
- export default class extends HTMLElement {
16
- title = ''
17
- description = ''
18
-
19
- constructor() {
20
- super()
21
- const attr = useAttr(this)
22
- this.title = attr.title
23
- this.description = attr.description
24
- // console.log([this])
25
- }
26
- }