{"_id":"@astralweb/nova-recently-viewed","_rev":"4-2f29a864462d04fc2a3e05409ee1444e","name":"@astralweb/nova-recently-viewed","dist-tags":{"latest":"1.0.2"},"versions":{"0.0.1":{"name":"@astralweb/nova-recently-viewed","version":"0.0.1","keywords":["recently-viewed","nova","vue","nuxt"],"author":{"name":"Astral Web"},"license":"Proprietary","_id":"@astralweb/nova-recently-viewed@0.0.1","maintainers":[{"name":"jimsu","email":"jim@astralwebinc.com"},{"name":"astralweb-darren","email":"darren@astralwebinc.com"},{"name":"infoaw","email":"info@astralwebinc.com"}],"homepage":"https://github.com/AstralWebTW/nova-packages/tree/main/packages/recently-viewed","bugs":{"url":"https://github.com/AstralWebTW/nova-packages/issues"},"dist":{"shasum":"376ce962d78bbdedbb20b3044b92d684ea5bd556","tarball":"https://registry.npmjs.org/@astralweb/nova-recently-viewed/-/nova-recently-viewed-0.0.1.tgz","fileCount":35,"integrity":"sha512-/puK3BqrSps3FgdMfY5JVOfZYO1Y3brRn4KdltwaQzsFZx/Xo7Gveo+Xzpl3loGvVjjoxBL1soZxV2nc3XlmhA==","signatures":[{"sig":"MEUCIQDElpFAdEPXxFu7pYjxnoISNoH/FCUhVV6+TiNxUZffGQIgPCConUmgsg4QDU5n01iyvFFOvTCQY+e/773YuWY65N4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":125268},"main":"dist/index.cjs","type":"module","_from":"file:astralweb-nova-recently-viewed-0.0.1.tgz","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=20.0.0","pnpm":">=10.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./api":{"types":"./dist/api/index.d.ts","import":"./dist/api.js","require":"./dist/api.cjs"},"./types":{"types":"./dist/types/index.d.ts","import":"./dist/types.js","require":"./dist/types.cjs"},"./composables":{"types":"./dist/composables/index.d.ts","import":"./dist/composables.js","require":"./dist/composables.cjs"}},"scripts":{"ci":"pnpm typecheck && pnpm lint && pnpm test && pnpm build","dev":"vite build --watch","lint":"eslint src/","test":"vitest run","build":"vite build","test:ui":"vitest --ui","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","lint:types":"tsc --noEmit && eslint .","test:watch":"vitest","test:coverage":"vitest run --coverage","test:typecheck":"vitest typecheck","typecheck:watch":"tsc --noEmit --watch"},"_npmUser":{"name":"infoaw","email":"info@astralwebinc.com"},"_resolved":"/tmp/2b6ee52312f4a7e24326c196f3a00709/astralweb-nova-recently-viewed-0.0.1.tgz","_integrity":"sha512-/puK3BqrSps3FgdMfY5JVOfZYO1Y3brRn4KdltwaQzsFZx/Xo7Gveo+Xzpl3loGvVjjoxBL1soZxV2nc3XlmhA==","repository":{"url":"git+https://github.com/AstralWebTW/nova-packages.git","type":"git","directory":"packages/recently-viewed"},"_npmVersion":"10.8.2","description":"Recently Viewed module for Nova e-commerce platform - (Internal Use Only)","directories":{},"_nodeVersion":"20.19.5","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vite":"^7.1.1","eslint":"^9.22.0","terser":"^5.43.1","vitest":"^3.0.9","vue-tsc":"^2.2.12","happy-dom":"^20.0.2","stylelint":"^16.23.1","typescript":"^5.8.2","@types/node":"^22.13.10","sass-embedded":"^1.90.0","@vue/test-utils":"^2.4.6","vite-plugin-dts":"^4.3.0","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"^3.2.4","@astralweb/eslint-config":"^1.0.0","@astralweb/nova-magento-types":"^1.3.1","vite-plugin-css-injected-by-js":"^3.5.2"},"peerDependencies":{"vue":"^3.5.18","nuxt":"^3.12.4","tailwindcss":"^3.4.17"},"_npmOperationalInternal":{"tmp":"tmp/nova-recently-viewed_0.0.1_1760678322455_0.32592002334239467","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@astralweb/nova-recently-viewed","version":"1.0.0","keywords":["recently-viewed","nova","vue","nuxt"],"author":{"name":"Astral Web"},"license":"Proprietary","_id":"@astralweb/nova-recently-viewed@1.0.0","maintainers":[{"name":"jimsu","email":"jim@astralwebinc.com"},{"name":"astralweb-darren","email":"darren@astralwebinc.com"},{"name":"infoaw","email":"info@astralwebinc.com"}],"homepage":"https://github.com/AstralWebTW/nova-packages/tree/main/packages/recently-viewed","bugs":{"url":"https://github.com/AstralWebTW/nova-packages/issues"},"dist":{"shasum":"4bbf9578bdf1f55bb515f266f3c47a0832de096f","tarball":"https://registry.npmjs.org/@astralweb/nova-recently-viewed/-/nova-recently-viewed-1.0.0.tgz","fileCount":35,"integrity":"sha512-00ttfCZoHaWU8XXeTNvt6CTcUZoJBBm6qhRutBzSeyV3pWUfGNb9qLIbdOxwqaZeDRQq3IjF6jusXpu7ceuxXg==","signatures":[{"sig":"MEYCIQDXhxqV5QHbnEC0sgJU/n3ldyvVrrYLF9gLvD8uxzBQdAIhAN8kCM+CCW2/5xy5JWrj2Rjqihp3PISqlarLOgX4b0k1","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":125269},"main":"dist/index.cjs","type":"module","_from":"file:astralweb-nova-recently-viewed-1.0.0.tgz","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=20.0.0","pnpm":">=10.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./api":{"types":"./dist/api/index.d.ts","import":"./dist/api.js","require":"./dist/api.cjs"},"./types":{"types":"./dist/types/index.d.ts","import":"./dist/types.js","require":"./dist/types.cjs"},"./composables":{"types":"./dist/composables/index.d.ts","import":"./dist/composables.js","require":"./dist/composables.cjs"}},"scripts":{"ci":"pnpm typecheck && pnpm lint && pnpm test && pnpm build","dev":"vite build --watch","lint":"eslint src/","test":"vitest run","build":"vite build","test:ui":"vitest --ui","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","lint:types":"tsc --noEmit && eslint .","test:watch":"vitest","test:coverage":"vitest run --coverage","test:typecheck":"vitest typecheck","typecheck:watch":"tsc --noEmit --watch"},"_npmUser":{"name":"infoaw","email":"info@astralwebinc.com"},"_resolved":"/tmp/92ecc77550e8542703d83d7bc1b20968/astralweb-nova-recently-viewed-1.0.0.tgz","_integrity":"sha512-00ttfCZoHaWU8XXeTNvt6CTcUZoJBBm6qhRutBzSeyV3pWUfGNb9qLIbdOxwqaZeDRQq3IjF6jusXpu7ceuxXg==","repository":{"url":"git+https://github.com/AstralWebTW/nova-packages.git","type":"git","directory":"packages/recently-viewed"},"_npmVersion":"10.8.2","description":"Recently Viewed module for Nova e-commerce platform - (Internal Use Only)","directories":{},"_nodeVersion":"20.19.6","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vite":"^7.1.11","eslint":"^9.22.0","terser":"^5.43.1","vitest":"^3.2.4","vue-tsc":"^2.2.12","happy-dom":"^20.0.2","stylelint":"^16.23.1","typescript":"^5.8.2","@types/node":"^22.13.10","sass-embedded":"^1.90.0","@vue/test-utils":"^2.4.6","vite-plugin-dts":"^4.3.0","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"^3.2.4","@astralweb/eslint-config":"^1.0.0","@astralweb/nova-magento-types":"^1.3.1","vite-plugin-css-injected-by-js":"^3.5.2"},"peerDependencies":{"vue":"^3.5.18","nuxt":"^3.12.4","tailwindcss":"^3.4.17"},"_npmOperationalInternal":{"tmp":"tmp/nova-recently-viewed_1.0.0_1764917696014_0.6745510364889571","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@astralweb/nova-recently-viewed","version":"1.0.1","keywords":["recently-viewed-product","magento","nuxt-module"],"author":{"name":"Astral Web"},"license":"Proprietary","_id":"@astralweb/nova-recently-viewed@1.0.1","maintainers":[{"name":"jimsu","email":"jim@astralwebinc.com"},{"name":"astralweb-darren","email":"darren@astralwebinc.com"},{"name":"infoaw","email":"info@astralwebinc.com"}],"homepage":"https://github.com/AstralWebTW/nova-packages/tree/main/packages/recently-viewed-product","bugs":{"url":"https://github.com/AstralWebTW/nova-packages/issues"},"dist":{"shasum":"9a2d2cda476ca8e22feff6528372475d46834e21","tarball":"https://registry.npmjs.org/@astralweb/nova-recently-viewed/-/nova-recently-viewed-1.0.1.tgz","fileCount":28,"integrity":"sha512-hkeUqJQZhhERgfOupL+idcYwNdmlibHMEu15PAP8JjgCWff5z+doTFoFi19wLq+6BxJSzjKNOUdbKzrKm2Mvag==","signatures":[{"sig":"MEUCIHx+/6mzcH4MRt7tW+L0gCErMkrG4LaztVuiEP/5nqESAiEAvKrOZlqKZRMctmZhLKp7JE/hgedqzZxBrqDkR8Nm9Vc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":21998},"main":"./dist/module.mjs","type":"module","_from":"file:astralweb-nova-recently-viewed-1.0.1.tgz","engines":{"node":">=20.0.0","pnpm":">=10.0.0"},"exports":{".":{"types":"./dist/module.d.mts","import":"./dist/module.mjs"},"./api":{"types":"./dist/runtime/api/index.d.ts","import":"./dist/runtime/api/index.js"},"./composables":{"types":"./dist/runtime/composables/index.d.ts","import":"./dist/runtime/composables/index.js"}},"scripts":{"dev":"pnpm run dev:prepare && nuxi dev playground","lint":"eslint .","test":"vitest run","build":"nuxt-module-build build","lint:fix":"eslint . --fix","dev:build":"nuxi build playground","typecheck":"tsc --noEmit","test:types":"vue-tsc --noEmit && cd playground && vue-tsc --noEmit","test:watch":"vitest watch","dev:prepare":"nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground","dev:preview":"nuxi preview playground --port 3001","build:prepare":"nuxt-module-build prepare && nuxi prepare playground"},"_npmUser":{"name":"infoaw","email":"info@astralwebinc.com"},"_resolved":"/tmp/c757f17d7662babac495aca5b8946a04/astralweb-nova-recently-viewed-1.0.1.tgz","_integrity":"sha512-hkeUqJQZhhERgfOupL+idcYwNdmlibHMEu15PAP8JjgCWff5z+doTFoFi19wLq+6BxJSzjKNOUdbKzrKm2Mvag==","repository":{"url":"git+https://github.com/AstralWebTW/nova-packages.git","type":"git","directory":"packages/recently-viewed-product"},"_npmVersion":"10.8.2","description":"Recently Viewed module for Nova e-commerce platform (Internal Use Only)","directories":{},"_nodeVersion":"20.19.6","dependencies":{"@nuxt/kit":"^4.1.3"},"typesVersions":{"*":{".":["./dist/types.d.mts"]}},"_hasShrinkwrap":false,"devDependencies":{"nuxt":"^4.1.3","eslint":"^9.37.0","vitest":"^3.2.4","vue-tsc":"^3.1.1","typescript":"^5.9.3","@types/node":"latest","@nuxt/schema":"^4.1.3","@nuxt/devtools":"^2.6.5","@nuxt/test-utils":"^3.19.2","@nuxt/eslint-config":"^1.9.0","@nuxt/module-builder":"^1.0.2","@astralweb/eslint-config":"1.0.6"},"peerDependencies":{"nuxt":"^3.0.0 || ^4.0.0","@vue-storefront/sdk":"^3.2.0","@vue-storefront/middleware":"^5.4.0","@vue-storefront/magento-api":"^6.3.0"},"_npmOperationalInternal":{"tmp":"tmp/nova-recently-viewed_1.0.1_1764921315070_0.9089478332586896","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@astralweb/nova-recently-viewed","version":"1.0.2","description":"Recently Viewed module for Nova e-commerce platform (Internal Use Only)","license":"Proprietary","type":"module","exports":{".":{"types":"./dist/module.d.mts","import":"./dist/module.mjs"},"./api":{"types":"./dist/runtime/api/index.d.ts","import":"./dist/runtime/api/index.js"},"./composables":{"types":"./dist/runtime/composables/index.d.ts","import":"./dist/runtime/composables/index.js"}},"main":"./dist/module.mjs","typesVersions":{"*":{".":["./dist/types.d.mts"]}},"dependencies":{"@nuxt/kit":"^4.1.3"},"peerDependencies":{"@vue-storefront/magento-api":"^6.3.0","@vue-storefront/middleware":"^5.4.0","@vue-storefront/sdk":"^3.2.0","nuxt":"^3.0.0 || ^4.0.0"},"devDependencies":{"@apollo/client":"^3.8.0","@nuxt/devtools":"^2.6.5","@nuxt/eslint-config":"^1.9.0","@nuxt/module-builder":"^1.0.2","@nuxt/schema":"^4.1.3","@nuxt/test-utils":"^3.19.2","@types/node":"latest","@vue-storefront/middleware":"^5.4.1","eslint":"^9.38.0","graphql-tag":"^2.12.0","nuxt":"^4.1.3","tailwindcss":"^4.1.17","typescript":"^5.9.3","vitest":"^3.2.4","vue-tsc":"^3.1.1","@astralweb/eslint-config":"2.1.0"},"repository":{"type":"git","url":"git+https://github.com/AstralWebTW/nova-packages.git","directory":"packages/recently-viewed-product"},"publishConfig":{"access":"public"},"keywords":["recently-viewed-product","magento","nuxt-module"],"author":{"name":"Astral Web"},"homepage":"https://github.com/AstralWebTW/nova-packages/tree/main/packages/recently-viewed-product","engines":{"node":">=20.0.0","pnpm":">=10.0.0"},"scripts":{"build:prepare":"nuxt-module-build prepare && nuxi prepare playground","build":"nuxt-module-build build","dev":"pnpm run dev:prepare && nuxi dev playground","dev:build":"nuxi build playground","dev:preview":"nuxi preview playground --port 3001","dev:prepare":"nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground","typecheck":"nuxt typecheck","lint":"eslint .","lint:fix":"eslint . --fix","test":"vitest run","test:watch":"vitest watch","test:types":"vue-tsc --noEmit && cd playground && vue-tsc --noEmit"},"_id":"@astralweb/nova-recently-viewed@1.0.2","bugs":{"url":"https://github.com/AstralWebTW/nova-packages/issues"},"_integrity":"sha512-Wy2VT1Rp/XQZvDXnNbUdHRtHN+nJWVg8M59cqKFcLCgXnFHbntsWCwx+gb94/pLNCnPxvUPNpINbROlgkkwUgQ==","_resolved":"/tmp/6f9a7127da6b28b145097caba59cb1af/astralweb-nova-recently-viewed-1.0.2.tgz","_from":"file:astralweb-nova-recently-viewed-1.0.2.tgz","_nodeVersion":"20.20.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-Wy2VT1Rp/XQZvDXnNbUdHRtHN+nJWVg8M59cqKFcLCgXnFHbntsWCwx+gb94/pLNCnPxvUPNpINbROlgkkwUgQ==","shasum":"3846e5351b7e1ad55372eaf12c8a0a289da3bc68","tarball":"https://registry.npmjs.org/@astralweb/nova-recently-viewed/-/nova-recently-viewed-1.0.2.tgz","fileCount":28,"unpackedSize":22187,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGCGP7GoMcZ1wzqnB1sl4gl8otlZYrhOm3XJuCsjwvTkAiEAs3D6sMgkl+vcyoqi840VuEL+MVA1BkT9UTSZv73d06g="}]},"_npmUser":{"name":"infoaw","email":"info@astralwebinc.com"},"directories":{},"maintainers":[{"name":"jimsu","email":"jim@astralwebinc.com"},{"name":"astralweb-darren","email":"darren@astralwebinc.com"},{"name":"infoaw","email":"info@astralwebinc.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nova-recently-viewed_1.0.2_1772087974143_0.0590847538190411"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-17T05:18:42.359Z","modified":"2026-02-26T06:39:34.444Z","0.0.1":"2025-10-17T05:18:42.625Z","1.0.0":"2025-12-05T06:54:56.166Z","1.0.1":"2025-12-05T07:55:15.211Z","1.0.2":"2026-02-26T06:39:34.286Z"},"bugs":{"url":"https://github.com/AstralWebTW/nova-packages/issues"},"author":{"name":"Astral Web"},"license":"Proprietary","homepage":"https://github.com/AstralWebTW/nova-packages/tree/main/packages/recently-viewed-product","keywords":["recently-viewed-product","magento","nuxt-module"],"repository":{"type":"git","url":"git+https://github.com/AstralWebTW/nova-packages.git","directory":"packages/recently-viewed-product"},"description":"Recently Viewed module for Nova e-commerce platform (Internal Use Only)","maintainers":[{"name":"jimsu","email":"jim@astralwebinc.com"},{"name":"astralweb-darren","email":"darren@astralwebinc.com"},{"name":"infoaw","email":"info@astralwebinc.com"}],"readme":"# Recently Viewed 模組使用指南\n\n> ⚠️ **內部使用套件** - 此套件僅供 Astral Web 內部使用，未經授權不得用於其他用途。\n\n## 概覽\n\nRecently Viewed 是一個 Nuxt 3 模組，提供完整的最近瀏覽商品追蹤與管理功能。模組採用 Nuxt Module 架構設計，支援本地儲存與伺服器同步、訪客與會員資料自動合併，並提供靈活的配置選項。\n\n## 安裝與設定\n\n### 1. 安裝套件\n\n#### 在 apps/web 和 apps/server 安裝\n\n```bash\nyarn add @astralweb/nova-recently-viewed\n```\n\n### 2. Middleware 擴充\n\n```typescript\n// apps/server/extendApiMethods/index.ts\n\nexport {\n  recentlyViewedProducts,\n  addRecentlyViewedProducts,\n} from '@astralweb/nova-recently-viewed/api';\n```\n\n### 3. 註冊模組\n\n```typescript\n// apps/web/nuxt.config.ts\n\nexport default defineNuxtConfig({\n  modules: [\n    '@astralweb/nova-recently-viewed',\n  ],\n})\n```\n\n## 架構設計\n\n### 三層架構\n\n1. **API Layer** (`useRecentlyViewedApi`)\n   - 處理與 GraphQL 後端的通信\n   - 提供 `syncToServer` 和 `fetchFromServer` 方法\n\n2. **Storage Layer** (`useRecentlyViewedStorage`)\n   - 管理本地儲存與核心業務邏輯\n   - 處理訪客/會員資料合併\n   - 提供完整的 CRUD 操作\n\n3. **List Layer** (`useRecentlyViewedList`)\n   - 高階封裝，適用於產品詳情頁\n   - 自動處理初始化、登入狀態變化、SKU 更新\n   - 提供開箱即用的體驗\n\n## 使用方式\n\n適合產品詳情頁，自動處理所有邏輯。\n\n```vue\n<template>\n  <ProductSlider :products-sku=\"recentlyViewedSkus\" />\n</template>\n\n<script setup lang=\"ts\">\nconst { recentlyViewedSkus } = useRecentlyViewedList({\n  currentSku: computed(() => product.value?.sku ?? ''),\n  isLoggedIn: computed(() => !!user.value),\n  enableServerSync: true,\n});\n</script>\n```\n\n**自動處理：**\n- ✅ 組件掛載時初始化\n- ✅ SKU 變化時更新列表\n- ✅ 登入狀態變化時合併資料\n- ✅ 本地緩存優化\n\n\n## API 參考\n\n### useRecentlyViewedList\n\n```typescript\nconst { recentlyViewedSkus } = useRecentlyViewedList({\n  currentSku: Ref<string> | ComputedRef<string>,\n  isLoggedIn: ComputedRef<boolean>,\n  maxItems?: number,              // 預設：20\n  guestStorageKey?: string,       // 預設：'recently-viewed-guest'\n  customerStorageKey?: string,    // 預設：'recently-viewed-customer'\n  enableServerSync?: boolean,     // 預設：true\n  autoInit?: boolean,             // 預設：true\n});\n```\n\n**返回值：**\n- `recentlyViewedSkus`: `Ref<string[]>` - 最近瀏覽商品的 SKU 列表\n\n### useRecentlyViewedStorage\n\n核心 composable，提供完整的儲存管理功能。\n\n```typescript\nconst {\n  addRecentlyViewed,\n  getRecentlyViewedSkus,\n  getSkusFromLocalStorage,\n  clearAllRecentlyViewed,\n  mergeGuestToCustomer,\n  isLoggedIn,\n} = useRecentlyViewedStorage(config, isLoggedIn);\n```\n\n**配置選項：**\n```typescript\ninterface RecentlyViewedConfig {\n  maxItems?: number;              // 最多儲存數量（預設：20）\n  guestStorageKey?: string;       // 訪客 localStorage key\n  customerStorageKey?: string;    // 會員 localStorage key\n  enableServerSync?: boolean;     // 啟用伺服器同步（預設：true）\n}\n```\n\n**方法：**\n- `addRecentlyViewed(sku: string): Promise<void>` - 添加商品到最近瀏覽\n- `getRecentlyViewedSkus(excludeSku?: string): Promise<string[]>` - 獲取 SKU 列表（伺服器優先）\n- `getSkusFromLocalStorage(excludeSku?: string): string[]` - 從本地儲存獲取 SKU 列表\n- `clearAllRecentlyViewed(): void` - 清除所有記錄\n- `mergeGuestToCustomer(): Promise<void>` - 合併訪客資料到會員帳戶\n\n### useRecentlyViewedApi\n\nAPI 層 composable，處理與後端的通信。\n\n```typescript\nconst {\n  syncToServer,\n  fetchFromServer,\n} = useRecentlyViewedApi();\n```\n\n**方法：**\n- `syncToServer(input: AddRecentlyViewedInputItem[]): Promise<void>` - 同步資料到伺服器\n- `fetchFromServer(): Promise<AddRecentlyViewedInputItem[]>` - 從伺服器獲取資料\n\n## 工作原理\n\n### 訪客模式\n\n- 資料保存在 `localStorage`（key: `recently-viewed-guest`）\n- 不進行伺服器同步\n- 本地去重與數量限制\n\n### 登入模式\n\n- 主要資料來源：伺服器\n- 本地緩存：加速 UI 更新\n- 新增時：同步到伺服器 → 更新本地緩存\n\n### 登入時資料合併\n\n1. 讀取訪客 `localStorage` 資料\n2. 同步到伺服器（合併到會員帳戶）\n3. 清除訪客資料\n4. 從伺服器獲取最新資料\n\n## 授權\n\n此套件僅供 Astral Web 內部使用，未經授權不得用於其他用途。\n","readmeFilename":"README.md"}