mirror of
https://github.com/atom/atom.git
synced 2026-01-24 06:18:03 -05:00
107 lines
2.9 KiB
CoffeeScript
107 lines
2.9 KiB
CoffeeScript
###
|
|
Cache for source code transpiled by TypeScript.
|
|
|
|
Inspired by https://github.com/atom/atom/blob/7a719d585db96ff7d2977db9067e1d9d4d0adf1a/src/babel.coffee
|
|
###
|
|
|
|
crypto = require 'crypto'
|
|
fs = require 'fs-plus'
|
|
path = require 'path'
|
|
tss = null # Defer until used
|
|
|
|
stats =
|
|
hits: 0
|
|
misses: 0
|
|
|
|
defaultOptions =
|
|
target: 1 # ES5
|
|
module: 'commonjs'
|
|
sourceMap: true
|
|
|
|
createTypeScriptVersionAndOptionsDigest = (version, options) ->
|
|
shasum = crypto.createHash('sha1')
|
|
# Include the version of typescript in the hash.
|
|
shasum.update('typescript', 'utf8')
|
|
shasum.update('\0', 'utf8')
|
|
shasum.update(version, 'utf8')
|
|
shasum.update('\0', 'utf8')
|
|
shasum.update(JSON.stringify(options))
|
|
shasum.digest('hex')
|
|
|
|
cacheDir = null
|
|
jsCacheDir = null
|
|
|
|
getCachePath = (sourceCode) ->
|
|
digest = crypto.createHash('sha1').update(sourceCode, 'utf8').digest('hex')
|
|
|
|
unless jsCacheDir?
|
|
tssVersion = require('typescript-simple/package.json').version
|
|
jsCacheDir = path.join(cacheDir, createTypeScriptVersionAndOptionsDigest(tssVersion, defaultOptions))
|
|
|
|
path.join(jsCacheDir, "#{digest}.js")
|
|
|
|
getCachedJavaScript = (cachePath) ->
|
|
if fs.isFileSync(cachePath)
|
|
try
|
|
cachedJavaScript = fs.readFileSync(cachePath, 'utf8')
|
|
stats.hits++
|
|
return cachedJavaScript
|
|
null
|
|
|
|
# Returns the TypeScript options that should be used to transpile filePath.
|
|
createOptions = (filePath) ->
|
|
options = filename: filePath
|
|
for key, value of defaultOptions
|
|
options[key] = value
|
|
options
|
|
|
|
transpile = (sourceCode, filePath, cachePath) ->
|
|
options = createOptions(filePath)
|
|
unless tss?
|
|
{TypeScriptSimple} = require 'typescript-simple'
|
|
tss = new TypeScriptSimple(options, false)
|
|
js = tss.compile(sourceCode, filePath)
|
|
stats.misses++
|
|
|
|
try
|
|
fs.writeFileSync(cachePath, js)
|
|
|
|
js
|
|
|
|
# Function that obeys the contract of an entry in the require.extensions map.
|
|
# Returns the transpiled version of the JavaScript code at filePath, which is
|
|
# either generated on the fly or pulled from cache.
|
|
loadFile = (module, filePath) ->
|
|
sourceCode = fs.readFileSync(filePath, 'utf8')
|
|
cachePath = getCachePath(sourceCode)
|
|
js = getCachedJavaScript(cachePath) ? transpile(sourceCode, filePath, cachePath)
|
|
module._compile(js, filePath)
|
|
|
|
register = ->
|
|
Object.defineProperty(require.extensions, '.ts', {
|
|
enumerable: true
|
|
writable: false
|
|
value: loadFile
|
|
})
|
|
|
|
setCacheDirectory = (newCacheDir) ->
|
|
if cacheDir isnt newCacheDir
|
|
cacheDir = newCacheDir
|
|
jsCacheDir = null
|
|
|
|
module.exports =
|
|
register: register
|
|
setCacheDirectory: setCacheDirectory
|
|
getCacheMisses: -> stats.misses
|
|
getCacheHits: -> stats.hits
|
|
|
|
# Visible for testing.
|
|
createTypeScriptVersionAndOptionsDigest: createTypeScriptVersionAndOptionsDigest
|
|
|
|
addPathToCache: (filePath) ->
|
|
return if path.extname(filePath) isnt '.ts'
|
|
|
|
sourceCode = fs.readFileSync(filePath, 'utf8')
|
|
cachePath = getCachePath(sourceCode)
|
|
transpile(sourceCode, filePath, cachePath)
|