@simoko/tw-zip
Version:
台灣縣市、行政區、郵遞區號(3碼/6碼)查詢工具,支援 React/Vue/Svelte/SolidJS/Angular
1 lines • 23.4 kB
Source Map (JSON)
{"version":3,"sources":["../../src/zip6/loader.ts","../../src/react/lazy.ts"],"names":["DEFAULT_BASE_URL","cityDataCache","citiesData","citiesDataPromise","loadCitiesData","options","baseUrl","res","data","error","loadCityData","city","trimmedCity","cached","response","preloadCities","cities","isCityCached","clearCache","parsedRulesCache","parseRules","rulesStr","parsed","rule","parts","calculateZipCode","area","road","number","lane","alley","cityData","zip3Map","areaData","zip3","rules","suffix","even","rLane","rLane1","rAlley","rAlley1","noBgn","_noBgn1","noEnd","_noEnd1","maxNo","useTwZip6","preload","loading","setLoading","useState","setCities","setZip3Map","setCityState","setAreaState","setRoadState","setNumber","setLane","setAlley","areas","setAreas","roads","setRoads","searchResults","setSearchResults","setCityData","requestIdRef","useRef","useEffect","mounted","init","firstCity","firstCityData","newAreas","newRoads","setCity","useCallback","value","currentRequestId","newCityData","setArea","setRoad","searchRoads","keyword","results","trimmed","a","r","result","useMemo","zipCode","citiesToPreload"],"mappings":"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","file":"lazy.cjs","sourcesContent":["/**\n * 動態載入 zip6 資料\n */\n\nexport type AreaData = Record<string, string>\nexport type CityAreaData = Record<string, AreaData>\nexport type Zip3Map = Record<string, Record<string, string>>\n\nexport interface CitiesData {\n cities: string[]\n zip3: Zip3Map\n}\n\n// 預設使用 jsDelivr CDN\nconst DEFAULT_BASE_URL = 'https://cdn.jsdelivr.net/npm/@simoko/tw-zip/data/zip6'\n\n// 快取\nconst cityDataCache = new Map<string, CityAreaData>()\nlet citiesData: CitiesData | null = null\nlet citiesDataPromise: Promise<CitiesData> | null = null\n\nexport interface LoaderOptions {\n baseUrl?: string\n}\n\n/**\n * 載入縣市列表和 zip3 對照表\n */\nexport async function loadCitiesData(options: LoaderOptions = {}): Promise<CitiesData> {\n if (citiesData) {\n return citiesData\n }\n\n if (citiesDataPromise) {\n return citiesDataPromise\n }\n\n const baseUrl = options.baseUrl || DEFAULT_BASE_URL\n\n citiesDataPromise = fetch(`${baseUrl}/cities.json`)\n .then((res) => {\n if (!res.ok) {\n throw new Error(`Failed to load cities data: HTTP ${res.status}`)\n }\n return res.json()\n })\n .then((data: CitiesData) => {\n citiesData = data\n return data\n })\n .catch((error) => {\n // 清除 promise 以允許重試\n citiesDataPromise = null\n throw error\n })\n\n return citiesDataPromise\n}\n\n/**\n * 載入指定縣市的資料\n */\nexport async function loadCityData(city: string, options: LoaderOptions = {}): Promise<CityAreaData> {\n const trimmedCity = city.trim()\n if (!trimmedCity) {\n throw new Error('City name cannot be empty')\n }\n\n const cached = cityDataCache.get(trimmedCity)\n if (cached) {\n return cached\n }\n\n const baseUrl = options.baseUrl || DEFAULT_BASE_URL\n\n const response = await fetch(`${baseUrl}/${encodeURIComponent(trimmedCity)}.json`)\n if (!response.ok) {\n throw new Error(`Failed to load city data for ${trimmedCity}: HTTP ${response.status}`)\n }\n\n const data = await response.json() as CityAreaData\n\n cityDataCache.set(trimmedCity, data)\n return data\n}\n\n/**\n * 預載入指定縣市\n */\nexport async function preloadCities(cities: string[], options: LoaderOptions = {}): Promise<void> {\n await Promise.all(cities.map(city => loadCityData(city, options)))\n}\n\n/**\n * 取得已快取的縣市資料(同步)\n */\nexport function getCachedCityData(city: string): CityAreaData | undefined {\n return cityDataCache.get(city)\n}\n\n/**\n * 檢查縣市資料是否已快取\n */\nexport function isCityCached(city: string): boolean {\n return cityDataCache.has(city)\n}\n\n/**\n * 清除快取\n */\nexport function clearCache(): void {\n cityDataCache.clear()\n citiesData = null\n citiesDataPromise = null\n}\n","import type { CityAreaData, Zip3Map } from '../zip6/loader'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport {\n clearCache,\n isCityCached,\n loadCitiesData,\n loadCityData,\n preloadCities,\n} from '../zip6/loader'\n\nexport interface SearchResult {\n city: string\n area: string\n road: string\n}\n\nexport interface Zip6Result {\n zipcode: string\n zip3: string\n city: string\n area: string\n road: string\n}\n\nexport interface UseTwZip6Options {\n /** 資料來源 URL(預設使用 jsDelivr CDN) */\n baseUrl?: string\n /** 預載入的縣市列表 */\n preload?: string[]\n}\n\n// 規則解析快取\nconst parsedRulesCache = new Map<string, Array<[string, ...number[]]>>()\n\n// 解析規則字串(帶快取)\nfunction parseRules(rulesStr: string): Array<[string, ...number[]]> {\n if (!rulesStr)\n return []\n\n const cached = parsedRulesCache.get(rulesStr)\n if (cached)\n return cached\n\n const parsed = rulesStr.split('|').map((rule) => {\n const parts = rule.split(',')\n return [parts[0], ...parts.slice(1).map(Number)] as [string, ...number[]]\n })\n\n parsedRulesCache.set(rulesStr, parsed)\n return parsed\n}\n\n// 計算郵遞區號\nfunction calculateZipCode(\n city: string,\n area: string,\n road: string,\n number: number | undefined,\n lane: number | undefined,\n alley: number | undefined,\n cityData: CityAreaData | undefined,\n zip3Map: Zip3Map,\n): Zip6Result | undefined {\n if (!cityData)\n return undefined\n\n const areaData = cityData[area]\n if (!areaData)\n return undefined\n\n const rulesStr = areaData[road]\n if (!rulesStr)\n return undefined\n\n const zip3 = zip3Map[city]?.[area]\n if (!zip3)\n return undefined\n\n const rules = parseRules(rulesStr)\n\n for (const rule of rules) {\n const [suffix, even = 0, rLane = 0, rLane1 = 0, rAlley = 0, rAlley1 = 0, noBgn = 0, _noBgn1 = 0, noEnd = 0, _noEnd1 = 0] = rule\n\n // 檢查巷\n if (rLane > 0 || rLane1 > 0) {\n if (!lane)\n continue\n if (rLane > 0 && rLane1 > 0) {\n if (lane < rLane || lane > rLane1)\n continue\n }\n else if (rLane > 0) {\n if (noEnd === 9999 || noEnd === 9998) {\n if (lane < rLane)\n continue\n }\n else if (lane !== rLane) {\n continue\n }\n }\n }\n\n // 檢查弄\n if (rAlley > 0 || rAlley1 > 0) {\n if (!alley)\n continue\n if (rAlley > 0 && rAlley1 > 0) {\n if (alley < rAlley || alley > rAlley1)\n continue\n }\n else if (rAlley > 0 && alley !== rAlley) {\n continue\n }\n }\n\n // 檢查門牌號碼\n if (number !== undefined && (noBgn > 0 || noEnd > 0)) {\n if (even === 1 && number % 2 === 0)\n continue\n if (even === 2 && number % 2 === 1)\n continue\n\n const maxNo = noEnd === 9999 || noEnd === 9998 ? Number.POSITIVE_INFINITY : noEnd\n if (noBgn > 0 && number < noBgn)\n continue\n if (maxNo !== Number.POSITIVE_INFINITY && number > maxNo)\n continue\n }\n else if (even !== 0 && number !== undefined) {\n if (even === 1 && number % 2 === 0)\n continue\n if (even === 2 && number % 2 === 1)\n continue\n }\n\n return { zipcode: zip3 + suffix, zip3, city, area, road }\n }\n\n // 沒有精確匹配,返回第一筆\n if (rules.length > 0) {\n const [suffix] = rules[0]\n return { zipcode: zip3 + suffix, zip3, city, area, road }\n }\n\n return undefined\n}\n\nexport function useTwZip6(options: UseTwZip6Options = {}) {\n const { baseUrl, preload } = options\n\n const [loading, setLoading] = useState(true)\n const [cities, setCities] = useState<string[]>([])\n const [zip3Map, setZip3Map] = useState<Zip3Map>({})\n\n const [city, setCityState] = useState<string>('')\n const [area, setAreaState] = useState<string>('')\n const [road, setRoadState] = useState<string>('')\n const [number, setNumber] = useState<number | undefined>(undefined)\n const [lane, setLane] = useState<number | undefined>(undefined)\n const [alley, setAlley] = useState<number | undefined>(undefined)\n\n const [areas, setAreas] = useState<string[]>([])\n const [roads, setRoads] = useState<string[]>([])\n const [searchResults, setSearchResults] = useState<SearchResult[]>([])\n const [cityData, setCityData] = useState<CityAreaData | undefined>(undefined)\n\n // 用於追蹤最新請求,處理競態條件\n const requestIdRef = useRef(0)\n\n // 初始化:載入縣市列表\n useEffect(() => {\n let mounted = true\n\n async function init() {\n setLoading(true)\n const data = await loadCitiesData({ baseUrl })\n\n if (!mounted)\n return\n\n setCities(data.cities)\n setZip3Map(data.zip3)\n\n const firstCity = data.cities[0] ?? ''\n setCityState(firstCity)\n\n // 預載入指定縣市\n if (preload && preload.length > 0) {\n await preloadCities(preload, { baseUrl })\n }\n\n // 載入第一個縣市的資料\n if (firstCity) {\n const firstCityData = await loadCityData(firstCity, { baseUrl })\n if (!mounted)\n return\n\n setCityData(firstCityData)\n const newAreas = Object.keys(firstCityData)\n setAreas(newAreas)\n setAreaState(newAreas[0] ?? '')\n\n if (newAreas[0]) {\n const areaData = firstCityData[newAreas[0]]\n if (areaData) {\n const newRoads = Object.keys(areaData)\n setRoads(newRoads)\n setRoadState(newRoads[0] ?? '')\n }\n }\n }\n\n setLoading(false)\n }\n\n init()\n\n return () => {\n mounted = false\n }\n }, [baseUrl])\n\n // 切換縣市(使用 requestId 處理競態條件)\n const setCity = useCallback(async (value: string) => {\n const currentRequestId = ++requestIdRef.current\n setCityState(value)\n setLoading(true)\n\n try {\n const newCityData = await loadCityData(value, { baseUrl })\n\n // 檢查競態條件:如果已有新的請求,忽略此結果\n if (requestIdRef.current !== currentRequestId) {\n return\n }\n\n setCityData(newCityData)\n const newAreas = Object.keys(newCityData)\n setAreas(newAreas)\n setAreaState(newAreas[0] ?? '')\n setRoads([])\n setRoadState('')\n setNumber(undefined)\n setLane(undefined)\n setAlley(undefined)\n\n if (newAreas[0]) {\n const areaData = newCityData[newAreas[0]]\n if (areaData) {\n const newRoads = Object.keys(areaData)\n setRoads(newRoads)\n setRoadState(newRoads[0] ?? '')\n }\n }\n }\n catch (error) {\n // 只有當前請求才報錯\n if (requestIdRef.current === currentRequestId) {\n console.error(`Failed to load city data for ${value}:`, error)\n }\n }\n finally {\n // 只有當前請求才更新 loading 狀態\n if (requestIdRef.current === currentRequestId) {\n setLoading(false)\n }\n }\n }, [baseUrl])\n\n // 切換行政區\n const setArea = useCallback((value: string) => {\n setAreaState(value)\n if (cityData) {\n const areaData = cityData[value]\n if (areaData) {\n const newRoads = Object.keys(areaData)\n setRoads(newRoads)\n setRoadState(newRoads[0] ?? '')\n }\n else {\n setRoads([])\n setRoadState('')\n }\n }\n setNumber(undefined)\n setLane(undefined)\n setAlley(undefined)\n }, [cityData])\n\n // 切換路名\n const setRoad = useCallback((value: string) => {\n setRoadState(value)\n setNumber(undefined)\n setLane(undefined)\n setAlley(undefined)\n }, [])\n\n // 路名搜尋(在已載入的縣市中搜尋)\n const searchRoads = useCallback((keyword: string) => {\n if (!keyword.trim()) {\n setSearchResults([])\n return\n }\n\n const results: SearchResult[] = []\n const trimmed = keyword.trim()\n\n // 搜尋目前縣市\n if (cityData) {\n for (const [a, areaData] of Object.entries(cityData)) {\n for (const r of Object.keys(areaData)) {\n if (r.includes(trimmed)) {\n results.push({ city, area: a, road: r })\n }\n }\n }\n }\n\n setSearchResults(results)\n }, [city, cityData])\n\n // 計算郵遞區號\n const result = useMemo<Zip6Result | undefined>(() => {\n if (!city || !area || !road || !cityData)\n return undefined\n return calculateZipCode(city, area, road, number, lane, alley, cityData, zip3Map)\n }, [city, area, road, number, lane, alley, cityData, zip3Map])\n\n const zipCode = result?.zipcode ?? ''\n const zip3 = result?.zip3 ?? ''\n\n return {\n // 載入狀態\n loading,\n\n // 選項列表\n cities,\n areas,\n roads,\n\n // 選中值\n city,\n area,\n road,\n number,\n lane,\n alley,\n\n // Setters\n setCity,\n setArea,\n setRoad,\n setNumber,\n setLane,\n setAlley,\n\n // 路名搜尋\n searchRoads,\n searchResults,\n\n // 結果\n zipCode,\n zip3,\n result,\n\n // 工具函數\n preloadCities: useCallback(\n (citiesToPreload: string[]) => preloadCities(citiesToPreload, { baseUrl }),\n [baseUrl]\n ),\n isCityCached,\n clearCache,\n }\n}\n"]}