11import Crypto from './Crypto'
22import Logger from './Logger'
3- import TResource from './interfaces/Resource'
3+ import TResource , { IHashSettings } from './interfaces/Resource'
44import * as Parallel from 'async-parallel'
55
66const STRANGE_PROTOCOLS = [ 'data:' , 'javascript:' , 'about:' , 'chrome:' , 'file:' ]
@@ -37,7 +37,7 @@ export class Bookmark<L extends TItemLocation> {
3737 public tags : string [ ]
3838 public location : L
3939 public isRoot = false
40- private hashValue : string
40+ private hashValue : Record < string , string >
4141
4242 constructor ( { id, parentId, url, title, tags, location } : { id :string | number , parentId :string | number , url :string , title :string , tags ?: string [ ] , location : L } ) {
4343 this . id = id
@@ -78,13 +78,25 @@ export class Bookmark<L extends TItemLocation> {
7878 return 0
7979 }
8080
81- async hash ( ) :Promise < string > {
81+ setHashCacheValue ( hashSettings : IHashSettings , value : string ) : void {
82+ const cacheKey = `${ hashSettings . preserveOrder } -${ hashSettings . hashFn } `
83+ if ( ! this . hashValue ) this . hashValue = { }
84+ this . hashValue [ cacheKey ] = value
85+ }
86+
87+ async hash ( { preserveOrder = false , hashFn = 'sha256' } ) :Promise < string > {
8288 if ( ! this . hashValue ) {
83- this . hashValue = await Crypto . sha256 (
84- JSON . stringify ( { title : this . title , url : this . url } )
85- )
89+ this . hashValue = { }
90+ const json = JSON . stringify ( { title : this . title , url : this . url } )
91+ if ( hashFn === 'sha256' ) {
92+ this . hashValue [ hashFn ] = await Crypto . sha256 ( json )
93+ } else if ( hashFn === 'murmur3' ) {
94+ this . hashValue [ hashFn ] = await Crypto . murmurHash3 ( json )
95+ } else {
96+ throw new Error ( 'Unsupported hash function specified' )
97+ }
8698 }
87- return this . hashValue
99+ return this . hashValue [ hashFn ]
88100 }
89101
90102 clone ( withHash ?: boolean ) :Bookmark < L > {
@@ -119,6 +131,7 @@ export class Bookmark<L extends TItemLocation> {
119131 toJSON ( ) {
120132 // Flatten inherited properties for serialization
121133 const result = { }
134+ // eslint-disable-next-line @typescript-eslint/no-this-alias
122135 let obj = this
123136 while ( obj ) {
124137 Object . entries ( obj ) . forEach ( ( [ key , value ] ) => {
@@ -306,9 +319,16 @@ export class Folder<L extends TItemLocation> {
306319 return 0
307320 }
308321
309- async hash ( preserveOrder = false ) : Promise < string > {
310- if ( this . hashValue && typeof this . hashValue [ String ( preserveOrder ) ] !== 'undefined' ) {
311- return this . hashValue [ String ( preserveOrder ) ]
322+ setHashCacheValue ( hashSettings : IHashSettings , value : string ) : void {
323+ const cacheKey = `${ hashSettings . preserveOrder } -${ hashSettings . hashFn } `
324+ if ( ! this . hashValue ) this . hashValue = { }
325+ this . hashValue [ cacheKey ] = value
326+ }
327+
328+ async hash ( { preserveOrder = false , hashFn = 'sha256' } : IHashSettings = { preserveOrder : false , hashFn : 'sha256' } ) : Promise < string > {
329+ const cacheKey = `${ preserveOrder } -${ hashFn } `
330+ if ( this . hashValue && typeof this . hashValue [ cacheKey ] !== 'undefined' ) {
331+ return this . hashValue [ cacheKey ]
312332 }
313333
314334 if ( ! this . loaded ) {
@@ -329,17 +349,22 @@ export class Folder<L extends TItemLocation> {
329349 } )
330350 }
331351 if ( ! this . hashValue ) this . hashValue = { }
332- this . hashValue [ String ( preserveOrder ) ] = await Crypto . sha256 (
333- JSON . stringify ( {
334- title : this . title ,
335- children : await Parallel . map (
336- children ,
337- child => child . hash ( preserveOrder ) ,
338- 1
339- )
340- } )
341- )
342- return this . hashValue [ String ( preserveOrder ) ]
352+ const json = JSON . stringify ( {
353+ title : this . title ,
354+ children : await Parallel . map (
355+ children ,
356+ child => child . hash ( { preserveOrder, hashFn} ) ,
357+ 1
358+ )
359+ } )
360+ if ( hashFn === 'sha256' ) {
361+ this . hashValue [ cacheKey ] = await Crypto . sha256 ( json )
362+ } else if ( hashFn === 'murmur3' ) {
363+ this . hashValue [ cacheKey ] = await Crypto . murmurHash3 ( json )
364+ } else {
365+ throw new Error ( 'Unsupported hash function specified' )
366+ }
367+ return this . hashValue [ cacheKey ]
343368 }
344369
345370 copy ( withHash ?:boolean ) :Folder < L > {
0 commit comments