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,19 @@ export class Bookmark<L extends TItemLocation> {
7878 return 0
7979 }
8080
81- async hash ( ) :Promise < string > {
81+ async hash ( { preserveOrder = false , hashFn = 'sha256' } ) :Promise < string > {
8282 if ( ! this . hashValue ) {
83- this . hashValue = await Crypto . sha256 (
84- JSON . stringify ( { title : this . title , url : this . url } )
85- )
83+ this . hashValue = { }
84+ const json = JSON . stringify ( { title : this . title , url : this . url } )
85+ if ( hashFn === 'sha256' ) {
86+ this . hashValue [ hashFn ] = await Crypto . sha256 ( json )
87+ } else if ( hashFn === 'murmur3' ) {
88+ this . hashValue [ hashFn ] = await Crypto . murmurHash3 ( json )
89+ } else {
90+ throw new Error ( 'Unsupported hash function specified' )
91+ }
8692 }
87- return this . hashValue
93+ return this . hashValue [ hashFn ]
8894 }
8995
9096 clone ( withHash ?: boolean ) :Bookmark < L > {
@@ -119,6 +125,7 @@ export class Bookmark<L extends TItemLocation> {
119125 toJSON ( ) {
120126 // Flatten inherited properties for serialization
121127 const result = { }
128+ // eslint-disable-next-line @typescript-eslint/no-this-alias
122129 let obj = this
123130 while ( obj ) {
124131 Object . entries ( obj ) . forEach ( ( [ key , value ] ) => {
@@ -306,9 +313,10 @@ export class Folder<L extends TItemLocation> {
306313 return 0
307314 }
308315
309- async hash ( preserveOrder = false ) : Promise < string > {
310- if ( this . hashValue && typeof this . hashValue [ String ( preserveOrder ) ] !== 'undefined' ) {
311- return this . hashValue [ String ( preserveOrder ) ]
316+ async hash ( { preserveOrder = false , hashFn = 'sha256' } : IHashSettings ) : Promise < string > {
317+ const cacheKey = `${ preserveOrder } -${ hashFn } `
318+ if ( this . hashValue && typeof this . hashValue [ cacheKey ] !== 'undefined' ) {
319+ return this . hashValue [ cacheKey ]
312320 }
313321
314322 if ( ! this . loaded ) {
@@ -329,17 +337,22 @@ export class Folder<L extends TItemLocation> {
329337 } )
330338 }
331339 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 ) ]
340+ const json = JSON . stringify ( {
341+ title : this . title ,
342+ children : await Parallel . map (
343+ children ,
344+ child => child . hash ( { preserveOrder, hashFn} ) ,
345+ 1
346+ )
347+ } )
348+ if ( hashFn === 'sha256' ) {
349+ this . hashValue [ cacheKey ] = await Crypto . sha256 ( json )
350+ } else if ( hashFn === 'murmur3' ) {
351+ this . hashValue [ cacheKey ] = await Crypto . murmurHash3 ( json )
352+ } else {
353+ throw new Error ( 'Unsupported hash function specified' )
354+ }
355+ return this . hashValue [ cacheKey ]
343356 }
344357
345358 copy ( withHash ?:boolean ) :Folder < L > {
0 commit comments