diff --git a/package-lock.json b/package-lock.json index 08714a9a2..885a8066f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { + "dexie": "^4.0.8", "medium-zoom": "^1.1.0", "opencollective-postinstall": "^2.0.2", "prismjs": "^1.29.0", @@ -5873,6 +5874,11 @@ "node": ">= 0.8.0" } }, + "node_modules/dexie": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/dexie/-/dexie-4.0.8.tgz", + "integrity": "sha512-1G6cJevS17KMDK847V3OHvK2zei899GwpDiqfEXHP1ASvme6eWJmAp9AU4s1son2TeGkWmC0g3y8ezOBPnalgQ==" + }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", diff --git a/package.json b/package.json index cc0bd26da..c9efb5d71 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "*.js": "eslint --fix" }, "dependencies": { + "dexie": "^4.0.8", "medium-zoom": "^1.1.0", "opencollective-postinstall": "^2.0.2", "prismjs": "^1.29.0", diff --git a/src/plugins/search/search.js b/src/plugins/search/search.js index 95aa83a8b..6e8f4e96f 100644 --- a/src/plugins/search/search.js +++ b/src/plugins/search/search.js @@ -2,8 +2,24 @@ import { getAndRemoveConfig, getAndRemoveDocisfyIgnoreConfig, } from '../../core/render/utils.js'; +import Dexie from 'dexie'; -let INDEXS = {}; +let INDEXES = {}; + +const db = new Dexie('DocsifySearchDB'); +db.version(1).stores({ + search: 'key, value', +}); + +async function saveData(maxAge, expireKey, indexKey) { + await db.search.put({ key: expireKey, value: Date.now() + maxAge }); + await db.search.put({ key: indexKey, value: JSON.stringify(INDEXES) }); +} + +async function getData(key) { + const item = await db.search.get(key); + return item ? item.value : null; +} const LOCAL_STORAGE = { EXPIRE_KEY: 'docsify.search.expires', @@ -73,11 +89,6 @@ function getListData(token) { return token.text; } -function saveData(maxAge, expireKey, indexKey) { - localStorage.setItem(expireKey, Date.now() + maxAge); - localStorage.setItem(indexKey, JSON.stringify(INDEXS)); -} - export function genIndex(path, content = '', router, depth) { const tokens = window.marked.lexer(content); const slugify = window.Docsify.slugify; @@ -149,10 +160,10 @@ export function ignoreDiacriticalMarks(keyword) { export function search(query) { const matchingResults = []; let data = []; - Object.keys(INDEXS).forEach(key => { + Object.keys(INDEXES).forEach(key => { data = [ ...data, - ...Object.keys(INDEXS[key]).map(page => INDEXS[key][page]), + ...Object.keys(INDEXES[key]).map(page => INDEXES[key][page]), ]; }); @@ -240,7 +251,7 @@ export function search(query) { return matchingResults.sort((r1, r2) => r2.score - r1.score); } -export function init(config, vm) { +export async function init(config, vm) { const isAuto = config.paths === 'auto'; const paths = isAuto ? getAllPaths(vm.router) : config.paths; @@ -274,12 +285,12 @@ export function init(config, vm) { const expireKey = resolveExpireKey(config.namespace) + namespaceSuffix; const indexKey = resolveIndexKey(config.namespace) + namespaceSuffix; - const isExpired = localStorage.getItem(expireKey) < Date.now(); + const isExpired = (await getData(expireKey)) < Date.now(); - INDEXS = JSON.parse(localStorage.getItem(indexKey)); + INDEXES = JSON.parse(await getData(indexKey)); if (isExpired) { - INDEXS = {}; + INDEXES = {}; } else if (!isAuto) { return; } @@ -288,14 +299,16 @@ export function init(config, vm) { let count = 0; paths.forEach(path => { - if (INDEXS[path]) { + if (INDEXES[path]) { return count++; } Docsify.get(vm.router.getFile(path), false, vm.config.requestHeaders).then( - result => { - INDEXS[path] = genIndex(path, result, vm.router, config.depth); - len === ++count && saveData(config.maxAge, expireKey, indexKey); + async result => { + INDEXES[path] = genIndex(path, result, vm.router, config.depth); + if (len === ++count) { + await saveData(config.maxAge, expireKey, indexKey); + } }, ); }); diff --git a/test/integration/example.test.js b/test/integration/example.test.js index baadd978f..cf1d3cb88 100644 --- a/test/integration/example.test.js +++ b/test/integration/example.test.js @@ -20,7 +20,6 @@ describe('Creating a Docsify site (integration tests in Jest)', function () { const docsifyInitConfig = { config: { name: 'Docsify Name', - themeColor: 'red', }, markdown: { coverpage: ` @@ -58,8 +57,6 @@ describe('Creating a Docsify site (integration tests in Jest)', function () { scriptURLs: [ // docsifyInit() route 'data-test-scripturls.js', - // Server route - '/dist/plugins/search.js', ], style: ` body { @@ -76,7 +73,6 @@ describe('Creating a Docsify site (integration tests in Jest)', function () { // Verify config options expect(typeof window.$docsify).toBe('object'); - expect(window.$docsify).toHaveProperty('themeColor', 'red'); expect(document.querySelector('.app-name').textContent).toContain( 'Docsify Name', ); @@ -101,7 +97,6 @@ describe('Creating a Docsify site (integration tests in Jest)', function () { // Verify docsifyInitConfig.scriptURLs were executed expect(document.body.hasAttribute('data-test-scripturls')).toBe(true); - expect(document.querySelector('.search input[type="search"]')).toBeTruthy(); // Verify docsifyInitConfig.script was added to the DOM expect(