Compare commits

...

3 Commits

Author SHA1 Message Date
autofix-ci[bot]
e5b91da41e [autofix.ci] apply automated fixes 2024-02-04 15:28:02 +00:00
Jarred Sumner
f7333c1220 Update ModuleLoader.cpp 2024-02-04 07:19:17 -08:00
Jarred Sumner
d28344d2d4 Support watchedFiles in Bun.plugin 2024-02-04 07:17:51 -08:00
6 changed files with 85 additions and 3 deletions

View File

@@ -1,6 +1,9 @@
#include "root.h"
#include "headers-handwritten.h"
#include "JavaScriptCore/JSArray.h"
#include "JavaScriptCore/JSCast.h"
#include "ModuleLoader.h"
#include "ZigGlobalObject.h"
@@ -40,6 +43,15 @@ namespace Bun {
using namespace JSC;
using namespace Zig;
using namespace WebCore;
extern "C" bool Bun__isAbsolutePath(BunString* path);
enum class HotReload : uint8_t {
none = 0,
hot = 1,
watch = 2
};
extern "C" HotReload Bun__watchMode;
static OnLoadResult handleOnLoadResultNotPromise(Zig::GlobalObject* globalObject, JSC::JSValue objectValue, bool wasModuleMock = false);
@@ -107,7 +119,7 @@ static JSC::SyntheticSourceProvider::SyntheticSourceGenerator generateInternalMo
};
}
static OnLoadResult handleOnLoadObjectResult(Zig::GlobalObject* globalObject, JSC::JSObject* object)
static OnLoadResult handleOnLoadObjectResult(Zig::GlobalObject* globalObject, JSC::JSObject* object, BunString watchedFile)
{
OnLoadResult result {};
result.type = OnLoadResultTypeObject;
@@ -242,6 +254,46 @@ OnLoadResult handleOnLoadResultNotPromise(Zig::GlobalObject* globalObject, JSC::
result.value.sourceText.value = JSValue {};
result.value.sourceText.string = {};
if (Bun__watchMode != HotReload::none) {
if (JSC::JSValue watchedFilePathsValue = object->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "watchedFilePaths"_s))) {
if (!watchedFilePathsValue.isUndefinedOrNull()) {
if (!isJSArray(watchedFilePathsValue)) {
throwException(globalObject, scope, createError(globalObject, "Expected watchedFilePaths to be an array of strings"_s));
result.value.error = scope.exception();
return result;
}
JSC::JSArray* watchedFilePathsObject = jsCast<JSArray*>(watchedFilePathsValue);
const auto length = watchedFilePathsObject->length();
if (length > 0) {
JSValue first = watchedFilePathsObject->getIndex(globalObject, 0);
if (first.isString()) {
auto watchedFile = first.toWTFString(globalObject);
if (watchedFile.isEmpty()) {
throwException(globalObject, scope, createError(globalObject, "Expected watchedFilePaths string to not be empty"_s));
result.value.error = scope.exception();
return result;
}
auto str = Bun::toStringRef(globalObject, first);
if (!Bun__isAbsolutePath(&str)) {
throwException(globalObject, scope, createError(globalObject, "Expected watchedFilePaths string to be an absolute path"_s));
str.deref();
result.value.error = scope.exception();
return result;
}
result.value.sourceText.watchedFilePath = str;
} else {
throwException(globalObject, scope, createError(globalObject, "Expected watchedFilePaths to be an array of strings"_s));
result.value.error = scope.exception();
return result;
}
}
}
}
}
if (JSC::JSValue contentsValue = object->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "contents"_s))) {
if (contentsValue.isString()) {
if (JSC::JSString* contentsJSString = contentsValue.toStringOrNull(globalObject)) {
@@ -256,7 +308,9 @@ OnLoadResult handleOnLoadResultNotPromise(Zig::GlobalObject* globalObject, JSC::
if (UNLIKELY(result.value.sourceText.value.isEmpty())) {
throwException(globalObject, scope, createError(globalObject, "Expected \"contents\" to be a string or an ArrayBufferView"_s));
result.value.sourceText.watchedFilePath.deref();
result.value.error = scope.exception();
return result;
}
@@ -331,7 +385,14 @@ static JSValue handleVirtualModuleResult(
switch (onLoadResult.type) {
case OnLoadResultTypeCode: {
Bun__transpileVirtualModule(globalObject, specifier, referrer, &onLoadResult.value.sourceText.string, onLoadResult.value.sourceText.loader, res);
Bun__transpileVirtualModule(
globalObject,
specifier,
referrer,
&onLoadResult.value.sourceText.string,
onLoadResult.value.sourceText.loader,
&onLoadResult.value.sourceText.watchedFilePath,
res);
if (!res->success) {
return reject(JSValue::decode(reinterpret_cast<EncodedJSValue>(res->result.err.ptr)));
}

View File

@@ -1,3 +1,4 @@
#include "helpers.h"
#include "root.h"
#include "headers-handwritten.h"
@@ -30,6 +31,7 @@ struct CodeString {
ZigString string;
JSC::JSValue value;
BunLoaderType loader;
BunString watchedFilePath = Zig::BunStringEmpty;
};
union OnLoadResultValue {

View File

@@ -305,6 +305,7 @@ extern "C" bool Bun__transpileVirtualModule(
const BunString* referrer,
ZigString* sourceCode,
BunLoaderType loader,
BunString* watchedFilePath,
ErrorableResolvedSource* result);
extern "C" JSC::EncodedJSValue Bun__runVirtualModule(

View File

@@ -2393,8 +2393,10 @@ pub const ModuleLoader = struct {
referrer_ptr: *const bun.String,
source_code: *ZigString,
loader_: Api.Loader,
watched_file_path: ?*bun.String,
ret: *ErrorableResolvedSource,
) bool {
_ = watched_file_path; // autofix
JSC.markBinding(@src());
const jsc_vm = globalObject.bunVM();
std.debug.assert(jsc_vm.plugin_runner != null);
@@ -2872,3 +2874,14 @@ export fn Bun__resolveEmbeddedNodeFile(vm: *JSC.VirtualMachine, in_out_str: *bun
in_out_str.* = bun.String.createUTF8(bun.path.joinAbs(bun.fs.FileSystem.instance.fs.tmpdirPath(), .auto, tmpfilename));
return true;
}
pub export fn Bun__isAbsolutePath(str: *bun.String) bool {
const utf8 = str.toUTF8(bun.default_allocator);
defer utf8.deinit();
if (str.hasPrefixComptime("file:") or str.hasPrefixComptime("data:") or str.hasPrefixComptime("blob:") or str.hasPrefixComptime("http:") or str.hasPrefixComptime("https:")) {
return false;
}
return std.fs.path.isAbsolute(utf8.slice());
}

View File

@@ -288,6 +288,7 @@ pub const Run = struct {
pub fn start(this: *Run) void {
var vm = this.vm;
vm.hot_reload = this.ctx.debug.hot_reload;
vm.onUnhandledRejection = &onUnhandledRejectionBeforeClose;
if (this.ctx.runtime_options.eval_script.len > 0) {

View File

@@ -522,9 +522,11 @@ pub const Arguments = struct {
if (args.flag("--hot")) {
ctx.debug.hot_reload = .hot;
Bun__watchMode = .hot;
} else if (args.flag("--watch")) {
ctx.debug.hot_reload = .watch;
bun.auto_reload_on_crash = true;
Bun__watchMode = .watch;
}
if (args.option("--origin")) |origin| {
@@ -1052,7 +1054,7 @@ pub const Command = struct {
pub const MacroOptions = union(enum) { unspecified: void, disable: void, map: MacroMap };
pub const HotReload = enum {
pub const HotReload = enum(u8) {
none,
hot,
watch,
@@ -2164,3 +2166,5 @@ pub const Command = struct {
});
};
};
pub export var Bun__watchMode: bun.CLI.Command.HotReload = .none;