reactpy 2.0.0b5__tar.gz → 2.0.0b7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/.gitignore +1 -1
  2. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/PKG-INFO +1 -1
  3. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/pyproject.toml +37 -38
  4. reactpy-2.0.0b7/src/build_scripts/build_js_app.py +30 -0
  5. reactpy-2.0.0b7/src/build_scripts/build_js_client.py +30 -0
  6. reactpy-2.0.0b7/src/build_scripts/build_js_event_to_object.py +30 -0
  7. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/build_scripts/clean_js_dir.py +14 -11
  8. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/build_scripts/copy_dir.py +1 -0
  9. reactpy-2.0.0b7/src/build_scripts/delete_old_coverage.py +21 -0
  10. reactpy-2.0.0b7/src/build_scripts/install_playwright.py +17 -0
  11. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/js/bun.lockb +0 -0
  12. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/js/package.json +3 -2
  13. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/js/tsconfig.json +0 -6
  14. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/__init__.py +4 -3
  15. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/_html.py +11 -9
  16. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/config.py +1 -1
  17. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/core/_life_cycle_hook.py +4 -1
  18. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/core/_thread_local.py +1 -1
  19. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/core/hooks.py +11 -19
  20. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/core/layout.py +43 -38
  21. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/core/serve.py +11 -16
  22. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/core/vdom.py +3 -5
  23. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/executors/asgi/pyscript.py +4 -1
  24. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/executors/asgi/standalone.py +1 -1
  25. {reactpy-2.0.0b5/src/reactpy → reactpy-2.0.0b7/src/reactpy/executors}/pyscript/component_template.py +1 -1
  26. {reactpy-2.0.0b5/src/reactpy → reactpy-2.0.0b7/src/reactpy/executors}/pyscript/components.py +1 -1
  27. {reactpy-2.0.0b5/src/reactpy → reactpy-2.0.0b7/src/reactpy/executors}/pyscript/utils.py +1 -1
  28. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/executors/utils.py +32 -7
  29. reactpy-2.0.0b7/src/reactpy/reactjs/__init__.py +351 -0
  30. reactpy-2.0.0b7/src/reactpy/reactjs/module.py +267 -0
  31. reactpy-2.0.0b7/src/reactpy/reactjs/types.py +7 -0
  32. reactpy-2.0.0b7/src/reactpy/reactjs/utils.py +212 -0
  33. reactpy-2.0.0b7/src/reactpy/static/index-64wy0fss.js +5 -0
  34. reactpy-2.0.0b7/src/reactpy/static/index-64wy0fss.js.map +10 -0
  35. reactpy-2.0.0b7/src/reactpy/static/index-beq660xy.js +5 -0
  36. reactpy-2.0.0b7/src/reactpy/static/index-beq660xy.js.map +12 -0
  37. reactpy-2.0.0b7/src/reactpy/static/index.js +4 -0
  38. reactpy-2.0.0b7/src/reactpy/static/index.js.map +19 -0
  39. reactpy-2.0.0b7/src/reactpy/static/preact-dom.js +4 -0
  40. reactpy-2.0.0b7/src/reactpy/static/preact-dom.js.map +11 -0
  41. reactpy-2.0.0b7/src/reactpy/static/preact-jsx-runtime.js +4 -0
  42. reactpy-2.0.0b7/src/reactpy/static/preact-jsx-runtime.js.map +9 -0
  43. reactpy-2.0.0b7/src/reactpy/static/preact.js +4 -0
  44. reactpy-2.0.0b7/src/reactpy/static/preact.js.map +10 -0
  45. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/templatetags/jinja.py +4 -1
  46. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/testing/__init__.py +2 -7
  47. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/testing/backend.py +24 -12
  48. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/testing/common.py +1 -9
  49. reactpy-2.0.0b7/src/reactpy/testing/display.py +111 -0
  50. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/testing/logs.py +1 -1
  51. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/transforms.py +2 -2
  52. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/types.py +17 -11
  53. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/utils.py +1 -1
  54. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/web/__init__.py +0 -6
  55. reactpy-2.0.0b7/src/reactpy/web/module.py +130 -0
  56. reactpy-2.0.0b7/src/reactpy/web/utils.py +3 -0
  57. reactpy-2.0.0b5/src/reactpy/static/index.js +0 -4
  58. reactpy-2.0.0b5/src/reactpy/static/index.js.map +0 -22
  59. reactpy-2.0.0b5/src/reactpy/testing/display.py +0 -74
  60. reactpy-2.0.0b5/src/reactpy/testing/utils.py +0 -27
  61. reactpy-2.0.0b5/src/reactpy/web/module.py +0 -566
  62. reactpy-2.0.0b5/src/reactpy/web/templates/react.js +0 -61
  63. reactpy-2.0.0b5/src/reactpy/web/utils.py +0 -159
  64. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/LICENSE +0 -0
  65. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/README.md +0 -0
  66. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/js/.gitignore +0 -0
  67. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/js/eslint.config.mjs +0 -0
  68. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/_console/__init__.py +0 -0
  69. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/_console/ast_utils.py +0 -0
  70. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/_console/cli.py +0 -0
  71. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/_console/rewrite_keys.py +0 -0
  72. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/_console/rewrite_props.py +0 -0
  73. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/_option.py +0 -0
  74. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/_warnings.py +0 -0
  75. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/core/__init__.py +0 -0
  76. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/core/_f_back.py +0 -0
  77. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/core/component.py +0 -0
  78. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/core/events.py +0 -0
  79. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/executors/__init__.py +0 -0
  80. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/executors/asgi/__init__.py +0 -0
  81. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/executors/asgi/middleware.py +0 -0
  82. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/executors/asgi/types.py +0 -0
  83. {reactpy-2.0.0b5/src/reactpy → reactpy-2.0.0b7/src/reactpy/executors}/pyscript/__init__.py +0 -0
  84. {reactpy-2.0.0b5/src/reactpy → reactpy-2.0.0b7/src/reactpy/executors}/pyscript/layout_handler.py +0 -0
  85. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/logging.py +0 -0
  86. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/py.typed +0 -0
  87. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/morphdom/morphdom-esm.js +0 -0
  88. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/morphdom/morphdom-factory.js +0 -0
  89. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/morphdom/morphdom-umd.js +0 -0
  90. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/morphdom/morphdom-umd.min.js +0 -0
  91. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/morphdom/morphdom.js +0 -0
  92. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/codemirror-BYspKCDy.js +0 -0
  93. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/codemirror-BYspKCDy.js.map +0 -0
  94. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/codemirror_commands-BLDaEdQ6.js +0 -0
  95. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/codemirror_commands-BLDaEdQ6.js.map +0 -0
  96. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/codemirror_lang-python-CkOVBHci.js +0 -0
  97. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/codemirror_lang-python-CkOVBHci.js.map +0 -0
  98. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/codemirror_language-DOkvasqm.js +0 -0
  99. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/codemirror_language-DOkvasqm.js.map +0 -0
  100. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/codemirror_state-BIAL8JKm.js +0 -0
  101. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/codemirror_state-BIAL8JKm.js.map +0 -0
  102. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/codemirror_view-Bt4sLgyA.js +0 -0
  103. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/codemirror_view-Bt4sLgyA.js.map +0 -0
  104. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/core-PTfg6inS.js +0 -0
  105. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/core-PTfg6inS.js.map +0 -0
  106. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/core.css +0 -0
  107. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/core.js +0 -0
  108. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/core.js.map +0 -0
  109. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/deprecations-manager-DIDxhyRq.js +0 -0
  110. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/deprecations-manager-DIDxhyRq.js.map +0 -0
  111. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/donkey-CLhmQOjG.js +0 -0
  112. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/donkey-CLhmQOjG.js.map +0 -0
  113. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/error-uzvvriog.js +0 -0
  114. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/error-uzvvriog.js.map +0 -0
  115. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/index-jZ1aOVVJ.js +0 -0
  116. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/index-jZ1aOVVJ.js.map +0 -0
  117. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/mpy-CnF17tqI.js +0 -0
  118. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/mpy-CnF17tqI.js.map +0 -0
  119. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/py-BZSSqcx3.js +0 -0
  120. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/py-BZSSqcx3.js.map +0 -0
  121. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/py-editor-DZ0Dxzzk.js +0 -0
  122. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/py-editor-DZ0Dxzzk.js.map +0 -0
  123. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/py-game-bqieV522.js +0 -0
  124. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/py-game-bqieV522.js.map +0 -0
  125. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/py-terminal-DYY4WN57.js +0 -0
  126. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/py-terminal-DYY4WN57.js.map +0 -0
  127. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/service-worker.js +0 -0
  128. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/storage.js +0 -0
  129. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/storage.js.map +0 -0
  130. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/toml-BK2RWy-G.js +0 -0
  131. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/toml-BK2RWy-G.js.map +0 -0
  132. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/toml-Blg7Izee.js +0 -0
  133. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/toml-Blg7Izee.js.map +0 -0
  134. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/xterm-DrSYbXEP.js +0 -0
  135. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/xterm-DrSYbXEP.js.map +0 -0
  136. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/xterm-readline-CK_45Ygx.js +0 -0
  137. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/xterm-readline-CK_45Ygx.js.map +0 -0
  138. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/xterm.css +0 -0
  139. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/xterm_addon-fit--gyF3PcZ.js +0 -0
  140. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/xterm_addon-fit--gyF3PcZ.js.map +0 -0
  141. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/xterm_addon-web-links-D95xh2la.js +0 -0
  142. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/xterm_addon-web-links-D95xh2la.js.map +0 -0
  143. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/zip-pccs084i.js +0 -0
  144. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript/zip-pccs084i.js.map +0 -0
  145. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/static/pyscript-hide-debug.css +0 -0
  146. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/templatetags/__init__.py +0 -0
  147. {reactpy-2.0.0b5 → reactpy-2.0.0b7}/src/reactpy/widgets.py +0 -0
@@ -1,5 +1,5 @@
1
1
  # --- Build Artifacts ---
2
- src/reactpy/static/index.js*
2
+ src/reactpy/static/*.js*
3
3
  src/reactpy/static/morphdom/
4
4
  src/reactpy/static/pyscript/
5
5
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reactpy
3
- Version: 2.0.0b5
3
+ Version: 2.0.0b7
4
4
  Summary: It's React, but in Python.
5
5
  Project-URL: Changelog, https://reactpy.dev/docs/about/changelog.html
6
6
  Project-URL: Documentation, https://reactpy.dev/
@@ -1,6 +1,6 @@
1
1
  [build-system]
2
2
  build-backend = "hatchling.build"
3
- requires = ["hatchling", "hatch-build-scripts"]
3
+ requires = ["hatchling", "hatch-build-scripts", "hatch"]
4
4
 
5
5
  ##############################
6
6
  # >>> Hatch Build Config <<< #
@@ -39,12 +39,7 @@ classifiers = [
39
39
  "Programming Language :: Python :: Implementation :: CPython",
40
40
  "Programming Language :: Python :: Implementation :: PyPy",
41
41
  ]
42
- dependencies = [
43
- "fastjsonschema >=2.14.5",
44
- "requests >=2",
45
- "lxml >=4",
46
- "anyio >=3",
47
- ]
42
+ dependencies = ["fastjsonschema>=2.14.5", "requests>=2", "lxml>=4", "anyio>=3"]
48
43
  dynamic = ["version"]
49
44
  urls.Changelog = "https://reactpy.dev/docs/about/changelog.html"
50
45
  urls.Documentation = "https://reactpy.dev/"
@@ -53,7 +48,7 @@ urls.Source = "https://github.com/reactive-python/reactpy"
53
48
  [project.optional-dependencies]
54
49
  all = ["reactpy[asgi,jinja,testing]"]
55
50
  asgi = ["asgiref", "asgi-tools", "servestatic", "orjson"]
56
- jinja = ["jinja2-simple-tags", "jinja2 >=3"]
51
+ jinja = ["jinja2-simple-tags", "jinja2>=3"]
57
52
  testing = ["playwright", "uvicorn[standard]"]
58
53
 
59
54
  [tool.hatch.version]
@@ -76,28 +71,34 @@ installer = "uv"
76
71
  reactpy = "reactpy._console.cli:entry_point"
77
72
 
78
73
  [[tool.hatch.build.hooks.build-scripts.scripts]]
79
- # Note: `hatch` can't be called within `build-scripts` when installing packages in editable mode, so we have to write the commands long-form
80
- commands = [
81
- 'python "src/build_scripts/clean_js_dir.py"',
82
- 'bun install --cwd "src/js/packages/event-to-object"',
83
- 'bun run --cwd "src/js/packages/event-to-object" build',
84
- 'bun install --cwd "src/js/packages/@reactpy/client"',
85
- 'bun run --cwd "src/js/packages/@reactpy/client" build',
86
- 'bun install --cwd "src/js/packages/@reactpy/app"',
87
- 'bun run --cwd "src/js/packages/@reactpy/app" build',
88
- 'python "src/build_scripts/copy_dir.py" "src/js/node_modules/@pyscript/core/dist" "src/reactpy/static/pyscript"',
89
- 'python "src/build_scripts/copy_dir.py" "src/js/node_modules/morphdom/dist" "src/reactpy/static/morphdom"',
90
- ]
74
+ commands = []
91
75
  artifacts = []
92
76
 
93
77
  #############################
94
78
  # >>> Hatch Test Runner <<< #
95
79
  #############################
80
+ [tool.hatch.envs.hatch-test.scripts]
81
+ run = [
82
+ 'hatch --env default run "src/build_scripts/install_playwright.py"',
83
+ "hatch --env default run javascript:build --dev",
84
+ "hatch --env default build -t wheel",
85
+ "pytest{env:HATCH_TEST_ARGS:} {args} --max-worker-restart 10",
86
+ ]
87
+ run-cov = [
88
+ 'hatch --env default run "src/build_scripts/install_playwright.py"',
89
+ "hatch --env default run javascript:build --dev",
90
+ "hatch --env default build -t wheel",
91
+ 'hatch --env default run "src/build_scripts/delete_old_coverage.py"',
92
+ "coverage run -m pytest{env:HATCH_TEST_ARGS:} {args} --max-worker-restart 10",
93
+ ]
94
+ cov-combine = "coverage combine"
95
+ cov-report = "coverage report"
96
96
 
97
97
  [tool.hatch.envs.hatch-test]
98
98
  extra-dependencies = [
99
99
  "pytest-sugar",
100
100
  "pytest-asyncio",
101
+ "pytest-timeout",
101
102
  "responses",
102
103
  "exceptiongroup",
103
104
  "jsonpointer",
@@ -120,8 +121,10 @@ filterwarnings = """
120
121
  testpaths = "tests"
121
122
  xfail_strict = true
122
123
  asyncio_mode = "auto"
123
- asyncio_default_fixture_loop_scope = "function"
124
+ asyncio_default_fixture_loop_scope = "session"
125
+ asyncio_default_test_loop_scope = "session"
124
126
  log_cli_level = "INFO"
127
+ timeout = 120
125
128
 
126
129
  #######################################
127
130
  # >>> Hatch Documentation Scripts <<< #
@@ -167,6 +170,7 @@ extra-dependencies = [
167
170
  "types-requests",
168
171
  "types-lxml",
169
172
  "jsonpointer",
173
+ "pytest",
170
174
  ]
171
175
 
172
176
  [tool.hatch.envs.python.scripts]
@@ -182,33 +186,28 @@ detached = true
182
186
  [tool.hatch.envs.javascript.scripts]
183
187
  check = [
184
188
  'hatch run javascript:build',
185
- 'bun install --cwd "src/js"',
186
189
  'bun run --cwd "src/js" lint',
187
190
  'bun run --cwd "src/js/packages/event-to-object" checkTypes',
188
191
  'bun run --cwd "src/js/packages/@reactpy/client" checkTypes',
189
192
  'bun run --cwd "src/js/packages/@reactpy/app" checkTypes',
190
193
  ]
191
194
  fix = ['bun install --cwd "src/js"', 'bun run --cwd "src/js" format']
192
- test = ['hatch run javascript:build_event_to_object', 'bun test']
195
+ test = ['hatch run javascript:build_event_to_object --dev', 'bun test']
193
196
  build = [
194
197
  'hatch run "src/build_scripts/clean_js_dir.py"',
195
198
  'bun install --cwd "src/js"',
196
- 'hatch run javascript:build_event_to_object',
197
- 'hatch run javascript:build_client',
198
- 'hatch run javascript:build_app',
199
+ 'hatch run javascript:build_event_to_object {args}',
200
+ 'hatch run javascript:build_client {args}',
201
+ 'hatch run javascript:build_app {args}',
202
+ 'hatch --env default run "src/build_scripts/copy_dir.py" "src/js/node_modules/@pyscript/core/dist" "src/reactpy/static/pyscript"',
203
+ 'hatch --env default run "src/build_scripts/copy_dir.py" "src/js/node_modules/morphdom/dist" "src/reactpy/static/morphdom"',
204
+
199
205
  ]
200
206
  build_event_to_object = [
201
- 'bun install --cwd "src/js/packages/event-to-object"',
202
- 'bun run --cwd "src/js/packages/event-to-object" build',
203
- ]
204
- build_client = [
205
- 'bun install --cwd "src/js/packages/@reactpy/client"',
206
- 'bun run --cwd "src/js/packages/@reactpy/client" build',
207
- ]
208
- build_app = [
209
- 'bun install --cwd "src/js/packages/@reactpy/app"',
210
- 'bun run --cwd "src/js/packages/@reactpy/app" build',
207
+ 'hatch run "src/build_scripts/build_js_event_to_object.py" {args}',
211
208
  ]
209
+ build_client = ['hatch run "src/build_scripts/build_js_client.py" {args}']
210
+ build_app = ['hatch run "src/build_scripts/build_js_app.py" {args}']
212
211
  publish_event_to_object = [
213
212
  'hatch run javascript:build_event_to_object',
214
213
  'cd "src/js/packages/event-to-object" && bun publish --access public',
@@ -233,8 +232,8 @@ omit = [
233
232
  "src/reactpy/__init__.py",
234
233
  "src/reactpy/_console/*",
235
234
  "src/reactpy/__main__.py",
236
- "src/reactpy/pyscript/layout_handler.py",
237
- "src/reactpy/pyscript/component_template.py",
235
+ "src/reactpy/executors/pyscript/layout_handler.py",
236
+ "src/reactpy/executors/pyscript/component_template.py",
238
237
  ]
239
238
 
240
239
  [tool.coverage.report]
@@ -0,0 +1,30 @@
1
+ # /// script
2
+ # requires-python = ">=3.11"
3
+ # dependencies = []
4
+ # ///
5
+ import pathlib
6
+ import subprocess
7
+ import sys
8
+
9
+ dev_mode = "--dev" in sys.argv
10
+ root_dir = pathlib.Path(__file__).parent.parent.parent
11
+ build_commands = [
12
+ [
13
+ "bun",
14
+ "install",
15
+ "--cwd",
16
+ "src/js/packages/@reactpy/app",
17
+ *([] if dev_mode else ["--production"]),
18
+ ],
19
+ [
20
+ "bun",
21
+ "run",
22
+ "--cwd",
23
+ "src/js/packages/@reactpy/app",
24
+ "buildDev" if dev_mode else "build",
25
+ ],
26
+ ]
27
+
28
+ for command in build_commands:
29
+ print(f"Running command: '{command}'...") # noqa: T201
30
+ subprocess.run(command, check=True, cwd=root_dir) # noqa: S603
@@ -0,0 +1,30 @@
1
+ # /// script
2
+ # requires-python = ">=3.11"
3
+ # dependencies = []
4
+ # ///
5
+ import pathlib
6
+ import subprocess
7
+ import sys
8
+
9
+ dev_mode = "--dev" in sys.argv
10
+ root_dir = pathlib.Path(__file__).parent.parent.parent
11
+ build_commands = [
12
+ [
13
+ "bun",
14
+ "install",
15
+ "--cwd",
16
+ "src/js/packages/@reactpy/client",
17
+ *([] if dev_mode else ["--production"]),
18
+ ],
19
+ [
20
+ "bun",
21
+ "run",
22
+ "--cwd",
23
+ "src/js/packages/@reactpy/client",
24
+ "build",
25
+ ],
26
+ ]
27
+
28
+ for command in build_commands:
29
+ print(f"Running command: '{command}'...") # noqa: T201
30
+ subprocess.run(command, check=True, cwd=root_dir) # noqa: S603
@@ -0,0 +1,30 @@
1
+ # /// script
2
+ # requires-python = ">=3.11"
3
+ # dependencies = []
4
+ # ///
5
+ import pathlib
6
+ import subprocess
7
+ import sys
8
+
9
+ dev_mode = "--dev" in sys.argv
10
+ root_dir = pathlib.Path(__file__).parent.parent.parent
11
+ build_commands = [
12
+ [
13
+ "bun",
14
+ "install",
15
+ "--cwd",
16
+ "src/js/packages/event-to-object",
17
+ *([] if dev_mode else ["--production"]),
18
+ ],
19
+ [
20
+ "bun",
21
+ "run",
22
+ "--cwd",
23
+ "src/js/packages/event-to-object",
24
+ "build",
25
+ ],
26
+ ]
27
+
28
+ for command in build_commands:
29
+ print(f"Running command: '{command}'...") # noqa: T201
30
+ subprocess.run(command, check=True, cwd=root_dir) # noqa: S603
@@ -11,31 +11,34 @@ import os
11
11
  import pathlib
12
12
  import shutil
13
13
 
14
+ print("Cleaning JS source directory...") # noqa: T201
15
+
14
16
  # Get the path to the JS source directory
15
17
  js_src_dir = pathlib.Path(__file__).parent.parent / "js"
16
-
17
- # Get the paths to all `dist` folders in the JS source directory
18
- dist_dirs = glob.glob(str(js_src_dir / "**/dist"), recursive=True)
19
-
20
- # Get the paths to all `node_modules` folders in the JS source directory
21
- node_modules_dirs = glob.glob(str(js_src_dir / "**/node_modules"), recursive=True)
22
-
23
- # Get the paths to all `tsconfig.tsbuildinfo` files in the JS source directory
24
- tsconfig_tsbuildinfo_files = glob.glob(
25
- str(js_src_dir / "**/tsconfig.tsbuildinfo"), recursive=True
26
- )
18
+ static_output_dir = pathlib.Path(__file__).parent.parent / "reactpy" / "static"
27
19
 
28
20
  # Delete all `dist` folders
21
+ dist_dirs = glob.glob(str(js_src_dir / "**/dist"), recursive=True)
29
22
  for dist_dir in dist_dirs:
30
23
  with contextlib.suppress(FileNotFoundError):
31
24
  shutil.rmtree(dist_dir)
32
25
 
33
26
  # Delete all `node_modules` folders
27
+ node_modules_dirs = glob.glob(str(js_src_dir / "**/node_modules"), recursive=True)
34
28
  for node_modules_dir in node_modules_dirs:
35
29
  with contextlib.suppress(FileNotFoundError):
36
30
  shutil.rmtree(node_modules_dir)
37
31
 
38
32
  # Delete all `tsconfig.tsbuildinfo` files
33
+ tsconfig_tsbuildinfo_files = glob.glob(
34
+ str(js_src_dir / "**/tsconfig.tsbuildinfo"), recursive=True
35
+ )
39
36
  for tsconfig_tsbuildinfo_file in tsconfig_tsbuildinfo_files:
40
37
  with contextlib.suppress(FileNotFoundError):
41
38
  os.remove(tsconfig_tsbuildinfo_file)
39
+
40
+ # Delete all `index-*.js` files
41
+ index_js_files = glob.glob(str(static_output_dir / "index-*.js*"))
42
+ for index_js_file in index_js_files:
43
+ with contextlib.suppress(FileNotFoundError):
44
+ os.remove(index_js_file)
@@ -31,6 +31,7 @@ if __name__ == "__main__":
31
31
  root_dir = Path(__file__).parent.parent.parent
32
32
  src = Path(root_dir / sys.argv[1])
33
33
  dest = Path(root_dir / sys.argv[2])
34
+ print(f"Copying files from '{sys.argv[1]}' to '{sys.argv[2]}'...") # noqa: T201
34
35
 
35
36
  if not src.exists():
36
37
  logging.error("Source directory %s does not exist", src)
@@ -0,0 +1,21 @@
1
+ # /// script
2
+ # requires-python = ">=3.11"
3
+ # dependencies = []
4
+ # ///
5
+
6
+ import logging
7
+ from glob import glob
8
+ from pathlib import Path
9
+
10
+ # Delete old `.coverage*` files in the project root
11
+ print("Deleting old coverage files...") # noqa: T201
12
+ root_dir = Path(__file__).parent.parent.parent
13
+ coverage_files = glob(str(root_dir / ".coverage*"))
14
+
15
+ for path in coverage_files:
16
+ coverage_file = Path(path)
17
+ if coverage_file.exists():
18
+ try:
19
+ coverage_file.unlink()
20
+ except Exception as e:
21
+ logging.error(f"Failed to delete {coverage_file}: {e}")
@@ -0,0 +1,17 @@
1
+ # /// script
2
+ # requires-python = ">=3.11"
3
+ # dependencies = []
4
+ # ///
5
+
6
+ import subprocess
7
+
8
+ print("Installing Playwright browsers...") # noqa: T201
9
+
10
+ # Install Chromium browser for Playwright, and fail if it cannot be installed
11
+ subprocess.run(["playwright", "install", "chromium"], check=True) # noqa: S607
12
+
13
+ # Try to install system dependencies. We don't generate an exception if this fails
14
+ # as *nix systems (such as WSL) return a failure code if there are *any* dependencies
15
+ # that could be cleaned up via `sudo apt autoremove`. This occurs even if we weren't
16
+ # the ones to install those dependencies in the first place.
17
+ subprocess.run(["playwright", "install-deps", "chromium"], check=False) # noqa: S607
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "workspaces": [
3
- "packages/*",
4
- "packages/@reactpy/*"
3
+ "packages/event-to-object",
4
+ "packages/@reactpy/app",
5
+ "packages/@reactpy/client"
5
6
  ],
6
7
  "catalog": {
7
8
  "preact": "^10.27.2",
@@ -15,12 +15,6 @@
15
15
  "moduleResolution": "bundler",
16
16
  "noEmitOnError": true,
17
17
  "noUnusedLocals": true,
18
- "paths": {
19
- "react": ["./node_modules/preact/compat/"],
20
- "react-dom": ["./node_modules/preact/compat/"],
21
- "react-dom/*": ["./node_modules/preact/compat/*"],
22
- "react/jsx-runtime": ["./node_modules/preact/jsx-runtime"]
23
- },
24
18
  "resolveJsonModule": true,
25
19
  "skipLibCheck": true,
26
20
  "sourceMap": true,
@@ -1,4 +1,4 @@
1
- from reactpy import config, logging, types, web, widgets
1
+ from reactpy import config, logging, reactjs, types, web, widgets
2
2
  from reactpy._html import html
3
3
  from reactpy.core import hooks
4
4
  from reactpy.core.component import component
@@ -19,11 +19,11 @@ from reactpy.core.hooks import (
19
19
  use_state,
20
20
  )
21
21
  from reactpy.core.vdom import Vdom
22
- from reactpy.pyscript.components import pyscript_component
22
+ from reactpy.executors.pyscript.components import pyscript_component
23
23
  from reactpy.utils import Ref, reactpy_to_string, string_to_reactpy
24
24
 
25
25
  __author__ = "The Reactive Python Team"
26
- __version__ = "2.0.0b5"
26
+ __version__ = "2.0.0b7"
27
27
 
28
28
  __all__ = [
29
29
  "Ref",
@@ -36,6 +36,7 @@ __all__ = [
36
36
  "html",
37
37
  "logging",
38
38
  "pyscript_component",
39
+ "reactjs",
39
40
  "reactpy_to_string",
40
41
  "string_to_reactpy",
41
42
  "types",
@@ -6,7 +6,6 @@ from typing import ClassVar, overload
6
6
  from reactpy.core.vdom import Vdom
7
7
  from reactpy.types import (
8
8
  EventHandlerDict,
9
- Key,
10
9
  VdomAttributes,
11
10
  VdomChild,
12
11
  VdomChildren,
@@ -14,7 +13,7 @@ from reactpy.types import (
14
13
  VdomDict,
15
14
  )
16
15
 
17
- __all__ = ["html"]
16
+ __all__ = ["h", "html"]
18
17
 
19
18
  NO_CHILDREN_ALLOWED_HTML_BODY = {
20
19
  "area",
@@ -100,12 +99,10 @@ NO_CHILDREN_ALLOWED_SVG = {
100
99
  def _fragment(
101
100
  attributes: VdomAttributes,
102
101
  children: Sequence[VdomChild],
103
- key: Key | None,
104
102
  event_handlers: EventHandlerDict,
105
103
  ) -> VdomDict:
106
104
  """An HTML fragment - this element will not appear in the DOM"""
107
- attributes.pop("key", None)
108
- if attributes or event_handlers:
105
+ if any(k != "key" for k in attributes) or event_handlers:
109
106
  msg = "Fragments cannot have attributes besides 'key'"
110
107
  raise TypeError(msg)
111
108
  model = VdomDict(tagName="")
@@ -113,8 +110,8 @@ def _fragment(
113
110
  if children:
114
111
  model["children"] = children
115
112
 
116
- if key is not None:
117
- model["key"] = key
113
+ if attributes:
114
+ model["attributes"] = attributes
118
115
 
119
116
  return model
120
117
 
@@ -122,7 +119,6 @@ def _fragment(
122
119
  def _script(
123
120
  attributes: VdomAttributes,
124
121
  children: Sequence[VdomChild],
125
- key: Key | None,
126
122
  event_handlers: EventHandlerDict,
127
123
  ) -> VdomDict:
128
124
  """Create a new `<script> <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script>`__ element.
@@ -148,6 +144,8 @@ def _script(
148
144
  msg = "'script' elements do not support event handlers"
149
145
  raise ValueError(msg)
150
146
 
147
+ key = attributes.get("key")
148
+
151
149
  if children:
152
150
  if len(children) > 1:
153
151
  msg = "'script' nodes may have, at most, one child."
@@ -165,7 +163,9 @@ def _script(
165
163
  key = attributes["src"]
166
164
 
167
165
  if key is not None:
168
- model["key"] = key
166
+ if "attributes" not in model:
167
+ model["attributes"] = {}
168
+ model["attributes"]["key"] = key
169
169
 
170
170
  return model
171
171
 
@@ -287,6 +287,7 @@ class HtmlConstructor:
287
287
  "fragment": Vdom("", custom_constructor=_fragment),
288
288
  "svg": SvgConstructor(),
289
289
  }
290
+ __call__ = __cache__["fragment"].__call__
290
291
 
291
292
  def __getattr__(self, value: str) -> VdomConstructor:
292
293
  value = value.rstrip("_").replace("_", "-")
@@ -423,3 +424,4 @@ class HtmlConstructor:
423
424
 
424
425
 
425
426
  html = HtmlConstructor()
427
+ h = html # shorthand alias for html
@@ -77,7 +77,7 @@ set of publicly available APIs for working with the client.
77
77
 
78
78
  REACTPY_TESTS_DEFAULT_TIMEOUT = Option(
79
79
  "REACTPY_TESTS_DEFAULT_TIMEOUT",
80
- 10.0,
80
+ 15.0,
81
81
  mutable=False,
82
82
  validator=float,
83
83
  )
@@ -33,7 +33,10 @@ class _HookStack(Singleton): # nocov
33
33
  )
34
34
 
35
35
  def get(self) -> list[LifeCycleHook]:
36
- return self._state.get()
36
+ try:
37
+ return self._state.get()
38
+ except LookupError:
39
+ return []
37
40
 
38
41
  def initialize(self) -> Token[list[LifeCycleHook]] | None:
39
42
  return None if isinstance(self._state, ThreadLocal) else self._state.set([])
@@ -8,7 +8,7 @@ _StateType = TypeVar("_StateType")
8
8
 
9
9
  class ThreadLocal(Generic[_StateType]): # nocov
10
10
  """Utility for managing per-thread state information. This is only used in
11
- environments where ContextVars are not available, such as the `pyodide`
11
+ environments where ContextVars are not available, such as the `pyscript`
12
12
  executor."""
13
13
 
14
14
  def __init__(self, default: Callable[[], _StateType]):
@@ -84,11 +84,7 @@ class _CurrentState(Generic[_Type]):
84
84
  self,
85
85
  initial_value: _Type | Callable[[], _Type],
86
86
  ) -> None:
87
- if callable(initial_value):
88
- self.value = initial_value()
89
- else:
90
- self.value = initial_value
91
-
87
+ self.value = initial_value() if callable(initial_value) else initial_value
92
88
  hook = HOOK_STACK.current_hook()
93
89
 
94
90
  def dispatch(new: _Type | Callable[[_Type], _Type]) -> None:
@@ -434,10 +430,7 @@ def use_callback(
434
430
  def setup(function: _CallbackFunc) -> _CallbackFunc:
435
431
  return memoize(lambda: function)
436
432
 
437
- if function is not None:
438
- return setup(function)
439
- else:
440
- return setup
433
+ return setup(function) if function is not None else setup
441
434
 
442
435
 
443
436
  class _LambdaCaller(Protocol):
@@ -553,17 +546,16 @@ def _try_to_infer_closure_values(
553
546
  func: Callable[..., Any] | None,
554
547
  values: Sequence[Any] | ellipsis | None,
555
548
  ) -> Sequence[Any] | None:
556
- if values is ...:
557
- if isinstance(func, FunctionType):
558
- return (
559
- [cell.cell_contents for cell in func.__closure__]
560
- if func.__closure__
561
- else []
562
- )
563
- else:
564
- return None
565
- else:
549
+ if values is not ...:
566
550
  return values
551
+ if isinstance(func, FunctionType):
552
+ return (
553
+ [cell.cell_contents for cell in func.__closure__]
554
+ if func.__closure__
555
+ else []
556
+ )
557
+ else:
558
+ return None
567
559
 
568
560
 
569
561
  def strictly_equal(x: Any, y: Any) -> bool: