reload module

This commit is contained in:
2025-12-06 11:33:34 -06:00
parent 825c6aa284
commit 5ac58dfbb0

View File

@@ -57,6 +57,84 @@ function get_import_package(name) {
return null
}
Shop.file_info = function(file) {
var info = {
path: file,
is_module: false,
is_actor: false,
package: null,
name: null
}
if (file.endsWith(MOD_EXT)) {
info.is_module = true
} else if (file.endsWith(ACTOR_EXT)) {
info.is_actor = true
}
// Strip extension for name
var name_without_ext = file
if (info.is_module) {
name_without_ext = file.substring(0, file.length - MOD_EXT.length)
} else if (info.is_actor) {
name_without_ext = file.substring(0, file.length - ACTOR_EXT.length)
}
// Check if file is in a package
if (file.startsWith('.cell/modules/')) {
var rest = file.substring('.cell/modules/'.length)
// Get all packages and find which one matches this path
var packages = Shop.list_packages()
var matched_pkg = null
var matched_path = null
for (var i = 0; i < packages.length; i++) {
var pkg = packages[i]
var parsed = Shop.parse_package(pkg)
var pkg_path = parsed.path
if (rest.startsWith(pkg_path + '/')) {
// Found matching package - use longest match
if (!matched_pkg || pkg_path.length > matched_path.length) {
matched_pkg = pkg
matched_path = pkg_path
}
}
}
if (matched_path) {
info.package = matched_path
var import_part = rest.substring(matched_path.length + 1)
// Strip extension from import name
if (info.is_module && import_part.endsWith(MOD_EXT)) {
import_part = import_part.substring(0, import_part.length - MOD_EXT.length)
} else if (info.is_actor && import_part.endsWith(ACTOR_EXT)) {
import_part = import_part.substring(0, import_part.length - ACTOR_EXT.length)
}
info.name = import_part
} else {
// Fallback: use first path component as package
var slash_idx = rest.indexOf('/')
if (slash_idx > 0) {
info.package = rest.substring(0, slash_idx)
var import_part = rest.substring(slash_idx + 1)
if (info.is_module && import_part.endsWith(MOD_EXT)) {
import_part = import_part.substring(0, import_part.length - MOD_EXT.length)
} else if (info.is_actor && import_part.endsWith(ACTOR_EXT)) {
import_part = import_part.substring(0, import_part.length - ACTOR_EXT.length)
}
info.name = import_part
}
}
} else {
info.package = 'local'
info.name = name_without_ext
}
return info
}
function get_import_name(path)
{
var parts = path.split('/')
@@ -654,22 +732,23 @@ function resolve_locator(path, ext, ctx)
return null;
}
function c_sym_path(path)
{
return path.replace(/\//g, '_').replace(/\\/g, '_').replace(/\./g, '_').replace(/-/g, '_')
}
function resolve_c_symbol(path, package_context)
{
var local_path = package_context ? package_context : 'local'
var local_sym_base = path.replace(/\//g, '_').replace(/-/g, '_').replace(/\./g, '_')
var local_sym_base = c_sym_path(path)
var local
function symbolify_path(p) {
return p.replace(/\//g, '_').replace(/-/g, '_').replace(/\./g, '_')
}
function symbol_candidates(pkg_path, mod_sym) {
var variants = []
var paths = [pkg_path]
if (!pkg_path.startsWith('/')) paths.push('/' + pkg_path)
for (var i = 0; i < paths.length; i++) {
var candidate = `js_${symbolify_path(paths[i])}_${mod_sym}_use`
var candidate = `js_${c_sym_path(paths[i])}_${mod_sym}_use`
if (variants.indexOf(candidate) < 0)
variants.push(candidate)
}
@@ -754,7 +833,6 @@ function resolve_c_symbol(path, package_context)
}
}
}
var core_sym = `js_${path.replace(/\//g, '_')}_use`;
if (os.internal_exists(core_sym))
return {
@@ -766,18 +844,13 @@ function resolve_c_symbol(path, package_context)
return null
}
// first looks in local
// then in dependencies
// then in core
// package_context: optional package context to resolve relative paths within
Shop.use = function(path, package_context) {
function resolve_module_info(path, package_context) {
var c_resolve = resolve_c_symbol(path, package_context) || {scope:999}
var mod_resolve = resolve_locator(path, '.cm', package_context) || {scope:999}
var min_scope = Math.min(c_resolve.scope, mod_resolve.scope)
if (min_scope == 999)
throw new Error(`Module ${path} could not be found in ${package_context}`)
return null
var resolved_path
if (mod_resolve.scope != 999) resolved_path = mod_resolve.path
@@ -792,8 +865,31 @@ Shop.use = function(path, package_context) {
cache_key = cache_key.replace('//', '/')
if (use_cache[cache_key])
return use_cache[cache_key]
return {
cache_key: cache_key,
c_resolve: c_resolve,
mod_resolve: mod_resolve,
min_scope: min_scope
}
}
function get_module_cache_key(path, package_context) {
var info = resolve_module_info(path, package_context)
return info ? info.cache_key : null
}
Shop.is_loaded = function(path, package_context) {
var cache_key = get_module_cache_key(path, package_context)
log.console(cache_key)
if (!cache_key) return false
return use_cache[cache_key] != null
}
function execute_module(info)
{
var c_resolve = info.c_resolve
var mod_resolve = info.mod_resolve
var cache_key = info.cache_key
var used
@@ -805,12 +901,36 @@ Shop.use = function(path, package_context) {
used = mod_resolve.symbol.call(c_resolve.symbol(), $_)
if (!used)
throw new Error(`Module ${path} via package ${package_context} returned null`)
throw new Error(`Module ${json.encode(info)} returned null`)
use_cache[cache_key] = used
return used
}
function get_module(path, package_context) {
var info = resolve_module_info(path, package_context)
if (!info)
throw new Error(`Module ${path} could not be found in ${package_context}`)
return execute_module(info)
}
// first looks in local
// then in dependencies
// then in core
// package_context: optional package context to resolve relative paths within
Shop.use = function(path, package_context) {
var info = resolve_module_info(path, package_context)
if (!info)
throw new Error(`Module ${path} could not be found in ${package_context}`)
if (use_cache[info.cache_key])
return use_cache[info.cache_key]
use_cache[info.cache_key] = execute_module(info)
return use_cache[info.cache_key]
}
Shop.resolve_locator = resolve_locator
// Get cache path for a package and commit
@@ -1199,6 +1319,23 @@ Shop.compile_module = function(alias) {
return true
}
Shop.module_reload = function(path, package) {
if (!Shop.is_loaded(path,package)) return
var info = resolve_module_info(path, package)
if (!info) return
var cache_key = info.cache_key
log.console(`reloading ${cache_key}`)
var old = use_cache[cache_key]
var newmod = get_module(path, package)
log.console(typeof old)
log.console(typeof newmod)
for (var i in newmod)
old[i] = newmod[i]
}
Shop.build_package = function(package)
{
if (package == 'local') package = null
@@ -1247,7 +1384,7 @@ Shop.build_package = function(package)
var meta_path = obj_path + '.meta'
ensure_dir(obj_path.substring(0, obj_path.lastIndexOf('/')))
var safe_path = file.substring(0, file.lastIndexOf('.')).replace(/\//g, '_').replace(/\\/g, '_').replace(/\./g, '_').replace(/-/g, '_')
var safe_path = c_sym_path(file.substring(0, file.lastIndexOf('.')))
var use_name = use_prefix + safe_path + '_use'
var comp_src = file
var comp_obj = file + '.o'