@xyo-network/hash 4.3.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/ObjectHasher.d.ts +0 -5
- package/dist/browser/ObjectHasher.d.ts.map +1 -1
- package/dist/browser/index-browser.mjs.map +1 -1
- package/dist/browser/index.mjs.map +1 -1
- package/dist/browser/worker/subtleHash-bundle.mjs +2 -2
- package/dist/browser/worker/wasmHash-bundle.mjs +11380 -3806
- package/dist/neutral/ObjectHasher.d.ts +0 -5
- package/dist/neutral/ObjectHasher.d.ts.map +1 -1
- package/dist/neutral/index.mjs.map +1 -1
- package/dist/node/ObjectHasher.d.ts +0 -5
- package/dist/node/ObjectHasher.d.ts.map +1 -1
- package/dist/node/index.mjs.map +1 -1
- package/package.json +21 -17
- package/src/ObjectHasher.ts +0 -5
- package/src/spec/ObjectHasher.bigobj-parallel.perf.spec.ts +98 -0
- package/src/spec/ObjectHasher.bigobj.perf.spec.ts +148 -0
- package/src/spec/ObjectHasher.spec.ts +140 -0
- package/src/spec/ObjectHasher.subtle.perf.spec.ts +59 -0
- package/src/spec/ObjectHasher.wasm-subtle.perf.spec.ts +75 -0
- package/src/spec/ObjectHasher.wasm.perf.spec.ts +60 -0
- package/src/spec/removeEmptyFields.spec.ts +31 -0
- package/src/types/global.d.ts +5 -0
- package/xy.config.ts +0 -9
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import '@xylabs/vitest-extended'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
beforeAll, describe, expect, test,
|
|
5
|
+
} from 'vitest'
|
|
6
|
+
|
|
7
|
+
import { NodeObjectHasher as ObjectHasher } from '../NodeObjectHasher.ts'
|
|
8
|
+
|
|
9
|
+
const perfIterations = 50
|
|
10
|
+
|
|
11
|
+
describe('Hasher', () => {
|
|
12
|
+
const testObject = {
|
|
13
|
+
testArray: [1, 2, 3],
|
|
14
|
+
testBoolean: true,
|
|
15
|
+
testNull: null,
|
|
16
|
+
testNullObject: { t: null, x: undefined },
|
|
17
|
+
testNumber: 5,
|
|
18
|
+
testObject: { t: 1 },
|
|
19
|
+
testSomeNullObject: {
|
|
20
|
+
s: 1, t: null, x: undefined,
|
|
21
|
+
},
|
|
22
|
+
testString: 'hello there. this is a pretty long string. what do you think?',
|
|
23
|
+
testUndefined: undefined,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
beforeAll(async () => {
|
|
27
|
+
await ObjectHasher.wasmInitialized
|
|
28
|
+
})
|
|
29
|
+
test('wasm vs js (compatibility-sync)', async () => {
|
|
30
|
+
ObjectHasher.warnIfUsingJsHash = false
|
|
31
|
+
ObjectHasher.allowSubtle = false
|
|
32
|
+
ObjectHasher.wasmSupport.allowWasm = false
|
|
33
|
+
const jsHash = await ObjectHasher.hash(testObject)
|
|
34
|
+
ObjectHasher.wasmSupport.allowWasm = true
|
|
35
|
+
const wasmHash = await ObjectHasher.hash(testObject)
|
|
36
|
+
expect(jsHash).toEqual(wasmHash)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test('wasm vs js (compatibility-async)', async () => {
|
|
40
|
+
ObjectHasher.warnIfUsingJsHash = false
|
|
41
|
+
ObjectHasher.allowSubtle = false
|
|
42
|
+
ObjectHasher.wasmSupport.allowWasm = false
|
|
43
|
+
const jsHash = await ObjectHasher.hash(testObject)
|
|
44
|
+
ObjectHasher.wasmSupport.allowWasm = true
|
|
45
|
+
const wasmHash = await ObjectHasher.hash(testObject)
|
|
46
|
+
expect(jsHash).toEqual(wasmHash)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('subtle vs js (compatibility-async)', async () => {
|
|
50
|
+
ObjectHasher.warnIfUsingJsHash = false
|
|
51
|
+
ObjectHasher.allowSubtle = false
|
|
52
|
+
ObjectHasher.wasmSupport.allowWasm = false
|
|
53
|
+
const jsHash = await ObjectHasher.hash(testObject)
|
|
54
|
+
ObjectHasher.allowSubtle = true
|
|
55
|
+
const subtleHash = await ObjectHasher.hash(testObject)
|
|
56
|
+
expect(jsHash).toEqual(subtleHash)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test('wasm vs js (performance-serial)', async () => {
|
|
60
|
+
ObjectHasher.warnIfUsingJsHash = false
|
|
61
|
+
ObjectHasher.allowSubtle = false
|
|
62
|
+
ObjectHasher.wasmSupport.allowWasm = false
|
|
63
|
+
const jsHashStart = Date.now()
|
|
64
|
+
for (let x = 0; x < perfIterations; x++) {
|
|
65
|
+
await ObjectHasher.hash({ ...testObject, nonce: x })
|
|
66
|
+
}
|
|
67
|
+
const jsHashDuration = Date.now() - jsHashStart
|
|
68
|
+
ObjectHasher.wasmSupport.allowWasm = true
|
|
69
|
+
const wasmHashStart = Date.now()
|
|
70
|
+
for (let x = 0; x < perfIterations; x++) {
|
|
71
|
+
await ObjectHasher.hash({ ...testObject, nonce: x })
|
|
72
|
+
}
|
|
73
|
+
const wasmHashDuration = Date.now() - wasmHashStart
|
|
74
|
+
expect(wasmHashDuration).toBeDefined()
|
|
75
|
+
expect(jsHashDuration).toBeDefined()
|
|
76
|
+
console.log(
|
|
77
|
+
`Wasm (serial) is ${jsHashDuration - wasmHashDuration}ms (${((1 - wasmHashDuration / jsHashDuration) * 100).toPrecision(
|
|
78
|
+
2,
|
|
79
|
+
)}%) faster [${wasmHashDuration}ms vs ${jsHashDuration}ms ]`,
|
|
80
|
+
)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
test.skip('wasm vs js (performance-parallel)', async () => {
|
|
84
|
+
ObjectHasher.warnIfUsingJsHash = false
|
|
85
|
+
ObjectHasher.allowSubtle = false
|
|
86
|
+
ObjectHasher.wasmSupport.allowWasm = false
|
|
87
|
+
const jsTestObjects: ObjectHasher[] = []
|
|
88
|
+
for (let x = 0; x < perfIterations; x++) {
|
|
89
|
+
jsTestObjects.push(new ObjectHasher({ ...testObject, nonce: x }))
|
|
90
|
+
}
|
|
91
|
+
const jsHashStart = Date.now()
|
|
92
|
+
await Promise.all(jsTestObjects.map(obj => obj.hash()))
|
|
93
|
+
const jsHashDuration = Date.now() - jsHashStart
|
|
94
|
+
ObjectHasher.allowSubtle = false
|
|
95
|
+
ObjectHasher.wasmSupport.allowWasm = true
|
|
96
|
+
const wasmTestObjects: ObjectHasher[] = []
|
|
97
|
+
for (let x = 0; x < perfIterations; x++) {
|
|
98
|
+
wasmTestObjects.push(new ObjectHasher({ ...testObject, nonce: x }))
|
|
99
|
+
}
|
|
100
|
+
const wasmHashStart = Date.now()
|
|
101
|
+
await Promise.all(wasmTestObjects.map(obj => obj.hash()))
|
|
102
|
+
const wasmHashDuration = Date.now() - wasmHashStart
|
|
103
|
+
expect(wasmHashDuration).toBeDefined()
|
|
104
|
+
expect(jsHashDuration).toBeDefined()
|
|
105
|
+
console.log(
|
|
106
|
+
`Wasm (parallel) is ${jsHashDuration - wasmHashDuration}ms (${((1 - wasmHashDuration / jsHashDuration) * 100).toPrecision(
|
|
107
|
+
2,
|
|
108
|
+
)}%) faster than js [${wasmHashDuration}ms vs ${jsHashDuration}ms ]`,
|
|
109
|
+
)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
test('subtle vs js (performance-parallel)', async () => {
|
|
113
|
+
ObjectHasher.warnIfUsingJsHash = false
|
|
114
|
+
ObjectHasher.allowSubtle = false
|
|
115
|
+
ObjectHasher.wasmSupport.allowWasm = false
|
|
116
|
+
const jsTestObjects: ObjectHasher[] = []
|
|
117
|
+
for (let x = 0; x < perfIterations; x++) {
|
|
118
|
+
jsTestObjects.push(new ObjectHasher({ ...testObject, nonce: x }))
|
|
119
|
+
}
|
|
120
|
+
const jsHashStart = Date.now()
|
|
121
|
+
await Promise.all(jsTestObjects.map(obj => obj.hash()))
|
|
122
|
+
const jsHashDuration = Date.now() - jsHashStart
|
|
123
|
+
ObjectHasher.allowSubtle = true
|
|
124
|
+
ObjectHasher.wasmSupport.allowWasm = false
|
|
125
|
+
const subtleTestObjects: ObjectHasher[] = []
|
|
126
|
+
for (let x = 0; x < perfIterations; x++) {
|
|
127
|
+
subtleTestObjects.push(new ObjectHasher({ ...testObject, nonce: x }))
|
|
128
|
+
}
|
|
129
|
+
const subtleHashStart = Date.now()
|
|
130
|
+
await Promise.all(subtleTestObjects.map(obj => obj.hash()))
|
|
131
|
+
const subtleHashDuration = Date.now() - subtleHashStart
|
|
132
|
+
expect(subtleHashDuration).toBeDefined()
|
|
133
|
+
expect(jsHashDuration).toBeDefined()
|
|
134
|
+
console.log(
|
|
135
|
+
`Subtle (parallel) is ${jsHashDuration - subtleHashDuration}ms (${((1 - subtleHashDuration / jsHashDuration) * 100).toPrecision(
|
|
136
|
+
2,
|
|
137
|
+
)}%) faster than js [${subtleHashDuration}ms vs ${jsHashDuration}ms ]`,
|
|
138
|
+
)
|
|
139
|
+
})
|
|
140
|
+
})
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { NodeObjectHasher as ObjectHasher } from '../NodeObjectHasher.ts'
|
|
2
|
+
|
|
3
|
+
const perfIterations = 1000
|
|
4
|
+
|
|
5
|
+
import '@xylabs/vitest-extended'
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
beforeAll, describe, expect, test,
|
|
9
|
+
} from 'vitest'
|
|
10
|
+
|
|
11
|
+
describe('Hasher - Subtle performance', () => {
|
|
12
|
+
const testObject = {
|
|
13
|
+
testArray: [1, 2, 3],
|
|
14
|
+
testBoolean: true,
|
|
15
|
+
testNull: null,
|
|
16
|
+
testNullObject: { t: null, x: undefined },
|
|
17
|
+
testNumber: 5,
|
|
18
|
+
testObject: { t: 1 },
|
|
19
|
+
testSomeNullObject: {
|
|
20
|
+
s: 1, t: null, x: undefined,
|
|
21
|
+
},
|
|
22
|
+
testString: 'hello there. this is a pretty long string. what do you think?',
|
|
23
|
+
testUndefined: undefined,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
beforeAll(async () => {
|
|
27
|
+
await ObjectHasher.wasmInitialized
|
|
28
|
+
})
|
|
29
|
+
test('subtle vs js (performance-parallel)', async () => {
|
|
30
|
+
ObjectHasher.warnIfUsingJsHash = false
|
|
31
|
+
ObjectHasher.allowSubtle = false
|
|
32
|
+
ObjectHasher.wasmSupport.allowWasm = false
|
|
33
|
+
const jsTestObjects: ObjectHasher[] = []
|
|
34
|
+
for (let x = 0; x < perfIterations; x++) {
|
|
35
|
+
jsTestObjects.push(new ObjectHasher({ ...testObject, nonce: x }))
|
|
36
|
+
}
|
|
37
|
+
const jsHashStart = Date.now()
|
|
38
|
+
await Promise.all(jsTestObjects.map(obj => obj.hash()))
|
|
39
|
+
const jsHashDuration = Date.now() - jsHashStart
|
|
40
|
+
|
|
41
|
+
ObjectHasher.warnIfUsingJsHash = true
|
|
42
|
+
ObjectHasher.allowSubtle = true
|
|
43
|
+
ObjectHasher.wasmSupport.allowWasm = false
|
|
44
|
+
const subtleTestObjects: ObjectHasher[] = []
|
|
45
|
+
for (let x = 0; x < perfIterations; x++) {
|
|
46
|
+
subtleTestObjects.push(new ObjectHasher({ ...testObject, nonce: x }))
|
|
47
|
+
}
|
|
48
|
+
const subtleHashStart = Date.now()
|
|
49
|
+
await Promise.all(subtleTestObjects.map(obj => obj.hash()))
|
|
50
|
+
const subtleHashDuration = Date.now() - subtleHashStart
|
|
51
|
+
expect(subtleHashDuration).toBeDefined()
|
|
52
|
+
expect(jsHashDuration).toBeDefined()
|
|
53
|
+
console.log(
|
|
54
|
+
`Subtle (parallel) is ${jsHashDuration - subtleHashDuration}ms (${((1 - subtleHashDuration / jsHashDuration) * 100).toPrecision(
|
|
55
|
+
2,
|
|
56
|
+
)}%) faster than js [${subtleHashDuration}ms vs ${jsHashDuration}ms ]`,
|
|
57
|
+
)
|
|
58
|
+
})
|
|
59
|
+
})
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import '@xylabs/vitest-extended'
|
|
2
|
+
|
|
3
|
+
import { delay } from '@xylabs/delay'
|
|
4
|
+
import type { AnyObject } from '@xylabs/object'
|
|
5
|
+
import {
|
|
6
|
+
beforeAll,
|
|
7
|
+
describe, expect, test,
|
|
8
|
+
} from 'vitest'
|
|
9
|
+
|
|
10
|
+
import { NodeObjectHasher as ObjectHasher } from '../NodeObjectHasher.ts'
|
|
11
|
+
|
|
12
|
+
const perfIterations = 1000
|
|
13
|
+
|
|
14
|
+
describe('Hasher', () => {
|
|
15
|
+
const testObject = () => ({
|
|
16
|
+
salt: `${Date.now()}-${Math.floor(Math.random() * 1000)}`,
|
|
17
|
+
testArray: [1, 2, 3],
|
|
18
|
+
testBoolean: true,
|
|
19
|
+
testNull: null,
|
|
20
|
+
testNullObject: { t: null, x: undefined },
|
|
21
|
+
testNumber: 5,
|
|
22
|
+
testObject: { t: 1 },
|
|
23
|
+
testSomeNullObject: {
|
|
24
|
+
s: 1, t: null, x: undefined,
|
|
25
|
+
},
|
|
26
|
+
testString: 'hello there. this is a pretty long string. what do you think?',
|
|
27
|
+
testUndefined: undefined,
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
beforeAll(async () => {
|
|
31
|
+
await ObjectHasher.wasmInitialized
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('subtle vs wasm (performance-parallel)', async () => {
|
|
35
|
+
const testObjects: AnyObject[] = []
|
|
36
|
+
for (let x = 0; x < perfIterations; x++) {
|
|
37
|
+
testObjects.push(testObject())
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const subtleHashDuration = await (async () => {
|
|
41
|
+
ObjectHasher.allowSubtle = true
|
|
42
|
+
ObjectHasher.wasmSupport.allowWasm = false
|
|
43
|
+
// prime it
|
|
44
|
+
await Promise.all([{ length: 8 }].map(async (_, index) => await ObjectHasher.hash(testObjects[index])))
|
|
45
|
+
const subtleHashStart = Date.now()
|
|
46
|
+
const subtleResult = await Promise.all(testObjects.map(obj => ObjectHasher.hash(obj)))
|
|
47
|
+
console.log(`subtleResult count: ${subtleResult.length}`)
|
|
48
|
+
return Date.now() - subtleHashStart
|
|
49
|
+
})()
|
|
50
|
+
|
|
51
|
+
// allow for cleanup
|
|
52
|
+
await delay(2000)
|
|
53
|
+
|
|
54
|
+
const wasmHashDuration = await (async () => {
|
|
55
|
+
ObjectHasher.allowSubtle = false
|
|
56
|
+
ObjectHasher.wasmSupport.allowWasm = true
|
|
57
|
+
// prime it
|
|
58
|
+
await Promise.all([{ length: 8 }].map(async (_, index) => await ObjectHasher.hash(testObjects[index])))
|
|
59
|
+
const wasmHashStart = Date.now()
|
|
60
|
+
const wasmResult = await Promise.all(testObjects.map(obj => ObjectHasher.hash(obj)))
|
|
61
|
+
console.log(`wasmResult count: ${wasmResult.length}`)
|
|
62
|
+
return Date.now() - wasmHashStart
|
|
63
|
+
})()
|
|
64
|
+
|
|
65
|
+
expect(wasmHashDuration).toBeDefined()
|
|
66
|
+
expect(subtleHashDuration).toBeDefined()
|
|
67
|
+
console.log(
|
|
68
|
+
`Subtle (parallel) is ${wasmHashDuration - subtleHashDuration}ms (${((1 - subtleHashDuration / wasmHashDuration) * 100).toPrecision(
|
|
69
|
+
2,
|
|
70
|
+
)}%) faster than Wasm [${subtleHashDuration}ms vs ${wasmHashDuration}ms ]`,
|
|
71
|
+
)
|
|
72
|
+
console.log(`Wasm Average: ${(wasmHashDuration / perfIterations).toPrecision(2)}ms`)
|
|
73
|
+
console.log(`Subtle Average: ${(subtleHashDuration / perfIterations).toPrecision(2)}ms`)
|
|
74
|
+
})
|
|
75
|
+
})
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import '@xylabs/vitest-extended'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
beforeAll,
|
|
5
|
+
describe, expect, test,
|
|
6
|
+
} from 'vitest'
|
|
7
|
+
|
|
8
|
+
import { NodeObjectHasher as ObjectHasher } from '../NodeObjectHasher.ts'
|
|
9
|
+
|
|
10
|
+
const perfIterations = 1000
|
|
11
|
+
|
|
12
|
+
describe('Hasher', () => {
|
|
13
|
+
const testObject = {
|
|
14
|
+
testArray: [1, 2, 3],
|
|
15
|
+
testBoolean: true,
|
|
16
|
+
testNull: null,
|
|
17
|
+
testNullObject: { t: null, x: undefined },
|
|
18
|
+
testNumber: 5,
|
|
19
|
+
testObject: { t: 1 },
|
|
20
|
+
testSomeNullObject: {
|
|
21
|
+
s: 1, t: null, x: undefined,
|
|
22
|
+
},
|
|
23
|
+
testString: 'hello there. this is a pretty long string. what do you think?',
|
|
24
|
+
testUndefined: undefined,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
beforeAll(async () => {
|
|
28
|
+
await ObjectHasher.wasmInitialized
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test('wasm vs js (performance-parallel)', async () => {
|
|
32
|
+
ObjectHasher.warnIfUsingJsHash = false
|
|
33
|
+
ObjectHasher.allowSubtle = false
|
|
34
|
+
ObjectHasher.wasmSupport.allowWasm = false
|
|
35
|
+
const jsTestObjects: ObjectHasher[] = []
|
|
36
|
+
for (let x = 0; x < perfIterations; x++) {
|
|
37
|
+
jsTestObjects.push(new ObjectHasher({ ...testObject, nonce: x }))
|
|
38
|
+
}
|
|
39
|
+
const jsHashStart = Date.now()
|
|
40
|
+
await Promise.all(jsTestObjects.map(obj => obj.hash()))
|
|
41
|
+
const jsHashDuration = Date.now() - jsHashStart
|
|
42
|
+
ObjectHasher.warnIfUsingJsHash = true
|
|
43
|
+
ObjectHasher.allowSubtle = false
|
|
44
|
+
ObjectHasher.wasmSupport.allowWasm = true
|
|
45
|
+
const wasmTestObjects: ObjectHasher[] = []
|
|
46
|
+
for (let x = 0; x < perfIterations; x++) {
|
|
47
|
+
wasmTestObjects.push(new ObjectHasher({ ...testObject, nonce: x }))
|
|
48
|
+
}
|
|
49
|
+
const wasmHashStart = Date.now()
|
|
50
|
+
await Promise.all(wasmTestObjects.map(obj => obj.hash()))
|
|
51
|
+
const wasmHashDuration = Date.now() - wasmHashStart
|
|
52
|
+
expect(wasmHashDuration).toBeDefined()
|
|
53
|
+
expect(jsHashDuration).toBeDefined()
|
|
54
|
+
console.log(
|
|
55
|
+
`Wasm (parallel) is ${jsHashDuration - wasmHashDuration}ms (${((1 - wasmHashDuration / jsHashDuration) * 100).toPrecision(
|
|
56
|
+
2,
|
|
57
|
+
)}%) faster than js [${wasmHashDuration}ms vs ${jsHashDuration}ms ]`,
|
|
58
|
+
)
|
|
59
|
+
})
|
|
60
|
+
})
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import '@xylabs/vitest-extended'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
describe, expect, test,
|
|
5
|
+
} from 'vitest'
|
|
6
|
+
|
|
7
|
+
import { removeEmptyFields } from '../removeEmptyFields.ts'
|
|
8
|
+
|
|
9
|
+
describe('removeEmptyFields', () => {
|
|
10
|
+
test('deep', () => {
|
|
11
|
+
const testObject = {
|
|
12
|
+
testArray: [1, 2, 3],
|
|
13
|
+
testBoolean: true,
|
|
14
|
+
testNull: null,
|
|
15
|
+
testNullObject: { t: null, x: undefined },
|
|
16
|
+
testNumber: 5,
|
|
17
|
+
testObject: { t: 1 },
|
|
18
|
+
testSomeNullObject: {
|
|
19
|
+
s: 1, t: null, x: undefined,
|
|
20
|
+
},
|
|
21
|
+
testString: 'hi',
|
|
22
|
+
testUndefined: undefined,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const result = removeEmptyFields(testObject)
|
|
26
|
+
|
|
27
|
+
expect(Object.keys(result).length).toBe(8)
|
|
28
|
+
expect(Object.keys(result.testSomeNullObject as object).length).toBe(2)
|
|
29
|
+
expect(Object.keys(result.testNullObject as object).length).toBe(1)
|
|
30
|
+
})
|
|
31
|
+
})
|
package/xy.config.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { XyTsupConfig } from '@xylabs/ts-scripts-yarn3'
|
|
2
|
-
const config: XyTsupConfig = {
|
|
3
|
-
compile: {
|
|
4
|
-
browser: { src: { entry: ['index-browser.ts', 'worker/subtleHash.ts', 'worker/wasmHash.ts'] } },
|
|
5
|
-
node: { src: { entry: ['index.ts', 'worker/subtleHashNode.ts', 'worker/wasmHashNode.ts'] } },
|
|
6
|
-
},
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export default config
|