UNPKG

2.66 kBJavaScriptView Raw
1const carmi = require('./index')
2const path = require('path')
3const fs = require('fs-extra')
4const {isUpToDate, getDependenciesHashes, analyzeDependencies} = require('./src/analyze-dependencies')
5const getCacheFilePath = require('./src/get-cache-file-path')
6const wrapModule = require('./src/wrap-module')
7const base64ArrayBuffer = require('./bytecode/base64-arraybuffer')
8const {CACHE_SCENARIOS} = require('./src/cache-scenarios')
9const {defaults} = require('lodash')
10
11require('@babel/register')({
12 rootMode: 'upward',
13 extensions: ['.ts', '.js'],
14 ignore: [/node_modules/],
15 envName: 'carmi'
16})
17
18module.exports = function processCarmi(options) {
19 options = defaults(options, {
20 compiler: 'optimizing',
21 debug: false,
22 'type-check': false,
23 format: 'iife',
24 name: 'model',
25 prettier: false,
26 'no-cache': false,
27 'cache-scenario': CACHE_SCENARIOS.mtime,
28 'no-coverage': false,
29 ast: false
30 })
31
32 const statsFilePath = getCacheFilePath({
33 path: options.source
34 })
35
36 const dependencies = analyzeDependencies(options.source, statsFilePath)
37 const encoding = options.compiler === 'bytecode' ? null : 'utf-8'
38
39 const dependenciesHashes =
40 options['cache-scenario'] === CACHE_SCENARIOS.gitHash ? getDependenciesHashes(dependencies) : null
41
42 const cacheFilePath = getCacheFilePath({
43 path: options.source,
44 debug: options.debug,
45 format: options.format,
46 prettier: options.prettier,
47 dependenciesHashes,
48 name: options.name
49 })
50
51 fs.outputJSONSync(statsFilePath, dependencies)
52
53 let code
54
55 // We are using fallback to mtime check if scenario is `git-hash`, but getting hashes was resulted in error.
56 const upToDate = Boolean(dependenciesHashes) || isUpToDate(dependencies, cacheFilePath)
57 const useCache = !options['no-cache'] && fs.existsSync(cacheFilePath) && upToDate
58
59 if (useCache) {
60 // return from cache
61 code = fs.readFileSync(cacheFilePath, encoding)
62 } else {
63 // run carmi and generate cache
64 let model
65
66 try {
67 model = require(options.source)
68 } catch (e) {
69 console.error(`failed to require ${options.source} ${e.stack}`)
70 throw e
71 }
72
73 code = carmi.compile(model, options)
74 }
75
76 if (options['no-coverage'] && typeof code === 'string') {
77 code = `/* istanbul ignore file */
78 ${code}`
79 }
80
81 if (!options['no-cache']) {
82 fs.outputFileSync(cacheFilePath, code, encoding)
83 }
84
85 if (typeof code !== 'string' && options.format !== 'binary') {
86 code = wrapModule(
87 options.format,
88 `require('carmi/bytecode/carmi-instance')('${base64ArrayBuffer.encode(code)}')`,
89 name
90 )
91 }
92
93 if (options['no-coverage'] && typeof code === 'string') {
94 code = `/* istanbul ignore file */
95 ${code}`
96 }
97
98 return {code, dependencies};
99}