-
Notifications
You must be signed in to change notification settings - Fork 904
Expand file tree
/
Copy pathJavaScriptEnginePrecompilationUtils.cs
More file actions
117 lines (104 loc) · 4.31 KB
/
Copy pathJavaScriptEnginePrecompilationUtils.cs
File metadata and controls
117 lines (104 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System;
using System.Reflection;
using JavaScriptEngineSwitcher.Core;
using React.Exceptions;
namespace React
{
/// <summary>
/// Helper methods for pre-compilation features of the JavaScript engine environment.
/// </summary>
public static class JavaScriptEnginePrecompilationUtils
{
/// <summary>
/// Cache key for the script resource pre-compilation
/// </summary>
private const string PRECOMPILED_JS_RESOURCE_CACHE_KEY = "PRECOMPILED_JS_RESOURCE_{0}";
/// <summary>
/// Cache key for the script file pre-compilation
/// </summary>
private const string PRECOMPILED_JS_FILE_CACHE_KEY = "PRECOMPILED_JS_FILE_{0}";
/// <summary>
/// Value that indicates whether a cache entry, that contains a precompiled script, should be
/// evicted if it has not been accessed in a given span of time
/// </summary>
private readonly static TimeSpan PRECOMPILED_JS_CACHE_ENTRY_SLIDING_EXPIRATION = TimeSpan.FromMinutes(30);
/// <summary>
/// Tries to execute a code from JavaScript file with pre-compilation.
/// </summary>
/// <param name="engine">Engine to execute code from JavaScript file with pre-compilation</param>
/// <param name="cache">Cache used for storing the pre-compiled scripts</param>
/// <param name="fileSystem">File system wrapper</param>
/// <param name="path">Path to the JavaScript file</param>
/// <param name="scriptLoader">Delegate that loads a code from specified JavaScript file</param>
/// <returns>true if can perform a script pre-compilation; otherwise, false.</returns>
public static bool TryExecuteFileWithPrecompilation(this IJsEngine engine, ICache cache,
IFileSystem fileSystem, string path, Func<string, string> scriptLoader = null)
{
EnsurePrecompilationAvailability(engine, cache);
var cacheKey = string.Format(PRECOMPILED_JS_FILE_CACHE_KEY, path);
var precompiledScript = cache.Get<IPrecompiledScript>(cacheKey);
if (precompiledScript == null)
{
var contents = scriptLoader != null ? scriptLoader(path) : fileSystem.ReadAsString(path);
precompiledScript = engine.Precompile(contents, path);
var fullPath = fileSystem.MapPath(path);
cache.Set(
cacheKey,
precompiledScript,
slidingExpiration: PRECOMPILED_JS_CACHE_ENTRY_SLIDING_EXPIRATION,
cacheDependencyFiles: new[] { fullPath }
);
}
engine.Execute(precompiledScript);
return true;
}
/// <summary>
/// Tries to execute a code from embedded JavaScript resource with pre-compilation.
/// </summary>
/// <param name="engine">Engine to execute a code from embedded JavaScript resource with pre-compilation</param>
/// <param name="cache">Cache used for storing the pre-compiled scripts</param>
/// <param name="resourceName">The case-sensitive resource name</param>
/// <param name="assembly">The assembly, which contains the embedded resource</param>
/// <returns>true if can perform a script pre-compilation; otherwise, false.</returns>
public static bool TryExecuteResourceWithPrecompilation(this IJsEngine engine, ICache cache,
string resourceName, Assembly assembly)
{
EnsurePrecompilationAvailability(engine, cache);
var cacheKey = string.Format(PRECOMPILED_JS_RESOURCE_CACHE_KEY, resourceName);
var precompiledScript = cache.Get<IPrecompiledScript>(cacheKey);
if (precompiledScript == null)
{
precompiledScript = engine.PrecompileResource(resourceName, assembly);
cache.Set(
cacheKey,
precompiledScript,
slidingExpiration: PRECOMPILED_JS_CACHE_ENTRY_SLIDING_EXPIRATION
);
}
engine.Execute(precompiledScript);
return true;
}
/// <summary>
/// Ensures that the script pre-compilation is available.
/// </summary>
/// <param name="engine">Instance of the JavaScript engine</param>
/// <param name="cache">Cache used for storing the pre-compiled scripts</param>
private static void EnsurePrecompilationAvailability(IJsEngine engine, ICache cache)
{
if (!engine.SupportsScriptPrecompilation)
{
throw new ReactScriptPrecompilationNotAvailableException(string.Format(
"The {0} version {1} does not support the script pre-compilation.",
engine.Name,
engine.Version
));
}
if (cache is NullCache)
{
throw new ReactScriptPrecompilationNotAvailableException(string.Format(
"Usage of the script pre-compilation without caching does not make sense."
));
}
}
}
}