blu-react 0.0.2__tar.gz → 0.0.3__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 (227) hide show
  1. blu_react-0.0.3/CHANGELOG.md +18 -0
  2. {blu_react-0.0.2 → blu_react-0.0.3}/PKG-INFO +2 -3
  3. {blu_react-0.0.2 → blu_react-0.0.3}/docs/_includes/client-element-children.rst +1 -1
  4. {blu_react-0.0.2 → blu_react-0.0.3}/docs/_includes/client-side-rendering-notes.rst +18 -6
  5. {blu_react-0.0.2 → blu_react-0.0.3}/docs/_includes/iterables-must-use-keys-note.rst +1 -1
  6. {blu_react-0.0.2 → blu_react-0.0.3}/docs/api-reference/blu.html.rst +2 -1
  7. {blu_react-0.0.2 → blu_react-0.0.3}/docs/api-reference/cli.rst +1 -1
  8. {blu_react-0.0.2 → blu_react-0.0.3}/docs/api-reference/file-conventions.rst +96 -27
  9. {blu_react-0.0.2 → blu_react-0.0.3}/docs/api-reference/index.rst +1 -1
  10. blu_react-0.0.3/docs/api-reference/js.rst +35 -0
  11. blu_react-0.0.3/docs/api-reference/pyodide.rst +36 -0
  12. blu_react-0.0.3/docs/appendices/choosing-an-interpreter.rst +28 -0
  13. blu_react-0.0.3/docs/appendices/index.rst +10 -0
  14. {blu_react-0.0.2 → blu_react-0.0.3}/docs/conf.py +2 -0
  15. {blu_react-0.0.2 → blu_react-0.0.3}/docs/contributing.rst +4 -2
  16. {blu_react-0.0.2 → blu_react-0.0.3}/docs/index.rst +1 -0
  17. {blu_react-0.0.2 → blu_react-0.0.3}/docs/install.rst +0 -2
  18. {blu_react-0.0.2 → blu_react-0.0.3}/docs/quickstart.rst +2 -2
  19. blu_react-0.0.3/docs/requirements.txt +2 -0
  20. {blu_react-0.0.2 → blu_react-0.0.3}/docs/user-guide/client-side-rendering.rst +4 -4
  21. {blu_react-0.0.2 → blu_react-0.0.3}/docs/user-guide/creating-pages.rst +3 -3
  22. {blu_react-0.0.2 → blu_react-0.0.3}/docs/user-guide/deploying-your-app.rst +1 -1
  23. {blu_react-0.0.2 → blu_react-0.0.3}/docs/user-guide/routing.rst +8 -10
  24. {blu_react-0.0.2 → blu_react-0.0.3}/docs/user-guide/static-files.rst +1 -1
  25. {blu_react-0.0.2 → blu_react-0.0.3}/pyproject.toml +3 -2
  26. blu_react-0.0.3/scripts/profile_asgi_request.py +176 -0
  27. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/__init__.py +2 -3
  28. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_app/__init__.py +28 -17
  29. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_app/render.py +29 -38
  30. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_app/router.py +58 -28
  31. blu_react-0.0.3/src/blu/_blu_static_files/micropython-bootstrap.js +65 -0
  32. blu_react-0.0.3/src/blu/_blu_static_files/micropython.mjs +6711 -0
  33. blu_react-0.0.3/src/blu/_blu_static_files/micropython.wasm +0 -0
  34. blu_react-0.0.3/src/blu/_blu_static_files/pyodide-bootstrap.js +26 -0
  35. {blu_react-0.0.2/src/blu → blu_react-0.0.3/src/blu/_blu_static_files}/util.js +23 -8
  36. blu_react-0.0.3/src/blu/_client_main/micropython.py +143 -0
  37. blu_react-0.0.3/src/blu/_client_main/pyodide.py +38 -0
  38. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_hooks.py +115 -126
  39. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_http.py +3 -3
  40. blu_react-0.0.3/src/blu/_mPickle/manifest.py +40 -0
  41. blu_react-0.0.3/src/blu/_mPickle/mpickle/__init__.py +61 -0
  42. blu_react-0.0.3/src/blu/_mPickle/mpickle/_compat_pickle.py +270 -0
  43. blu_react-0.0.3/src/blu/_mPickle/mpickle/codecs.py +106 -0
  44. blu_react-0.0.3/src/blu/_mPickle/mpickle/copyreg.py +304 -0
  45. blu_react-0.0.3/src/blu/_mPickle/mpickle/itertools.py +119 -0
  46. blu_react-0.0.3/src/blu/_mPickle/mpickle/mpickle.py +2695 -0
  47. blu_react-0.0.3/src/blu/_mPickle/mpickle/ubytesio.py +38 -0
  48. blu_react-0.0.3/src/blu/_micropython/abc.py +23 -0
  49. blu_react-0.0.3/src/blu/_micropython/typing.py +36 -0
  50. blu_react-0.0.3/src/blu/_micropython/utils.py +121 -0
  51. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_nodes.py +55 -55
  52. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_server_functions.py +50 -32
  53. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_settings.py +2 -2
  54. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_utils/__init__.py +1 -0
  55. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_utils/asgi.py +8 -1
  56. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_utils/asyncio.py +23 -19
  57. blu_react-0.0.3/src/blu/_utils/client.py +10 -0
  58. blu_react-0.0.3/src/blu/html.py +270 -0
  59. blu_react-0.0.3/tests/apps/def_extra_query_params/__default__.py +2 -0
  60. blu_react-0.0.3/tests/apps/def_pos_only_path_param/__default__.py +2 -0
  61. blu_react-0.0.3/tests/apps/def_query/__default__.py +2 -0
  62. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/def_query_kwarg/__default__.py +1 -1
  63. blu_react-0.0.3/tests/apps/def_query_params_default/__default__.py +2 -0
  64. blu_react-0.0.3/tests/apps/def_route_and_query/_a_/_b_/__default__.py +2 -0
  65. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/routing/_a_/__index__.py +1 -1
  66. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/use_effect/__index__.py +6 -2
  67. blu_react-0.0.3/tests/apps/e2e_settings/__index__.py +19 -0
  68. blu_react-0.0.3/tests/apps/e2e_settings/__settings__.py +1 -0
  69. {blu_react-0.0.2/tests/apps/e2e_settings → blu_react-0.0.3/tests/apps/e2e_settings_pyodide}/__settings__.py +2 -0
  70. blu_react-0.0.3/tests/apps/e2e_simple_app/__index__.py +5 -0
  71. blu_react-0.0.3/tests/apps/e2e_simple_app/a/module.py +3 -0
  72. blu_react-0.0.3/tests/apps/index_query_abc/__index__.py +2 -0
  73. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/index_query_kwargs/__index__.py +1 -1
  74. blu_react-0.0.3/tests/apps/index_route_and_query/_a_/_b_/__index__.py +2 -0
  75. {blu_react-0.0.2 → blu_react-0.0.3}/tests/conftest.py +34 -6
  76. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/file_conventions/special_files/test_default.py +0 -21
  77. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/file_conventions/special_files/test_index.py +0 -21
  78. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/file_conventions/special_files/test_settings.py +2 -8
  79. {blu_react-0.0.2 → blu_react-0.0.3}/tests/test_e2e.py +53 -52
  80. {blu_react-0.0.2 → blu_react-0.0.3}/tests/utils.py +10 -1
  81. {blu_react-0.0.2 → blu_react-0.0.3}/uv.lock +20 -5
  82. blu_react-0.0.2/docs/api-reference/js.rst +0 -35
  83. blu_react-0.0.2/docs/api-reference/pyscript.rst +0 -38
  84. blu_react-0.0.2/docs/requirements.txt +0 -1
  85. blu_react-0.0.2/src/blu/_app/client_main.py +0 -159
  86. blu_react-0.0.2/src/blu/_utils/client.py +0 -3
  87. blu_react-0.0.2/src/blu/_utils/typing.py +0 -33
  88. blu_react-0.0.2/src/blu/html.py +0 -91
  89. blu_react-0.0.2/tests/apps/def_extra_query_params/__default__.py +0 -2
  90. blu_react-0.0.2/tests/apps/def_pos_only_path_param/__default__.py +0 -2
  91. blu_react-0.0.2/tests/apps/def_pos_only_underscore/__default__.py +0 -2
  92. blu_react-0.0.2/tests/apps/def_query/__default__.py +0 -2
  93. blu_react-0.0.2/tests/apps/def_query_params_default/__default__.py +0 -2
  94. blu_react-0.0.2/tests/apps/def_route_and_query/_a_/_b_/__default__.py +0 -2
  95. blu_react-0.0.2/tests/apps/default_single_underscore/__default__.py +0 -2
  96. blu_react-0.0.2/tests/apps/e2e/async_effect/__index__.py +0 -45
  97. blu_react-0.0.2/tests/apps/e2e/client_import/__index__.py +0 -14
  98. blu_react-0.0.2/tests/apps/index_pos_only_underscore/__index__.py +0 -2
  99. blu_react-0.0.2/tests/apps/index_query_abc/__index__.py +0 -2
  100. blu_react-0.0.2/tests/apps/index_route_and_query/_a_/_b_/__index__.py +0 -2
  101. blu_react-0.0.2/tests/apps/index_single_underscore/__index__.py +0 -2
  102. {blu_react-0.0.2 → blu_react-0.0.3}/.gitignore +0 -0
  103. {blu_react-0.0.2 → blu_react-0.0.3}/.pre-commit-config.yaml +0 -0
  104. {blu_react-0.0.2 → blu_react-0.0.3}/.readthedocs.yaml +0 -0
  105. {blu_react-0.0.2 → blu_react-0.0.3}/.vscode/launch.json +0 -0
  106. {blu_react-0.0.2 → blu_react-0.0.3}/.vscode/settings.json +0 -0
  107. {blu_react-0.0.2 → blu_react-0.0.3}/LICENSE +0 -0
  108. {blu_react-0.0.2 → blu_react-0.0.3}/README.md +0 -0
  109. {blu_react-0.0.2 → blu_react-0.0.3}/docs/Makefile +0 -0
  110. {blu_react-0.0.2 → blu_react-0.0.3}/docs/_img/cursor_code_completion.png +0 -0
  111. {blu_react-0.0.2 → blu_react-0.0.3}/docs/_img/directly_manipulating_rendered_elements.gif +0 -0
  112. {blu_react-0.0.2 → blu_react-0.0.3}/docs/_img/effect_cleanup.gif +0 -0
  113. {blu_react-0.0.2 → blu_react-0.0.3}/docs/_img/perform_an_action_immediately_after_rendering.gif +0 -0
  114. {blu_react-0.0.2 → blu_react-0.0.3}/docs/_img/responding_to_user_interaction.gif +0 -0
  115. {blu_react-0.0.2 → blu_react-0.0.3}/docs/_includes/client-element-call-notes.rst +0 -0
  116. {blu_react-0.0.2 → blu_react-0.0.3}/docs/_includes/hook-note.rst +0 -0
  117. {blu_react-0.0.2 → blu_react-0.0.3}/docs/_includes/hooks.rst +0 -0
  118. {blu_react-0.0.2 → blu_react-0.0.3}/docs/_static/styles.css +0 -0
  119. {blu_react-0.0.2 → blu_react-0.0.3}/docs/_templates/layout.html +0 -0
  120. {blu_react-0.0.2 → blu_react-0.0.3}/docs/api-reference/blu.rst +0 -0
  121. {blu_react-0.0.2 → blu_react-0.0.3}/docs/make.bat +0 -0
  122. {blu_react-0.0.2 → blu_react-0.0.3}/docs/user-guide/index.rst +0 -0
  123. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_cli.py +0 -0
  124. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_exceptions.py +0 -0
  125. {blu_react-0.0.2 → blu_react-0.0.3}/src/blu/_utils/json.py +0 -0
  126. {blu_react-0.0.2 → blu_react-0.0.3}/tests/__init__.py +0 -0
  127. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/app_module_reject/module.py +0 -0
  128. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/basic/__index__.py +0 -0
  129. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/client_false/module.py +0 -0
  130. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/client_module/module.py +0 -0
  131. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/def_async_handler/__default__.py +0 -0
  132. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/def_empty_path_param/a/__default__.py +0 -0
  133. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/def_extra_route_params/__default__.py +0 -0
  134. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/def_missing_query_params/__default__.py +0 -0
  135. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/def_missing_route_params/_a_/_b_/_c_/__default__.py +0 -0
  136. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/default_extra_segment/a/__default__.py +0 -0
  137. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/default_full_match/a/_b_/c/__default__.py +0 -0
  138. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/default_incomplete_match/a/b/c/__default__.py +0 -0
  139. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/default_path_param/__default__.py +0 -0
  140. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/default_response_ret/__default__.py +0 -0
  141. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/default_route_params/_a_/_b_/_c_/__default__.py +0 -0
  142. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/default_specific_priority/_a_/__default__.py +0 -0
  143. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/default_specific_priority/_b_/c/__default__.py +0 -0
  144. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/dynamic_non_matching_static/_dynamic_/__index__.py +0 -0
  145. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/dynamic_non_matching_static/static/__index__.py +0 -0
  146. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/dynamic_segment/_segment_/__index__.py +0 -0
  147. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/dynamic_static_not_full_match/_dynamic_/bar/__index__.py +0 -0
  148. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/dynamic_static_not_full_match/foo/baz/__index__.py +0 -0
  149. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/app_pkg_clientside/fail/__index__.py +0 -0
  150. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/app_pkg_clientside/fail/element.py +0 -0
  151. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/app_pkg_clientside/fail/module.py +0 -0
  152. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/app_pkg_clientside/success/__index__.py +0 -0
  153. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/app_pkg_clientside/success/element.py +0 -0
  154. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/app_pkg_clientside/success/module.py +0 -0
  155. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/dev_server/__index__.py +0 -0
  156. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/html_editing_effect/__index__.py +0 -0
  157. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/is_client/__index__.py +0 -0
  158. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/rendering/__index__.py +0 -0
  159. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/routing/_a_/__default__.py +0 -0
  160. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/routing/_a_/_b_/__index__.py +0 -0
  161. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/routing/_a_/static/__index__.py +0 -0
  162. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/server_functions/__index__.py +0 -0
  163. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/server_functions/hello_module.py +0 -0
  164. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/server_functions/shared.py +0 -0
  165. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/static_file/_dynamic_path_/hello.txt +0 -0
  166. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/unusual_root_nodes/float/__index__.py +0 -0
  167. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/unusual_root_nodes/int/__index__.py +0 -0
  168. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/unusual_root_nodes/iterable/__index__.py +0 -0
  169. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/unusual_root_nodes/key/__index__.py +0 -0
  170. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/unusual_root_nodes/none/__index__.py +0 -0
  171. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/unusual_root_nodes/str/__index__.py +0 -0
  172. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/unusual_root_nodes/tuple/__index__.py +0 -0
  173. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/use_ref/__index__.py +0 -0
  174. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/use_state/__index__.py +0 -0
  175. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/wrong_environment_error/__index__.py +0 -0
  176. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/e2e/yield_in_tuple/__index__.py +0 -0
  177. {blu_react-0.0.2/tests/apps/e2e_settings → blu_react-0.0.3/tests/apps/e2e_settings_pyodide}/__index__.py +0 -0
  178. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/empty_settings/__index__.py +0 -0
  179. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/empty_settings/__settings__.py +0 -0
  180. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/index_abc/a/b/c/__index__.py +0 -0
  181. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/index_async_handler/__index__.py +0 -0
  182. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/index_dynamic_abc/_a_/_b_/_c_/__index__.py +0 -0
  183. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/index_extra_route_params/__index__.py +0 -0
  184. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/index_file_priority/_a_/c/__default__.py +0 -0
  185. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/index_file_priority/_b_/c/__index__.py +0 -0
  186. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/index_missing_route_params/_a_/__index__.py +0 -0
  187. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/index_response/__index__.py +0 -0
  188. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/leading_underscore/_path/__index__.py +0 -0
  189. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/literal_segment/path/__index__.py +0 -0
  190. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/multiple_dynamic/_a_/b/__index__.py +0 -0
  191. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/multiple_dynamic/_c_/d/__index__.py +0 -0
  192. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/nested_dynamic_segments/_first_/_second_/__index__.py +0 -0
  193. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/nested_literal_segments/path/to/view/__index__.py +0 -0
  194. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/server_function_arbitrary_function_call/server_functions.py +0 -0
  195. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/server_function_arbitrary_function_call/server_only_module.py +0 -0
  196. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/server_function_csrf/__index__.py +0 -0
  197. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/server_function_csrf/file.txt +0 -0
  198. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/server_function_csrf/server_functions.py +0 -0
  199. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/server_functions_outside_app/valid.py +0 -0
  200. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/settings_below_top_level/foo/__settings__.py +0 -0
  201. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/settings_multi_client_reqs/__settings__.py +0 -0
  202. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/settings_one_client_req/__settings__.py +0 -0
  203. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/static_dynamic_nested/static/_dynamic_/__index__.py +0 -0
  204. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/static_dynamic_priority/_dynamic_/__index__.py +0 -0
  205. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/static_dynamic_priority/static/__index__.py +0 -0
  206. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/static_files/path/to/static/file.txt +0 -0
  207. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/static_files_dynamic_path/_a_/file.txt +0 -0
  208. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/top_level_segment/__index__.py +0 -0
  209. {blu_react-0.0.2 → blu_react-0.0.3}/tests/apps/trailing_underscore/path_/__index__.py +0 -0
  210. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/blu/test_ClientElement.py +0 -0
  211. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/blu/test_HTMLElement.py +0 -0
  212. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/blu/test_Key.py +0 -0
  213. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/blu/test_Response.py +0 -0
  214. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/blu/test_app.py +0 -0
  215. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/blu/test_create_rare_html_element.py +0 -0
  216. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/blu/test_html.py +0 -0
  217. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/blu/test_is_client.py +0 -0
  218. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/blu/test_server.py +0 -0
  219. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/file_conventions/_utils.py +0 -0
  220. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/file_conventions/directories/test_literal_segment.py +0 -0
  221. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/file_conventions/directories/test_route_param_name.py +0 -0
  222. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/file_conventions/test_static_files.py +0 -0
  223. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/test_cli.py +0 -0
  224. {blu_react-0.0.2 → blu_react-0.0.3}/tests/fast/test_security.py +0 -0
  225. {blu_react-0.0.2 → blu_react-0.0.3}/tests/projects/basic/app/__index__.py +0 -0
  226. {blu_react-0.0.2 → blu_react-0.0.3}/tests/projects/quickstart/app/__index__.py +0 -0
  227. {blu_react-0.0.2 → blu_react-0.0.3}/tests/resources/server_fn_outside_app.py +0 -0
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ ## v0.0.3 - 2026-10-12
4
+
5
+ _Blu now uses MicroPython by default and no longer uses PyScript. If you are upgrading from v0.0.2, add `INTERPRETER = 'pyodide'` to your `__settings__.py` and remove any references to the `pyscript`._
6
+
7
+ ### Added
8
+
9
+ - Add support for MicroPython in client-side code.
10
+
11
+ ### Changed
12
+
13
+ - **Breaking** Use `*` instead of `/` to separate route parameters and query parameters in route handlers.
14
+ - **Breaking** Make MicroPython the default client-side Python interpreter (use previous default interpreter by adding `INTERPRETER = 'pyodide'` to `__settings__.py`).
15
+
16
+ ### Removed
17
+
18
+ - **Breaking** Remove support for async callbacks in `blu.use_effect()`.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: blu-react
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: A full stack React framework for Python
5
5
  Project-URL: Homepage, https://github.com/johnlarson/blu
6
6
  Project-URL: Documentation, https://blu-react.readthedocs.io
@@ -11,7 +11,6 @@ License-File: LICENSE
11
11
  Classifier: Operating System :: OS Independent
12
12
  Classifier: Programming Language :: Python :: 3
13
13
  Requires-Python: >=3.14
14
- Requires-Dist: aiofiles
15
14
  Requires-Dist: uvicorn
16
15
  Description-Content-Type: text/markdown
17
16
 
@@ -51,7 +51,7 @@ A child of an HTML element can be any of the following types:
51
51
  - A :py:class:`int`. This renders as a text node whose text is the :py:class:`str` representation of the integer.
52
52
  - A :py:class:`float`. This renders as a text node whose text is the :py:class:`str` representation of the float.
53
53
  - An :py:class:`Iterable <collections.abc.Iterable>` of valid children. This renders as all the child nodes contained in the :py:class:`Iterable <collections.abc.Iterable>`.
54
- - A :class:`blu.ClientElement` (see :ref:`Client-Side Rendering`).
54
+ - A :class:`blu.ClientElement` (see :ref:`user-guide/client-side-rendering:Client-Side Rendering`).
55
55
  - A :class:`blu.Key`.
56
56
 
57
57
  .. code-block:: python
@@ -41,6 +41,17 @@
41
41
  return p['Hello, World!']
42
42
 
43
43
 
44
+ .. note::
45
+
46
+ By default, Python code that runs on the client is run by the MicroPython interpreter. This means some features of Python are unavailable to modules that are used client-side. You can choose to use a more fully-featured but slower-loading Python interpreter called Pyodide by adding the following to ``app/__settings__.py``:
47
+
48
+ .. code-block:: python
49
+ :caption: app/__settings__.py
50
+
51
+ INTERPRETER = 'pyodide'
52
+
53
+ For more information, see :doc:`/appendices/choosing-an-interpreter`
54
+
44
55
  .. note::
45
56
 
46
57
  Client-side code runs in a different environment than server-side code. If your client-side code uses an external library, make sure it is installed in the client environment by adding it to the list of client dependencies in ``app/__settings__.py`` (if the ``__settings__.py`` doesn't exist, create it)::
@@ -52,7 +63,7 @@
52
63
  .. code-block:: python
53
64
  :caption: app/__index__.py
54
65
 
55
- import arrr
66
+ import base64
56
67
  from blu import client
57
68
 
58
69
  __client__ = True
@@ -64,15 +75,16 @@
64
75
 
65
76
  @client
66
77
  def MyClientElement():
67
- return p[
68
- arrr.translate('Hello there. How are you?')
78
+ return div[
79
+ p['Message: Hello, World!'],
80
+ p['Base64-encoded:', base64.encode('Hello, World!')],
69
81
  ]
70
82
 
71
83
 
72
84
  .. code-block:: python
73
85
  :caption: app/__settings__.py
74
86
 
75
- CLIENT_REQUIREMENTS = ['arrr']
87
+ CLIENT_REQUIREMENTS = ['base64']
76
88
 
77
89
 
78
90
  .. note::
@@ -86,7 +98,7 @@
86
98
  from blu import client
87
99
  from blu.html import button
88
100
 
89
- from pyscript import window
101
+ from js import window
90
102
 
91
103
  __client__ = True
92
104
 
@@ -111,7 +123,7 @@
111
123
  from blu.html import button
112
124
 
113
125
  if is_client:
114
- from pyscript import window
126
+ from js import window
115
127
 
116
128
  __client__ = True
117
129
 
@@ -56,4 +56,4 @@
56
56
  # Right.
57
57
  div['Hello, Ana! Hello, Bill! Hello, Charlotte!']
58
58
 
59
- The rationale here is that, in :ref:`client-side rendering <Client-Side Rendering>`, items in a sequence may be moved around in response to user interaction. Giving keys to these items allows React to maintain state and render efficiently even when an item's position in a sequence changes.
59
+ The rationale here is that, in :ref:`client-side rendering <user-guide/client-side-rendering:Client-Side Rendering>`, items in a sequence may be moved around in response to user interaction. Giving keys to these items allows React to maintain state and render efficiently even when an item's position in a sequence changes.
@@ -1,4 +1,5 @@
1
1
  ``blu.html``
2
2
  ============
3
3
  .. automodule:: blu.html
4
- :special-members: __getattr__
4
+
5
+ .. autofunction:: blu.html.__getattr__
@@ -15,4 +15,4 @@ The deveopment server will automatically find an available port to run on, and o
15
15
 
16
16
  INFO: Uvicorn running on http://127.0.0.1:50227 (Press CTRL+C to quit)
17
17
 
18
- Don't run the development server in production. See :ref:`Deploying Your App` for details on how to deploy an app to a production environment.
18
+ Don't run the development server in production. See :ref:`user-guide/deploying-your-app:Deploying Your App` for details on how to deploy an app to a production environment.
@@ -1,11 +1,11 @@
1
1
  File Conventions
2
2
  ================
3
3
 
4
- A Blu app is defined by the :ref:`special files <Special Files>` under its ``app/`` directory. The ``app/`` directory should be placed in the project root (this is the working directory where you run the development server using the ``blu`` command).
4
+ A Blu app is defined by the :ref:`special files <api-reference/file-conventions:Special Files>` under its ``app/`` directory. The ``app/`` directory should be placed in the project root (this is the working directory where you run the development server using the ``blu`` command).
5
5
 
6
- Note that some special files' behavior is influenced by :ref:`the directories in their paths <Directories>`, relative to the ``app/`` directory.
6
+ Note that some special files' behavior is influenced by :ref:`the directories in their paths <api-reference/file-conventions:Directories>`, relative to the ``app/`` directory.
7
7
 
8
- You can also put :ref:`static files <Static Files>` in the ``app/`` directory.
8
+ You can also put :ref:`static files <api-reference/file-conventions:Static Files>` in the ``app/`` directory.
9
9
 
10
10
 
11
11
  Directories
@@ -92,10 +92,10 @@ Handles a request whose full URL matches all directories in the path to this fil
92
92
  /foo/some/other/path
93
93
  /foo/bar/extra/segments
94
94
 
95
- Top-level functions
96
- ^^^^^^^^^^^^^^^^^^^
95
+ An __index__.py file should have the following top-level function:
97
96
 
98
97
  .. py:function:: __page__(***url) -> blu.Node | blu.Response
98
+ :no-index:
99
99
 
100
100
  Handle a request whose URL path is matched by this file.
101
101
 
@@ -105,7 +105,7 @@ Top-level functions
105
105
  from blu.html import p
106
106
 
107
107
 
108
- def __page__(slug, /, q):
108
+ def __page__(slug, *, q):
109
109
  return (
110
110
  p['The slug value is: ', slug],
111
111
  p['The query param value is: ', q],
@@ -148,11 +148,10 @@ Handles a request for which the directories in the path to this file from the ``
148
148
  /
149
149
  /hello
150
150
 
151
- Top-level functions
152
- ^^^^^^^^^^^^^^^^^^^
153
-
151
+ A __default__.py file should have the following top-level function:
154
152
 
155
153
  .. py:function:: __page__(***url) -> blu.Node | blu.Response
154
+ :no-index:
156
155
 
157
156
  Handle a request whose URL path is matched by this file.
158
157
 
@@ -162,7 +161,7 @@ Top-level functions
162
161
  from blu.html import p
163
162
 
164
163
 
165
- def __page__(slug, path__, /, q):
164
+ def __page__(slug, path__, *, q):
166
165
  return (
167
166
  p['The slug value is: ', slug],
168
167
  p['The remaining path is: ', path],
@@ -189,14 +188,14 @@ __settings__.py
189
188
 
190
189
  Configuration for your Blu app.
191
190
 
192
- Should be placed in the root of the ``app/`` directory, i.e. the app directory should be the immediate parent of __settings__.py.
193
-
194
191
  .. code-block:: python
195
192
  :caption: app/__settings__.py
196
193
 
194
+ INTERPRETER = 'pyodide'
195
+
197
196
  CLIENT_REQUIREMENTS = ['arrr', 'aiohttp']
198
197
 
199
- You can configure your Blu app by creating a __settings__.py file and assigning configuration values at the top level of the file. For example, the __settings__.py file above sets the ``CLIENT_REQUIREMENTS`` configuration property to ``['arrr', 'aiohttp']``.
198
+ Must be placed in the root of the ``app/`` directory, i.e. the app directory must be the immediate parent of __settings__.py.
200
199
 
201
200
  A __settings__.py file is not required, and an app without a __settings__.py file will be treated the same as an app whose __settings__.py is empty.
202
201
 
@@ -205,16 +204,36 @@ A __settings__.py file can have any of the following settings:
205
204
  .. data:: CLIENT_REQUIREMENTS
206
205
  :type: list[str]
207
206
  :value: []
207
+
208
+ The Python libraries that Blu should install in the client environment.
208
209
 
209
210
  .. code-block:: python
210
211
 
211
- CLIENT_REQUIREMENTS = ['arrr', 'aiohttp']
212
+ CLIENT_REQUIREMENTS = ['abc', 'io']
213
+
214
+ If using the default Python interpreter, ``CLIENT_REQUIREMENTS`` can include any packages from the `micropython-lib repository <https://github.com/micropython/micropython-lib>`_, under the ``python-stdlib/``, ``python-ecosys/``, ``micropython/``, or ``unix-ffi/`` directories.
215
+
216
+ .. code-block:: python
217
+
218
+ CLIENT_REQUIREMENTS = ['bluetooth', 'io']
219
+
220
+ If :doc:`opting in to Pyodide </appendices/choosing-an-interpreter>`, ``CLIENT_REQUIREMENTS`` can include any values that can be passed in as requirements to Pyodide's `micropip.install() <https://micropip.pyodide.org/en/stable/project/api.html#micropip.install>`_ function.
221
+
222
+ .. code-block:: python
223
+
224
+ CLIENT_REQUIREMENTS = ['arrr', 'emoji']
225
+
226
+ .. data:: INTERPRETER
227
+ :type: typing.Literal['micropython', 'pyodide']
228
+ :value: 'micropython'
212
229
 
213
- The Python libraries that Blu should install in the client environment. For example, if you have code running client-side that uses `aiohttp <https://pypi.org/project/aiohttp/>`_, you must add aiohttp to the client-side requirements:
230
+ The Python interpreter to use for client-side code.
214
231
 
215
232
  .. code-block:: python
216
233
 
217
- CLIENT_REQUIREMENTS = ['aiohttp']
234
+ INTERPRETER = 'pyodide'
235
+
236
+ See :doc:`/appendices/choosing-an-interpreter` for more details.
218
237
 
219
238
 
220
239
  .. _file-conventions/files/what-does-triple-star-url-mean:
@@ -251,16 +270,16 @@ You can capture route parameters from dynamic route segments by passing them in
251
270
  Capturing query parameters
252
271
  ^^^^^^^^^^^^^^^^^^^^^^^^^^
253
272
 
254
- Any arguments specified after ``/`` in your call signature will capture query parameters instead of route parameters:
273
+ Any arguments specified after ``*`` in your call signature will capture query parameters instead of route parameters:
255
274
 
256
275
  .. code-block:: python
257
276
  :caption: app/_id_/__index__.py
258
277
 
259
278
  from blu.html import p
260
279
 
261
- def __page__(id, /, foo):
280
+ def __page__(id, *, foo):
262
281
  return (
263
- p['ID: ', id],
282
+ p['ID:', id],
264
283
  p['foo:', foo],
265
284
  )
266
285
 
@@ -271,7 +290,7 @@ Any arguments specified after ``/`` in your call signature will capture query pa
271
290
  <p>foo: 3</p>
272
291
 
273
292
 
274
- Python doesn't allow a ``/`` at the beginning of the call signature, so use ``_`` (single underscore) before the ``/`` if there are no route parameters:
293
+ You can capture query parameters without route parameters:
275
294
 
276
295
  .. code-block:: python
277
296
  :caption: app/greet_me/__index__.py
@@ -279,7 +298,7 @@ Python doesn't allow a ``/`` at the beginning of the call signature, so use ``_`
279
298
  from blu.html import p
280
299
 
281
300
 
282
- def __page__(_, /, my_name):
301
+ def __page__(*, my_name):
283
302
  return p['Hello ', my_name, '!']
284
303
 
285
304
  .. code-block:: html
@@ -295,7 +314,7 @@ You can set default values for query parameters:
295
314
  from blu.html import p
296
315
 
297
316
 
298
- def __page__(_, /, my_name='World'):
317
+ def __page__(*, my_name='World'):
299
318
  return p['Hello ', my_name, '!']
300
319
 
301
320
  .. code-block:: html
@@ -311,7 +330,57 @@ You can also use ``**kwargs`` for query parameters:
311
330
  from blu.html import p
312
331
 
313
332
 
314
- def __page__(_, /, my_name, **kwargs):
333
+ def __page__(**kwargs):
334
+ greeting = kwargs.get('greeting', 'Hello')
335
+ return p[greeting, '!']
336
+
337
+ .. code-block:: html
338
+ :caption: GET /greet_me?greeting=Hi
339
+
340
+ <p>Hi!</p>
341
+
342
+ .. note::
343
+
344
+ If you capture query parameters using ``**kwargs`` while also capturing route paramaters, use ``/`` to avoid name collisions:
345
+
346
+ .. code-block:: python
347
+ :caption: app/show_params/__index__.py
348
+
349
+ from blu.html import p
350
+
351
+
352
+ def __page__(x, /, **kwargs):
353
+ return p[
354
+ div['x: ', x],
355
+ div['**kwargs:'],
356
+ ul[
357
+ li[f'{k}: ', v] for k, v in **kwargs
358
+ ],
359
+ ]
360
+
361
+ .. code-block:: html
362
+ :caption: GET /show_params/A?x=1&y=2&z=3
363
+
364
+ <p>
365
+ <div>x: A</div>
366
+ <div>**kwargs:</div>
367
+ <ul>
368
+ <li>x: 1</li>
369
+ <li>y: 2</li>
370
+ <li>z: 3</li>
371
+ </ul>
372
+ </p>
373
+
374
+
375
+ This can also be paired with non-``**kwarg`` query parameters:
376
+
377
+ .. code-block:: python
378
+ :caption: app/greet_me/__index__.py
379
+
380
+ from blu.html import p
381
+
382
+
383
+ def __page__(*, my_name, **kwargs):
315
384
  greeting = kwargs.get('greeting', 'Hello')
316
385
  return p[greeting, ' ', my_name, '!']
317
386
 
@@ -339,18 +408,18 @@ Since a call to a ``__page__`` handler in a ``__default__.py`` file usually resu
339
408
 
340
409
  <p>Remaining path: bar/baz</p>
341
410
 
342
- This can be used alongside route parameters and query parameters. In this case, it should come before the ``/``:
411
+ This can be used alongside route parameters and query parameters. In this case, it should come before the ``*``:
343
412
 
344
413
  .. code-block:: python
345
414
  :caption: app/_id_/__default__.py
346
415
 
347
416
  from blu.html import p
348
417
 
349
- def __page__(id, path__, /, baz):
418
+ def __page__(id, path__, *, baz):
350
419
  return (
351
420
  p['ID: ', id],
352
- p['Remaining path:', __],
353
- p['baz:', baz],
421
+ p['Remaining path: ', path__],
422
+ p['baz: ', baz],
354
423
  )
355
424
 
356
425
  .. code-block:: html
@@ -8,6 +8,6 @@ API Reference
8
8
  blu
9
9
  blu.html
10
10
  js
11
- pyscript
11
+ pyodide
12
12
  file-conventions
13
13
  cli
@@ -0,0 +1,35 @@
1
+ ``js`` (client-only)
2
+ ====================
3
+
4
+ The JavaScript global scope is available in the client-side Python environment through the ``js`` module:
5
+
6
+ .. code-block:: python
7
+
8
+ from blu import is_client
9
+
10
+ __client__ = True
11
+
12
+
13
+ if is_client:
14
+ from js import Promise, addEventListener, alert, document
15
+
16
+
17
+ .. note::
18
+
19
+ ``js`` can only be imported in a client context.
20
+
21
+ .. code-block:: python
22
+
23
+ from blu import is_client
24
+
25
+ # Wrong!
26
+ from js import document
27
+
28
+ # Right.
29
+ if is_client:
30
+ from js import document
31
+
32
+
33
+ By default, Blu runs Python on the client using the MicroPython interpreter. You can view MicroPython's documentation on `in-browser type conversions <https://github.com/micropython/micropython/blob/master/ports/webassembly/README.md#proxying>`_ to learn how JavaScript types are converted into Python.
34
+
35
+ If you :doc:`opt in to using Pyodide </appendices/choosing-an-interpreter>` as your client-side Python interpreter, you can learn about Pyodide's type conversions `here <https://pyodide.org/en/stable/usage/type-conversions.html>`_.
@@ -0,0 +1,36 @@
1
+ .. _pyscript:
2
+
3
+ ``pyodide`` (opt-in)
4
+ ====================
5
+
6
+ By default, Blu uses MicroPython as its client-side Python interpreter. However, you can also :doc:`opt in to using Pyodide </appendices/choosing-an-interpreter>` as your Python interpreter.
7
+
8
+ Pyodide provides an additional client-side package called ``pyodide``, which provides utilities for using Python in the browser.
9
+
10
+ .. code-block:: python
11
+
12
+ from blu import is_client
13
+
14
+ if is_client:
15
+ from pyodide.http import pyfetch
16
+
17
+ response = await pyfetch('https://www.example.com/api/v2/data')
18
+ print(await response.json())
19
+
20
+ .. note::
21
+
22
+ The ``pyodide`` package can only be imported in a client context.
23
+
24
+ .. code-block:: python
25
+
26
+ from blu import is_client
27
+
28
+ # Wrong!
29
+ from pyodide.http import pyfetch
30
+
31
+ # Right.
32
+ if is_client:
33
+ from pyodide.http import pyfetch
34
+
35
+
36
+ For more information on the ``pyodide`` package, see the package's official `API reference <https://pyodide.org/en/stable/usage/api/python-api.html>`_.
@@ -0,0 +1,28 @@
1
+ .. _choosing-an-interpreter:
2
+
3
+ Choosing an Interpreter
4
+ =======================
5
+
6
+ The two most popular in-browser Python interpreters are Pyodide and MicroPython. Blu supports both, but uses MicroPython by default. To use Pyodide, set the interpreter in ``__settings__.py``:
7
+
8
+ .. code-block:: python
9
+ :caption: app/__settings__.py
10
+
11
+ INTERPRETER = 'pyodide'
12
+
13
+
14
+ Pyodide is CPython compiled to WebAssembly and has almost all the features available in other CPython distributions. MicroPython is a slim partial implementation of Python mainly used in microcontrollers. The main trade-offs are shown below:
15
+
16
+ .. list-table::
17
+ :header-rows: 1
18
+
19
+ * - Pyodide
20
+ - MicroPython
21
+ * - Implements almost all features of the Python language.
22
+ - Implements Python 3.10, with a few additional features from later versions.
23
+ * - Includes almost the entire Python standard library.
24
+ - Includes a small subset of the Python standard library, with some standard library packages available to be installed.
25
+ * - Provides Python APIs for interacting with the browser environment, as well as access to the JavaScript global scope.
26
+ - Only provides access to the JavaScript global scope.
27
+ * - Can have slow initial loads.
28
+ - Initial page load is almost instant.
@@ -0,0 +1,10 @@
1
+ .. _appendices:
2
+
3
+ Appendices
4
+ ==========
5
+
6
+ .. toctree::
7
+ :maxdepth: 2
8
+ :caption: Contents:
9
+
10
+ choosing-an-interpreter
@@ -49,6 +49,8 @@ html_css_files = ["styles.css"]
49
49
 
50
50
  todo_include_todos = True
51
51
 
52
+ autosectionlabel_prefix_document = True
53
+
52
54
  # autodoc
53
55
 
54
56
  autoclass_content = "both"
@@ -10,13 +10,15 @@ Setup
10
10
 
11
11
  3. Ensure `uv <https://docs.astral.sh/uv/>`_ is installed.
12
12
 
13
+
14
+
13
15
  4. Run tests with ``uv run pytest``. If the tests pass, you have successfully set up your development environment and are ready to make a change to the codebase.
14
16
 
15
17
 
16
18
  Making Changes
17
19
  --------------
18
20
 
19
- 1. Update the :ref:`API Reference` (and :ref:`User Guide`, if appropriate) to reflect intended changes.
21
+ 1. Update the :ref:`api-reference/index:API Reference` (and :ref:`user-guide/index:User Guide`, if appropriate) to reflect intended changes.
20
22
 
21
23
  2. Write tests or update existing ones to test the feature or bug fix you are implementing.
22
24
 
@@ -29,4 +31,4 @@ Making Changes
29
31
  Make a Pull Request Early
30
32
  -------------------------
31
33
 
32
- You don't have to wait until your changes are ready to merge to make a pull request. In fact, making a pull request early allows you to get early feedback, preventing you from doing significant work that is later rejected. For example, a pull request with just proposed documentation changes allows revisions to be made before anything is implemented, and a pull request with initial work allows revisions to be made to the implementation stategy before more work has been put into the implementation.
34
+ You don't have to wait until your changes are ready to merge to make a pull request. In fact, making a pull request early allows you to get early feedback, preventing you from doing significant work that is later rejected. For example, a pull request with only proposed documentation changes allows revisions to be made before anything is implemented, and a pull request with initial work allows revisions to be made to the implementation stategy before more work has been put into the implementation.
@@ -16,4 +16,5 @@ Welcome Blu's documentation.
16
16
  quickstart
17
17
  user-guide/index
18
18
  api-reference/index
19
+ appendices/index
19
20
  contributing
@@ -1,5 +1,3 @@
1
- .. _install:
2
-
3
1
  Install
4
2
  =======
5
3
 
@@ -1,7 +1,7 @@
1
1
  Quickstart
2
2
  ==========
3
3
 
4
- If you haven't already, :ref:`install Blu <install>`.
4
+ If you haven't already, :ref:`install Blu <install:Install>`.
5
5
 
6
6
  Next, create a directory called ``app``. Inside this directory, create a file called ``__index__.py`` with the following content:
7
7
 
@@ -39,4 +39,4 @@ This will start up the app and output a url where you can access it (``http://12
39
39
 
40
40
  If it works, you've created a simple web app using Blu.
41
41
 
42
- To learn how make more complex pages in Blu, see :ref:`Creating Pages`.
42
+ To learn how make more complex pages in Blu, see :ref:`user-guide/creating-pages:Creating Pages`.
@@ -0,0 +1,2 @@
1
+ sphinx-copybutton>=0.5.2
2
+ aiofiles~=25.1.0
@@ -224,7 +224,7 @@ What's going on here is:
224
224
  7. React sets the state value to 1, and then calls *MyClientElement*'s render function again. This time, the current value is 1, so *click_count* is 1, so the button will say "Click Count: 1".
225
225
  8. If the user clicks the button again, the current value will again be incremented, and the render function will be called again, resulting in a button that says "Click Count: 2".
226
226
 
227
- .. note:: :func:`use_state <blu.use_state>` is a special type of function used in React called a *hook*. There are specific rules you have to follow when using hooks. See :ref:`Hooks` for more details.
227
+ .. note:: :func:`use_state <blu.use_state>` is a special type of function used in React called a *hook*. There are specific rules you have to follow when using hooks. See :ref:`user-guide/client-side-rendering:Hooks` for more details.
228
228
 
229
229
 
230
230
  Directly Manipulating Rendered Elements
@@ -272,7 +272,7 @@ What's happening here is:
272
272
  1. Gets the current value of *input_ref* using ``[:]`` (remember that the current value is the rendered input element).
273
273
  2. Calls the *focus()* method on that value. Because the current value is a rendered HTML input element, calling its *focus()* method causes the input element to receive the browser's focus.
274
274
 
275
- .. note:: :func:`use_ref <blu.use_ref>` is a special type of function used in React called a *hook*. There are specific rules you have to follow when using hooks. See :ref:`Hooks` for more details.
275
+ .. note:: :func:`use_ref <blu.use_ref>` is a special type of function used in React called a *hook*. There are specific rules you have to follow when using hooks. See :ref:`user-guide/client-side-rendering:Hooks` for more details.
276
276
 
277
277
 
278
278
  Performing an Action Immediately After Rendering
@@ -316,7 +316,7 @@ What's happening here:
316
316
  7. This causes an alert modal to pop up in front of the page with the provided message.
317
317
  8. The user can then dismiss the alert modal.
318
318
 
319
- .. note:: :func:`use_effect <blu.use_effect>` is a special type of function used in React called a *hook*. There are specific rules you have to follow when using hooks. See :ref:`Hooks` for more details.
319
+ .. note:: :func:`use_effect <blu.use_effect>` is a special type of function used in React called a *hook*. There are specific rules you have to follow when using hooks. See :ref:`user-guide/client-side-rendering:Hooks` for more details.
320
320
 
321
321
  .. note::
322
322
 
@@ -355,7 +355,7 @@ What's happening here:
355
355
  Accessing Server-Side Resources from the Client
356
356
  -----------------------------------------------
357
357
 
358
- Sometimes you'll need to access server-side resources after a page has loaded, usually in response to user input. You can do using the :func:`@blu.server` decorator, which exposes a server-side function to be called client-side.
358
+ Sometimes you'll need to access server-side resources after a page has loaded, usually in response to user input. You can do so using the :func:`@blu.server` decorator, which exposes a server-side function to be called client-side.
359
359
 
360
360
  .. code-block:: python
361
361
  :caption: app/hello_module.py
@@ -3,7 +3,7 @@
3
3
  Creating Pages
4
4
  ==============
5
5
 
6
- The :ref:`Quickstart` guide shows how to make a simple page using Blu.
6
+ The :ref:`quickstart:Quickstart` guide shows how to make a simple page using Blu.
7
7
 
8
8
  This section goes into greater depth on how to generate user interfaces using Blu.
9
9
 
@@ -11,7 +11,7 @@ This section goes into greater depth on how to generate user interfaces using Bl
11
11
  HTML Elements
12
12
  -------------
13
13
 
14
- The :ref:`Quickstart` guide shows how to make a simple page with html, head, and body elements:
14
+ The :ref:`quickstart:Quickstart` guide shows how to make a simple page with html, head, and body elements:
15
15
 
16
16
  .. code-block:: python
17
17
 
@@ -140,7 +140,7 @@ You can set the HTML attributes of an element by calling it as a function:
140
140
 
141
141
  .. note::
142
142
 
143
- Event-handling attributes like "onClick" are only supported in client-side rendering (see :ref:`Client-Side Rendering` for more details).
143
+ Event-handling attributes like "onClick" are only supported in client-side rendering (see :ref:`user-guide/client-side-rendering:Client-Side Rendering` for more details).
144
144
 
145
145
  .. code-block:: python
146
146
 
@@ -5,7 +5,7 @@ Blu is an ASGI framework, meaning it doesn't include tools for running a product
5
5
 
6
6
  If you're familiar with ASGI frameworks, you may be wondering, "Where is the ASGI app?" The app you'll use to deploy is :data:`blu.app`.
7
7
 
8
- For example, to deploy your app using `Uvicorn <uvicorn.org>`_, run the following from your ``app/`` directory's parent directory (not the ``app/`` directory itself):
8
+ For example, to deploy your app using `Uvicorn <https://uvicorn.dev>`_, run the following from your ``app/`` directory's parent directory (not the ``app/`` directory itself):
9
9
 
10
10
  .. code-block:: console
11
11