init
This commit is contained in:
		
							
								
								
									
										2
									
								
								.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.npmignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					.npmrc
 | 
				
			||||||
 | 
					tests/
 | 
				
			||||||
							
								
								
									
										3
									
								
								.npmrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.npmrc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					//npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN}
 | 
				
			||||||
 | 
					//registry.npmjs.org/:_authToken=${NPM_TOKEN}
 | 
				
			||||||
 | 
					ignore-workspace-root-check=true
 | 
				
			||||||
							
								
								
									
										38
									
								
								css/reset.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								css/reset.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					/* Base Reset CSS */
 | 
				
			||||||
 | 
					* {
 | 
				
			||||||
 | 
					  margin: 0;
 | 
				
			||||||
 | 
					  padding: 0;
 | 
				
			||||||
 | 
					  box-sizing: border-box;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					html {
 | 
				
			||||||
 | 
					  height: 100%;
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
					  height: 100%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#root {
 | 
				
			||||||
 | 
					  height: 100%;
 | 
				
			||||||
 | 
					  overflow: auto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
					  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
 | 
				
			||||||
 | 
					  line-height: 1.5;
 | 
				
			||||||
 | 
					  -webkit-font-smoothing: antialiased;
 | 
				
			||||||
 | 
					  -moz-osx-font-smoothing: grayscale;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					img, picture, video, canvas, svg {
 | 
				
			||||||
 | 
					  display: block;
 | 
				
			||||||
 | 
					  max-width: 100%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					input, button, textarea, select {
 | 
				
			||||||
 | 
					  font: inherit;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					p, h1, h2, h3, h4, h5, h6 {
 | 
				
			||||||
 | 
					  overflow-wrap: break-word;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										142
									
								
								import-map.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								import-map.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,142 @@
 | 
				
			|||||||
 | 
					// 生成缓存键,基于当前模块的URL
 | 
				
			||||||
 | 
					const getCacheKey = () => {
 | 
				
			||||||
 | 
					  const url = new URL(import.meta.url);
 | 
				
			||||||
 | 
					  const basePath = url.pathname.replace('/import-map.js', '');
 | 
				
			||||||
 | 
					  return `importMap_${btoa(basePath).replace(/[+/=]/g, '_')}`;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					const getCurrentScriptData = () => {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    const script = document.getElementById('importmap');
 | 
				
			||||||
 | 
					    if (script) {
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        run: script.dataset.run !== 'false',
 | 
				
			||||||
 | 
					        // 可以获取其他data属性
 | 
				
			||||||
 | 
					        element: script,
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } catch (error) {
 | 
				
			||||||
 | 
					    console.warn('Error finding script with id "importmap":', error);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return { run: true, element: null };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					// 从localStorage获取缓存
 | 
				
			||||||
 | 
					const getCachedImportMap = () => {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    const cacheKey = getCacheKey();
 | 
				
			||||||
 | 
					    const cached = localStorage.getItem(cacheKey);
 | 
				
			||||||
 | 
					    if (cached) {
 | 
				
			||||||
 | 
					      const { data, timestamp } = JSON.parse(cached);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // 检查缓存是否过期(1天 = 24 * 60 * 60 * 1000 毫秒)
 | 
				
			||||||
 | 
					      const oneDay = 24 * 60 * 60 * 1000;
 | 
				
			||||||
 | 
					      const isExpired = Date.now() - timestamp > oneDay;
 | 
				
			||||||
 | 
					      if (isExpired) {
 | 
				
			||||||
 | 
					        localStorage.removeItem(cacheKey);
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return { data, timestamp };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } catch (error) {
 | 
				
			||||||
 | 
					    console.warn('Error reading cache:', error);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return null;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 保存到localStorage
 | 
				
			||||||
 | 
					const setCachedImportMap = (data) => {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    const cacheKey = getCacheKey();
 | 
				
			||||||
 | 
					    const cacheData = {
 | 
				
			||||||
 | 
					      data,
 | 
				
			||||||
 | 
					      timestamp: Date.now(),
 | 
				
			||||||
 | 
					      url: import.meta.url,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    localStorage.setItem(cacheKey, JSON.stringify(cacheData));
 | 
				
			||||||
 | 
					    console.log('Import map cached to localStorage');
 | 
				
			||||||
 | 
					  } catch (error) {
 | 
				
			||||||
 | 
					    console.warn('Error saving cache:', error);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 创建import map脚本元素
 | 
				
			||||||
 | 
					const createImportMapScript = (data) => {
 | 
				
			||||||
 | 
					  const script = document.createElement('script');
 | 
				
			||||||
 | 
					  script.type = 'importmap';
 | 
				
			||||||
 | 
					  script.textContent = JSON.stringify(data);
 | 
				
			||||||
 | 
					  document.head.appendChild(script);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const loadErrorDefualt = () => {
 | 
				
			||||||
 | 
					  const baseImportMap = {
 | 
				
			||||||
 | 
					    imports: {
 | 
				
			||||||
 | 
					      main: './index.js',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  createImportMapScript(baseImportMap);
 | 
				
			||||||
 | 
					  console.log('Loaded default import map (not cached due to error)');
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const loadImportMap = async () => {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    // 首先尝试从缓存加载
 | 
				
			||||||
 | 
					    const cached = getCachedImportMap();
 | 
				
			||||||
 | 
					    if (cached) {
 | 
				
			||||||
 | 
					      createImportMapScript(cached.data);
 | 
				
			||||||
 | 
					      // 后台更新缓存(可选:如果想要每次都检查更新的话)
 | 
				
			||||||
 | 
					      // 注释掉下面这行可以完全依赖缓存,直到手动清除
 | 
				
			||||||
 | 
					      // updateCacheInBackground();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const response = await fetch('./imports.json');
 | 
				
			||||||
 | 
					    if (!response.ok) {
 | 
				
			||||||
 | 
					      throw new Error(`HTTP error! status: ${response.status}`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const data = await response.json();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 创建import map并缓存
 | 
				
			||||||
 | 
					    createImportMapScript(data);
 | 
				
			||||||
 | 
					    setCachedImportMap(data);
 | 
				
			||||||
 | 
					  } catch (error) {
 | 
				
			||||||
 | 
					    // 错误情况下不缓存,直接使用默认配置
 | 
				
			||||||
 | 
					    loadErrorDefualt();
 | 
				
			||||||
 | 
					    console.error('Error loading import map:', error);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 后台更新缓存(可选功能)
 | 
				
			||||||
 | 
					export const updateCacheInBackground = async () => {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    const response = await fetch('./imports.json');
 | 
				
			||||||
 | 
					    if (response.ok) {
 | 
				
			||||||
 | 
					      const data = await response.json();
 | 
				
			||||||
 | 
					      setCachedImportMap(data);
 | 
				
			||||||
 | 
					      console.log('Cache updated in background');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } catch (error) {
 | 
				
			||||||
 | 
					    console.warn('Background cache update failed:', error);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const runMain = async () => {
 | 
				
			||||||
 | 
					  const { render } = await import('main');
 | 
				
			||||||
 | 
					  render();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const main = async () => {
 | 
				
			||||||
 | 
					  const { run, element } = getCurrentScriptData();
 | 
				
			||||||
 | 
					  if (!run) {
 | 
				
			||||||
 | 
					    console.log('Script execution is disabled by data-run attribute');
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    await loadImportMap();
 | 
				
			||||||
 | 
					  } catch (error) {
 | 
				
			||||||
 | 
					    console.error('Error loading import map:', error);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  await runMain();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main();
 | 
				
			||||||
							
								
								
									
										20
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "name": "@kevisual/native",
 | 
				
			||||||
 | 
					  "version": "0.0.1",
 | 
				
			||||||
 | 
					  "description": "",
 | 
				
			||||||
 | 
					  "main": "index.js",
 | 
				
			||||||
 | 
					  "files": [
 | 
				
			||||||
 | 
					    "*"
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					  "publishConfig": {
 | 
				
			||||||
 | 
					    "access": "public"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "scripts": {
 | 
				
			||||||
 | 
					    "test": "echo \"Error: no test specified\" && exit 1"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "keywords": [],
 | 
				
			||||||
 | 
					  "author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
 | 
				
			||||||
 | 
					  "license": "MIT",
 | 
				
			||||||
 | 
					  "packageManager": "pnpm@10.7.0",
 | 
				
			||||||
 | 
					  "type": "module"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user