\n\nMaybe it's possible to make `ReactiveSequence` generic for both way like this.",[3196],{"name":3172,"color":3173},454,"[hmr] Advanced generic typing","2025-09-25T10:43:48Z","https://github.com/promplate/pyth-on-line/issues/454",0.7588567,{"description":3203,"labels":3204,"number":3205,"owner":3175,"repository":3176,"state":3177,"title":3206,"updated_at":3207,"url":3208,"score":3209},"**issue (complexity):** Consider splitting the large core.py file into several smaller, focused modules for loader, module, reloader, errors, and CLI logic.\r\n\r\n**Refactor suggestion: split responsibilities into focused modules** \r\nRather than one 1,300 LOC file, break it up into:\r\n\r\n1. **loader.py** – `ReactiveModuleLoader` & `ReactiveModuleFinder` \r\n2. **module.py** – `ReactiveModule`, `NamespaceProxy`, signal plumbing \r\n3. **reloader.py** – `BaseReloader`, `SyncReloader`, `AsyncReloader` \r\n4. **errors.py** – `ErrorFilter` \r\n5. **cli.py** – `cli()` entrypoint \r\n\r\nThen have a short `__init__.py` that ties them together:\r\n\r\n```python\r\n# hmr/__init__.py\r\nfrom .loader import ReactiveModuleFinder, ReactiveModuleLoader\r\nfrom .module import ReactiveModule, NamespaceProxy\r\nfrom .reloader import SyncReloader, AsyncReloader, BaseReloader\r\nfrom .errors import ErrorFilter\r\nfrom .cli import cli\r\n__version__ = \"0.6.2\"\r\n```\r\n\r\n---\r\n\r\n### 1. loader.py\r\n```python\r\n# hmr/loader.py\r\nfrom importlib.abc import Loader, MetaPathFinder\r\nfrom importlib.util import spec_from_loader\r\nfrom pathlib import Path\r\nimport sys\r\n\r\nclass ReactiveModuleLoader(Loader):\r\n def __init__(self, file: Path): ...\r\n def create_module(self, spec): ...\r\n def exec_module(self, module): ...\r\n\r\nclass ReactiveModuleFinder(MetaPathFinder):\r\n def __init__(self, includes, excludes): ...\r\n def find_spec(self, fullname, paths, _=None):\r\n # walk sys.path, use spec_from_loader(...)\r\n ...\r\n```\r\n\r\n### 2. module.py\r\n```python\r\n# hmr/module.py\r\nfrom types import ModuleType\r\nfrom .proxy import NamespaceProxy\r\nfrom ..context import new_context\r\n\r\nHMR_CONTEXT = new_context()\r\n\r\nclass ReactiveModule(ModuleType):\r\n def __init__(...): ...\r\n @property\r\n def load(self): ...\r\n def __getattr__(...): ...\r\n # keep only module/proxy logic here\r\n```\r\n\r\n### 3. reloader.py\r\n```python\r\n# hmr/reloader.py\r\nfrom functools import cached_property\r\nfrom .module import ReactiveModule, get_path_module_map\r\nfrom .errors import ErrorFilter\r\nfrom .hooks import call_pre_reload_hooks, call_post_reload_hooks\r\n\r\nclass BaseReloader:\r\n def __init__(self, entry_file, includes, excludes): ...\r\n def run_entry_file(self): ...\r\n def on_events(self, events): ...\r\n\r\nclass SyncReloader(BaseReloader):\r\n def start_watching(self): ...\r\n def keep_watching_until_interrupt(self): ...\r\n\r\nclass AsyncReloader(BaseReloader):\r\n async def start_watching(self): ...\r\n async def keep_watching_until_interrupt(self): ...\r\n```\r\n\r\n### 4. errors.py\r\n```python\r\n# hmr/errors.py\r\nclass ErrorFilter:\r\n def __init__(self, *exclude_filenames): ...\r\n def __call__(self, tb): ...\r\n def __enter__(self): ...\r\n def __exit__(...): ...\r\n```\r\n\r\n### 5. cli.py\r\n```python\r\n# hmr/cli.py\r\nimport sys\r\nfrom pathlib import Path\r\nfrom .reloader import SyncReloader\r\n\r\ndef cli():\r\n if len(sys.argv) \u003C 2:\r\n print(\"Usage: hmr \u003Centry.py>\")\r\n sys.exit(1)\r\n entry = sys.argv[1]\r\n # insert parent into sys.path, start reloader…\r\n reloader = SyncReloader(entry)\r\n sys.modules[\"__main__\"] = reloader.entry_module\r\n reloader.keep_watching_until_interrupt()\r\n```\r\n\r\n**Benefits:** \r\n- each file ~200 LOC or less \r\n- clear separation of import‐hook, module‐proxy, reload, error‐filter, CLI logic \r\n- easier to navigate, test, and maintain without losing existing behavior.\r\n\r\n_Originally posted by @sourcery-ai[bot] in https://github.com/promplate/pyth-on-line/pull/319#discussion_r2145988833_\r\n ",[],321,"[hmr] Consider splitting the large `core.py` file into several smaller, focused modules","2025-06-13T20:17:48Z","https://github.com/promplate/pyth-on-line/issues/321",0.75986433,{"description":3211,"labels":3212,"number":3213,"owner":3175,"repository":3176,"state":3177,"title":3214,"updated_at":3215,"url":3216,"score":3217},"There are cases when multiple `Reloader` running in parallel, which is currently not supported because the calling stack in `hmr` is shared between threads.",[],342,"[hmr] `self.on_events(...)` calls should be locked","2025-07-07T18:51:08Z","https://github.com/promplate/pyth-on-line/issues/342",0.7852366,{"description":3219,"labels":3220,"number":3221,"owner":3175,"repository":3176,"state":3177,"title":3222,"updated_at":3223,"url":3224,"score":3225},"https://github.com/promplate/pyth-on-line/blob/a42a228ff2b93e1552f40d18c5a3f9ad53f929b4/src/lib/pyodide/start/notebook.ts#L1\n\n**suggestion:** Hard-coded deep relative import path is brittle\n\nRecommend configuring a module alias or updating the build setup to allow importing `reactivity` with a stable, shorter path.\n\nSuggested implementation:\n\n```typescript\nimport reactivity from \"@hmr/reactivity\";\n\n```\n\nMake sure your build tool (e.g., Vite, Webpack, or tsconfig.json for TypeScript) is configured with an alias like:\n```json\n{\n \"compilerOptions\": {\n \"baseUrl\": \".\",\n \"paths\": {\n \"@hmr/reactivity\": [\"packages/hmr/reactivity\"]\n }\n }\n}\n```\nor the equivalent for your setup.\n\n_Originally posted by @sourcery-ai[bot] in https://github.com/promplate/pyth-on-line/pull/319#discussion_r2145988795_\n ",[],322,"Hard-coded deep relative import path is brittle","2025-06-13T20:23:40Z","https://github.com/promplate/pyth-on-line/issues/322",0.79061234,{"description":3227,"labels":3228,"number":3229,"owner":3175,"repository":3176,"state":3177,"title":3230,"updated_at":3231,"url":3232,"score":3233},"Related: b38afd8fd9095d6814218ac11ae4275316e3b741",[],348,"[hmr] Need tests for `cache_across_reloads` gc behaviors","2025-07-20T11:39:27Z","https://github.com/promplate/pyth-on-line/issues/348",0.79619694,{"description":3235,"labels":3236,"number":3237,"owner":3175,"repository":3176,"state":3177,"title":3238,"updated_at":3239,"url":3240,"score":3241},"This is urgent. I can't imagine pitching the HMR ecosystem without having an intuitive documentation 😅",[],413,"Document HMR behaviors and usage of `reactivity` members","2025-09-05T05:02:24Z","https://github.com/promplate/pyth-on-line/issues/413",0.7968676,{"description":3243,"labels":3244,"number":3245,"owner":3175,"repository":3176,"state":3177,"title":3246,"updated_at":3247,"url":3248,"score":3249},"### Case 1\n\n```\nfoo/\nfoo/bar.py\n```\n\nWhen renaming `foo/bar.py` into `foo/__init__.py`.\n\n### Case 2\n\n```\nfoo/\nfoo/__init__.py\n```\n\nWhen renaming `foo/__init__.py` into `foo/bar.py`.\n",[],329,"[hmr] Refactoring between namespace and regular packages not supported","2025-06-17T18:55:41Z","https://github.com/promplate/pyth-on-line/issues/329",0.7971852,{"description":3251,"labels":3252,"number":3256,"owner":3175,"repository":3176,"state":3177,"title":3257,"updated_at":3258,"url":3259,"score":3260},"See: https://svelte.dev/docs/svelte/$derived#Overriding-derived-values\n\n> Derived expressions are recalculated when their dependencies change, but you can temporarily override their values by reassigning them. This can be useful for things like _optimistic UI_, where a value is derived from the ‘source of truth’ (such as data from your server) but you’d like to show immediate feedback to the user\n>\n> ```svelte\n> \u003Cscript>\n> \tlet { post, like } = $props();\n> \n> \tlet likes = $derived(post.likes);\n> \n> \tasync function onclick() {\n> \t\t// increment the `likes` count immediately...\n> \t\tlikes += 1;\n> \n> \t\t// and tell the server, which will eventually update `post`\n> \t\ttry {\n> \t\t\tawait like();\n> \t\t} catch {\n> \t\t\t// failed! roll back the change\n> \t\t\tlikes -= 1;\n> \t\t}\n> \t}\n> \u003C/script>\n> ```",[3253],{"name":3254,"color":3255},"enhancement","a2eeef",416,"[hmr] Support overriding `Derived` values to enable optimistic updates","2025-09-05T17:05:56Z","https://github.com/promplate/pyth-on-line/issues/416",0.7999222,["Reactive",3262],{},["Set"],["ShallowReactive",3265],{"$fTRc1wZytZ_XrK4EfJfei_Sz-An4H4Yy6syhVxH_PVJc":-1,"$fzn7PifL1ZEGDr38Bjflm7tACZ5MMgwSfSUIQdAKzy1g":-1},"/promplate/pyth-on-line/432"]