@@ -3,8 +3,33 @@ import {
3
3
getAndRemoveDocsifyIgnoreConfig ,
4
4
} from '../../core/render/utils.js' ;
5
5
import { markdownToTxt } from './markdown-to-txt.js' ;
6
+ import Dexie from 'dexie' ;
7
+
8
+ let INDEXES = { } ;
9
+
10
+ const db = new Dexie ( 'docsify' ) ;
11
+ db . version ( 1 ) . stores ( {
12
+ search : 'slug, title, body, path, indexKey' ,
13
+ expires : 'key, value' ,
14
+ } ) ;
15
+
16
+ async function saveData ( maxAge , expireKey ) {
17
+ INDEXES = Object . values ( INDEXES ) . flatMap ( innerData =>
18
+ Object . values ( innerData ) ,
19
+ ) ;
20
+ await db . search . bulkPut ( INDEXES ) ;
21
+ await db . expires . put ( { key : expireKey , value : Date . now ( ) + maxAge } ) ;
22
+ }
6
23
7
- let INDEXS = { } ;
24
+ async function getData ( key , isExpireKey = false ) {
25
+ if ( isExpireKey ) {
26
+ const item = await db . expires . get ( key ) ;
27
+ return item ? item . value : 0 ;
28
+ }
29
+
30
+ const item = await db . search . where ( { indexKey : key } ) . toArray ( ) ;
31
+ return item ? item : null ;
32
+ }
8
33
9
34
const LOCAL_STORAGE = {
10
35
EXPIRE_KEY : 'docsify.search.expires' ,
@@ -85,12 +110,7 @@ function getListData(token) {
85
110
return token . text ;
86
111
}
87
112
88
- function saveData ( maxAge , expireKey , indexKey ) {
89
- localStorage . setItem ( expireKey , Date . now ( ) + maxAge ) ;
90
- localStorage . setItem ( indexKey , JSON . stringify ( INDEXS ) ) ;
91
- }
92
-
93
- export function genIndex ( path , content = '' , router , depth ) {
113
+ export function genIndex ( path , content = '' , router , depth , indexKey ) {
94
114
const tokens = window . marked . lexer ( content ) ;
95
115
const slugify = window . Docsify . slugify ;
96
116
const index = { } ;
@@ -113,14 +133,22 @@ export function genIndex(path, content = '', router, depth) {
113
133
title = getAndRemoveDocsifyIgnoreConfig ( str ) . content ;
114
134
}
115
135
116
- index [ slug ] = { slug, title : title , body : '' } ;
136
+ index [ slug ] = {
137
+ slug,
138
+ title : title ,
139
+ body : '' ,
140
+ path : path ,
141
+ indexKey : indexKey ,
142
+ } ;
117
143
} else {
118
144
if ( tokenIndex === 0 ) {
119
145
slug = router . toURL ( path ) ;
120
146
index [ slug ] = {
121
147
slug,
122
148
title : path !== '/' ? path . slice ( 1 ) : 'Home Page' ,
123
149
body : token . text || '' ,
150
+ path : path ,
151
+ indexKey : indexKey ,
124
152
} ;
125
153
}
126
154
@@ -141,6 +169,9 @@ export function genIndex(path, content = '', router, depth) {
141
169
142
170
index [ slug ] . body = token . text || '' ;
143
171
}
172
+
173
+ index [ slug ] . path = path ;
174
+ index [ slug ] . indexKey = indexKey ;
144
175
}
145
176
} ) ;
146
177
slugify . clear ( ) ;
@@ -160,21 +191,14 @@ export function ignoreDiacriticalMarks(keyword) {
160
191
*/
161
192
export function search ( query ) {
162
193
const matchingResults = [ ] ;
163
- let data = [ ] ;
164
- Object . keys ( INDEXS ) . forEach ( key => {
165
- data = [
166
- ...data ,
167
- ...Object . keys ( INDEXS [ key ] ) . map ( page => INDEXS [ key ] [ page ] ) ,
168
- ] ;
169
- } ) ;
170
194
171
195
query = query . trim ( ) ;
172
196
let keywords = query . split ( / [ \s \- , \\ / ] + / ) ;
173
197
if ( keywords . length !== 1 ) {
174
198
keywords = [ query , ...keywords ] ;
175
199
}
176
200
177
- for ( const post of data ) {
201
+ for ( const post of INDEXES ) {
178
202
let matchesScore = 0 ;
179
203
let resultStr = '' ;
180
204
let handlePostTitle = '' ;
@@ -242,7 +266,7 @@ export function search(query) {
242
266
return matchingResults . sort ( ( r1 , r2 ) => r2 . score - r1 . score ) ;
243
267
}
244
268
245
- export function init ( config , vm ) {
269
+ export async function init ( config , vm ) {
246
270
const isAuto = config . paths === 'auto' ;
247
271
const paths = isAuto ? getAllPaths ( vm . router ) : config . paths ;
248
272
@@ -276,12 +300,12 @@ export function init(config, vm) {
276
300
const expireKey = resolveExpireKey ( config . namespace ) + namespaceSuffix ;
277
301
const indexKey = resolveIndexKey ( config . namespace ) + namespaceSuffix ;
278
302
279
- const isExpired = localStorage . getItem ( expireKey ) < Date . now ( ) ;
303
+ const isExpired = ( await getData ( expireKey , true ) ) < Date . now ( ) ;
280
304
281
- INDEXS = JSON . parse ( localStorage . getItem ( indexKey ) ) ;
305
+ INDEXES = await getData ( indexKey ) ;
282
306
283
307
if ( isExpired ) {
284
- INDEXS = { } ;
308
+ INDEXES = { } ;
285
309
} else if ( ! isAuto ) {
286
310
return ;
287
311
}
@@ -290,14 +314,25 @@ export function init(config, vm) {
290
314
let count = 0 ;
291
315
292
316
paths . forEach ( path => {
293
- if ( INDEXS [ path ] ) {
317
+ const pathExists = Array . isArray ( INDEXES )
318
+ ? INDEXES . some ( obj => obj . path === path )
319
+ : false ;
320
+ if ( pathExists ) {
294
321
return count ++ ;
295
322
}
296
323
297
324
Docsify . get ( vm . router . getFile ( path ) , false , vm . config . requestHeaders ) . then (
298
- result => {
299
- INDEXS [ path ] = genIndex ( path , result , vm . router , config . depth ) ;
300
- len === ++ count && saveData ( config . maxAge , expireKey , indexKey ) ;
325
+ async result => {
326
+ INDEXES [ path ] = genIndex (
327
+ path ,
328
+ result ,
329
+ vm . router ,
330
+ config . depth ,
331
+ indexKey ,
332
+ ) ;
333
+ if ( len === ++ count ) {
334
+ await saveData ( config . maxAge , expireKey ) ;
335
+ }
301
336
} ,
302
337
) ;
303
338
} ) ;
0 commit comments