"""One-shot rewrite of soma/reactive imports. For each soma file (excluding soma/reactive itself): - find each `import { ... } from '/reactive'` or `'$soma/reactive'` - split the names: libs symbols → '$libs/reactive', provider symbols → '$soma/provider' - emit one or two replacement imports """ import os import re import sys LIBS_SYMBOLS = { 'state', 'readableActive', 'writableActive', 'autoReset', 'isState', 'isActive', 'ActiveSymbol', 'WritableSymbol', 'Active', 'State', 'Getter', 'ActiveProps', 'StateProps', } PROVIDER_SYMBOLS = { 'bindProps', 'OptsFromProps', 'WritableSpec', 'PropsConfigEntry', } IMPORT_RE = re.compile( r"import\s+(type\s+)?\{([^}]+)\}\s+from\s+['\"](?:(?:\.\./)+reactive|\$soma/reactive)['\"];?", re.MULTILINE, ) def parse_names(block): out = [] for raw in block.split(','): item = raw.strip() if not item: continue is_type = False if item.startswith('type '): is_type = True item = item[5:].strip() out.append((item, is_type)) return out def render_import(items, source, has_type_import): if not items: return '' type_marker = 'type ' if has_type_import else '' parts = [] for name, is_type in items: if has_type_import: parts.append(name) else: parts.append(f'type {name}' if is_type else name) body = ',\n\t'.join(parts) return f"import {type_marker}{{\n\t{body}\n}} from '{source}';" def process_match(m): has_type_import = bool(m.group(1)) names = parse_names(m.group(2)) libs_items = [(n, t) for (n, t) in names if n in LIBS_SYMBOLS] prov_items = [(n, t) for (n, t) in names if n in PROVIDER_SYMBOLS] other_items = [(n, t) for (n, t) in names if n not in LIBS_SYMBOLS and n not in PROVIDER_SYMBOLS] if other_items: print('UNKNOWN names:', other_items, file=sys.stderr) return m.group(0) out = [] if libs_items: out.append(render_import(libs_items, '$libs/reactive', has_type_import)) if prov_items: out.append(render_import(prov_items, '$soma/provider', has_type_import)) return '\n'.join(out) SKIP_DIR = os.path.normpath('src/uix/soma/reactive') changed = [] for root, dirs, files in os.walk('src/uix/soma'): if os.path.normpath(root) == SKIP_DIR: continue for f in files: if not f.endswith(('.ts', '.svelte', '.svelte.ts')): continue p = os.path.join(root, f) s = open(p, 'r', encoding='utf-8').read() new = IMPORT_RE.sub(process_match, s) if new != s: open(p, 'w', encoding='utf-8').write(new) changed.append(p) for f in changed: print(f) print(f'--- {len(changed)} files updated ---')