add hot reload to util
This commit is contained in:
@@ -703,6 +703,27 @@ static JSValue js_os_stack(JSContext *js, JSValue self, int argc, JSValue *argv)
|
|||||||
JS_RETURN(arr.val);
|
JS_RETURN(arr.val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JSValue js_os_unstone(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
||||||
|
if (argc < 1) return JS_NULL;
|
||||||
|
JSValue obj = argv[0];
|
||||||
|
if (mist_is_blob(obj)) {
|
||||||
|
JSBlob *bd = (JSBlob *)chase(obj);
|
||||||
|
bd->mist_hdr = objhdr_set_s(bd->mist_hdr, false);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
if (JS_IsArray(obj)) {
|
||||||
|
JSArray *arr = JS_VALUE_GET_ARRAY(obj);
|
||||||
|
arr->mist_hdr = objhdr_set_s(arr->mist_hdr, false);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
if (mist_is_gc_object(obj)) {
|
||||||
|
JSRecord *rec = JS_VALUE_GET_RECORD(obj);
|
||||||
|
rec->mist_hdr = objhdr_set_s(rec->mist_hdr, false);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
return JS_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_os_funcs[] = {
|
static const JSCFunctionListEntry js_os_funcs[] = {
|
||||||
MIST_FUNC_DEF(os, platform, 0),
|
MIST_FUNC_DEF(os, platform, 0),
|
||||||
MIST_FUNC_DEF(os, arch, 0),
|
MIST_FUNC_DEF(os, arch, 0),
|
||||||
@@ -731,6 +752,7 @@ static const JSCFunctionListEntry js_os_funcs[] = {
|
|||||||
MIST_FUNC_DEF(os, getenv, 1),
|
MIST_FUNC_DEF(os, getenv, 1),
|
||||||
MIST_FUNC_DEF(os, qbe, 1),
|
MIST_FUNC_DEF(os, qbe, 1),
|
||||||
MIST_FUNC_DEF(os, stack, 1),
|
MIST_FUNC_DEF(os, stack, 1),
|
||||||
|
MIST_FUNC_DEF(os, unstone, 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
JSValue js_core_internal_os_use(JSContext *js) {
|
JSValue js_core_internal_os_use(JSContext *js) {
|
||||||
|
|||||||
@@ -455,6 +455,7 @@ Shop.extract_commit_hash = function(pkg, response) {
|
|||||||
|
|
||||||
var open_dls = {}
|
var open_dls = {}
|
||||||
var package_dylibs = {} // pkg -> [{file, symbol, dylib}, ...]
|
var package_dylibs = {} // pkg -> [{file, symbol, dylib}, ...]
|
||||||
|
var reload_hashes = {} // cache_key -> content hash for reload change detection
|
||||||
|
|
||||||
function open_dylib_cached(path) {
|
function open_dylib_cached(path) {
|
||||||
var handle = open_dls[path]
|
var handle = open_dls[path]
|
||||||
@@ -1982,19 +1983,27 @@ Shop.file_reload = function(file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Shop.module_reload = function(path, package) {
|
Shop.module_reload = function(path, package) {
|
||||||
if (!Shop.is_loaded(path,package)) return
|
if (!Shop.is_loaded(path, package)) return false
|
||||||
|
|
||||||
// Clear the module info cache for this path
|
|
||||||
var lookup_key = package ? package + ':' + path : ':' + path
|
var lookup_key = package ? package + ':' + path : ':' + path
|
||||||
module_info_cache[lookup_key] = null
|
var info = resolve_module_info(path, package)
|
||||||
|
if (!info) return false
|
||||||
|
|
||||||
// Invalidate package dylib cache so next resolve triggers rebuild
|
// Check if source actually changed
|
||||||
if (package) {
|
var mod_path = null
|
||||||
package_dylibs[package] = null
|
var source = null
|
||||||
|
var new_hash = null
|
||||||
|
if (info.mod_resolve) mod_path = info.mod_resolve.path
|
||||||
|
if (mod_path && fd.is_file(mod_path)) {
|
||||||
|
source = fd.slurp(mod_path)
|
||||||
|
new_hash = content_hash(stone(blob(text(source))))
|
||||||
|
if (reload_hashes[info.cache_key] == new_hash) return false
|
||||||
|
reload_hashes[info.cache_key] = new_hash
|
||||||
}
|
}
|
||||||
|
|
||||||
var info = resolve_module_info(path, package)
|
// Clear caches
|
||||||
if (!info) return
|
module_info_cache[lookup_key] = null
|
||||||
|
if (package) package_dylibs[package] = null
|
||||||
|
|
||||||
var cache_key = info.cache_key
|
var cache_key = info.cache_key
|
||||||
var old = use_cache[cache_key]
|
var old = use_cache[cache_key]
|
||||||
@@ -2003,13 +2012,18 @@ Shop.module_reload = function(path, package) {
|
|||||||
var newmod = get_module(path, package)
|
var newmod = get_module(path, package)
|
||||||
use_cache[cache_key] = newmod
|
use_cache[cache_key] = newmod
|
||||||
|
|
||||||
|
// Smart update: unstone -> merge -> re-stone to preserve references
|
||||||
if (old && is_object(old) && is_object(newmod)) {
|
if (old && is_object(old) && is_object(newmod)) {
|
||||||
|
os.unstone(old)
|
||||||
arrfor(array(newmod), function(k) { old[k] = newmod[k] })
|
arrfor(array(newmod), function(k) { old[k] = newmod[k] })
|
||||||
arrfor(array(old), function(k) {
|
arrfor(array(old), function(k) {
|
||||||
if (!(k in newmod)) old[k] = null
|
if (!(k in newmod)) old[k] = null
|
||||||
})
|
})
|
||||||
|
stone(old)
|
||||||
use_cache[cache_key] = old
|
use_cache[cache_key] = old
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_package_scripts(package)
|
function get_package_scripts(package)
|
||||||
|
|||||||
Reference in New Issue
Block a user