pulse-framework 0.1.53__py3-none-any.whl → 0.1.55__py3-none-any.whl

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 (41) hide show
  1. pulse/__init__.py +3 -3
  2. pulse/app.py +34 -20
  3. pulse/code_analysis.py +38 -0
  4. pulse/codegen/codegen.py +18 -50
  5. pulse/codegen/templates/route.py +100 -56
  6. pulse/component.py +24 -6
  7. pulse/components/for_.py +17 -2
  8. pulse/cookies.py +38 -2
  9. pulse/env.py +4 -4
  10. pulse/hooks/init.py +174 -14
  11. pulse/hooks/state.py +105 -0
  12. pulse/js/__init__.py +12 -9
  13. pulse/js/obj.py +79 -0
  14. pulse/js/pulse.py +112 -0
  15. pulse/js/react.py +457 -0
  16. pulse/messages.py +13 -13
  17. pulse/proxy.py +18 -5
  18. pulse/render_session.py +282 -266
  19. pulse/renderer.py +36 -73
  20. pulse/serializer.py +5 -2
  21. pulse/transpiler/__init__.py +13 -0
  22. pulse/transpiler/assets.py +66 -0
  23. pulse/transpiler/builtins.py +0 -20
  24. pulse/transpiler/dynamic_import.py +131 -0
  25. pulse/transpiler/emit_context.py +49 -0
  26. pulse/transpiler/errors.py +29 -11
  27. pulse/transpiler/function.py +36 -5
  28. pulse/transpiler/imports.py +33 -27
  29. pulse/transpiler/js_module.py +73 -20
  30. pulse/transpiler/modules/pulse/tags.py +35 -15
  31. pulse/transpiler/nodes.py +121 -36
  32. pulse/transpiler/py_module.py +1 -1
  33. pulse/transpiler/react_component.py +4 -11
  34. pulse/transpiler/transpiler.py +32 -26
  35. pulse/user_session.py +10 -0
  36. pulse_framework-0.1.55.dist-info/METADATA +196 -0
  37. {pulse_framework-0.1.53.dist-info → pulse_framework-0.1.55.dist-info}/RECORD +39 -32
  38. pulse/hooks/states.py +0 -285
  39. pulse_framework-0.1.53.dist-info/METADATA +0 -18
  40. {pulse_framework-0.1.53.dist-info → pulse_framework-0.1.55.dist-info}/WHEEL +0 -0
  41. {pulse_framework-0.1.53.dist-info → pulse_framework-0.1.55.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,6 @@
1
- pulse/__init__.py,sha256=TZW4PEV1WHpVHFHZ0zOGiT1LtmR5azYXl0uclYtKXtw,31990
1
+ pulse/__init__.py,sha256=WN17B77pSD_Slz75YV3b1ove8GXsqeXhO-b1S_ZIrVE,31983
2
2
  pulse/_examples.py,sha256=dFuhD2EVXsbvAeexoG57s4VuN4gWLaTMOEMNYvlPm9A,561
3
- pulse/app.py,sha256=hrEV8fLgO0IXkIo41HYq4ckRjvwGymcOeyaaY0hnVb4,31087
3
+ pulse/app.py,sha256=D2T7K7HX87yg2UBIW9YYvT895Xp8UiiLSL8gWFZsaqQ,31635
4
4
  pulse/channel.py,sha256=d9eLxgyB0P9UBVkPkXV7MHkC4LWED1Cq3GKsEu_SYy4,13056
5
5
  pulse/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  pulse/cli/cmd.py,sha256=rTcqt_hg89n2FMJhf7ODUPClCx8dzcuKUe1Jv062UmQ,15339
@@ -13,21 +13,22 @@ pulse/cli/packages.py,sha256=DSnhxz61AoLVvBre3c0dnVYSpiKPI0rKFq4YmgM_VlA,7220
13
13
  pulse/cli/processes.py,sha256=BFSKTRoNlCTAi3lDAjKHsKN1c-S032eol0tFd84pdVQ,7566
14
14
  pulse/cli/secrets.py,sha256=dNfQe6AzSYhZuWveesjCRHIbvaPd3-F9lEJ-kZA7ROw,921
15
15
  pulse/cli/uvicorn_log_config.py,sha256=f7ikDc5foXh3TmFMrnfnW8yev48ZAdlo8F4F_aMVoVk,2391
16
+ pulse/code_analysis.py,sha256=NBba_7VtOxZYMyfku_p-bWkG0O_1pi1AxcaNyVM1nmY,1024
16
17
  pulse/codegen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- pulse/codegen/codegen.py,sha256=M5X-TpLwI25wfZhI2G0DjM3Op4kvoDF0HQeeGD3xujE,10296
18
+ pulse/codegen/codegen.py,sha256=Etr_0UpZY7EKE-SjcMiuGENDKuEZbyPWuFfccaQcdAs,9260
18
19
  pulse/codegen/js.py,sha256=fm2aL3RdnL7KlgrXDkKbM0E6BkXYBkID0XlKTDAX26c,1521
19
20
  pulse/codegen/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
21
  pulse/codegen/templates/layout.py,sha256=nmWPQcO9SRXc3mCCVLCmykreSF96TqQfdDY7dvUBxRg,4737
21
- pulse/codegen/templates/route.py,sha256=yWNoThsTivsK-8gtFF-ShDxT5Rj1QP1-26Yw66pvME8,7929
22
+ pulse/codegen/templates/route.py,sha256=UjBrb3e_8tMkd1OjBjEsnYmK6PCQqOYZBWDuU59FcrI,9234
22
23
  pulse/codegen/templates/routes_ts.py,sha256=nPgKCvU0gzue2k6KlOL1TJgrBqqRLmyy7K_qKAI8zAE,1129
23
24
  pulse/codegen/utils.py,sha256=QoXcV-h-DLLmq_t03hDNUePS0fNnofUQLoR-TXzDFCY,539
24
- pulse/component.py,sha256=3YVsiK0GvCzhsOEknd-hL-vPsij_UwcxksVVb-7tH2M,2922
25
+ pulse/component.py,sha256=QiIFNtYraljwDmTCCjYiuGT9BlOjO8VgHpFCj1GO2i0,3543
25
26
  pulse/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
- pulse/components/for_.py,sha256=HBTwrIsCUwJcJa57wJ6NZNjWUxMWBVpuPQpt3Ih6v04,1314
27
+ pulse/components/for_.py,sha256=OF7hso4hg0_X_FDwEzto6CoMcZ_fJho7TIp2ag0F_N0,1784
27
28
  pulse/components/if_.py,sha256=jXOrZ6sbSA-qgjJg-_-buppjS1wDDfRnKRF4Y7pQNTc,1636
28
29
  pulse/components/react_router.py,sha256=uQ08mdvcqA_i4EaFcfIR80DZkpMW_kqmBS1U5rNblqc,1068
29
30
  pulse/context.py,sha256=fMK6GdQY4q_3452v5DJli2f2_urVihnpzb-O-O9cJ1Q,1734
30
- pulse/cookies.py,sha256=c7ua1Lv6mNe1nYnA4SFVvewvRQAbYy9fN5G3Hr_Dr5c,5000
31
+ pulse/cookies.py,sha256=R-gf_x25SKqfJFGxdOazf91lQp-YUpd3HyUYF-nMji4,6184
31
32
  pulse/decorators.py,sha256=ywNgLN6VFcKOM5fbFdUUzh-DWk4BuSXdD1BTfd1N-0U,4827
32
33
  pulse/dom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
34
  pulse/dom/elements.py,sha256=YHXkVpfMAC4-0o61fK-E0LGTOM3KMCtBfpHHAwLx7dw,23241
@@ -36,18 +37,18 @@ pulse/dom/props.py,sha256=WrPwOYSoJmn-VWxU2KvJC1j64L4tlT8X2JpabK94gYQ,26721
36
37
  pulse/dom/svg.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
38
  pulse/dom/tags.py,sha256=U6mKmwB9JAFM6LTESMJcoIejNfnyxIdQo2-TLM5OaZ0,7585
38
39
  pulse/dom/tags.pyi,sha256=0BC7zTh22roPBuMQawL8hgI6IrfN8xJZuDIoKMd4QKc,14393
39
- pulse/env.py,sha256=p3XI8KG1ZCcXPD3LJP7fW8JPYfyvoYY5ENwae2o0PiA,2889
40
+ pulse/env.py,sha256=BXbyPWlCb045_RhjzEbg1LUIA0ppwwO2OE5CilGxGqY,2884
40
41
  pulse/form.py,sha256=KSCr8UrWnP4zuO7xhndkSgG-YyU_oFGVPuz743GD1k0,9081
41
42
  pulse/helpers.py,sha256=v054teQPOFNJZMgs_G7-BIGsvTLvolTEABgtoSUR3_c,14890
42
43
  pulse/hooks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
44
  pulse/hooks/core.py,sha256=QfYRz2O8-drNSQx_xnv8mK8ksWcw3LNM1H2hoInT0Rk,7457
44
45
  pulse/hooks/effects.py,sha256=pVq5OndlhFLHLpM9Pn9Bp5rEpnpmJEpbIp2UaHHyJFQ,2428
45
- pulse/hooks/init.py,sha256=OWd6TrUJq3Z1kv1cayI9Kz4tAvdvQg-zLACD6GZEDbk,11663
46
+ pulse/hooks/init.py,sha256=QZUfdOCqW7xcy_jn-lFBN8h_68ppmKDraF-2bhjWr1g,15848
46
47
  pulse/hooks/runtime.py,sha256=61CGZ9B0ScwCx8bwUrXIWYPAJIZtGCp3GcdBqa33dgo,5145
47
48
  pulse/hooks/setup.py,sha256=c_uVi0S0HPioEvjdWUaSdAGT9M3Cxpw8J-llvtmDOGo,4496
48
49
  pulse/hooks/stable.py,sha256=mLNS6WyA4tC-65gNybPOE0DLEz1YlxOCddD9odElArU,1772
49
- pulse/hooks/states.py,sha256=fFqN3gf7v7rY6QmieKWN1hVCQRRnL-5H4TeG9LTnKSc,6778
50
- pulse/js/__init__.py,sha256=KeXqLtBly5K2Vyh7SuPorZylXOh1W4vk_UAXRnaNh0Q,3394
50
+ pulse/hooks/state.py,sha256=2EX_N0YO_Jycx7CGE4xQEm3DjlPk97gaNYwhXPkfVJ8,2827
51
+ pulse/js/__init__.py,sha256=bl6RVTTrA_JInHcFtPDuUoYDYFeymkixrGXT24ZiisQ,3644
51
52
  pulse/js/__init__.pyi,sha256=WN22WsJB-XFk6auL9zklwG2Kof3zeOsc56A56dJ3MWg,3097
52
53
  pulse/js/_types.py,sha256=F4Go2JtJ2dbxq1fXpc2ablG_nyvhvHzOlZLlEv0VmyU,7421
53
54
  pulse/js/array.py,sha256=fMs0ykV7PwJawGN4lugtTe_yxBFfBRgjm1ley1IA_no,8892
@@ -60,18 +61,21 @@ pulse/js/map.py,sha256=VdWVOwIex_jTmB9OqHfxkSMw-tbAZcejJCFQB581wIg,2248
60
61
  pulse/js/math.py,sha256=UdOe2ri_Rxuu1qDhSiS270WrUMJj6VtSwnGZPpbq-k8,1766
61
62
  pulse/js/navigator.py,sha256=pilMh8e39XjM7DcVkOV-hlRg61Ldsgxil70h51d0fEo,1510
62
63
  pulse/js/number.py,sha256=rByDqG1La8Ijb8qcj740SgEK5ZQJUlV3V30ORkMewOc,1271
64
+ pulse/js/obj.py,sha256=sxOve2ny8mm40iBxLO6QxY0OmcBZheIkoqUimfBks8E,2078
63
65
  pulse/js/object.py,sha256=wMULUSjTPNRalnDkmmYjzeplm1N7ClVgMt7VoKQjzsI,4442
64
66
  pulse/js/promise.py,sha256=ipJTLXef5ub5tqexQY69M9AwxW-JyEhXg8DiSgo7OtA,4676
67
+ pulse/js/pulse.py,sha256=onWrfsagiXQk0VAIHAWj1pdPb17VchDgNVyuIMx9GKA,3027
68
+ pulse/js/react.py,sha256=0O4lENAQlHHVJ8zWZjJsEed3At5XvN-wz2ZjA-EOwII,11931
65
69
  pulse/js/regexp.py,sha256=5gpfDDe72uoOu2-uC8LvOPqrQH1HF6G-u77kPmIohbQ,1056
66
70
  pulse/js/set.py,sha256=nKSIxe0W4ZfA4NQ_-Jd401GTDfnQWRqMxag7eadoP70,3022
67
71
  pulse/js/string.py,sha256=VMjHDEF260-AVRqUBDKR0FXShmCU06y9IMAMpxVCc0E,822
68
72
  pulse/js/weakmap.py,sha256=XDCNykrHE2bjjKEd1TB-vToKE6Yz2W8-VSA79ajUoMA,1417
69
73
  pulse/js/weakset.py,sha256=nixXyjnSKRLFIACebzxTSXm0ZVUy09OY9BXF97ua9lU,1261
70
74
  pulse/js/window.py,sha256=kP57l2nYjJy6h6Zt-BbB4cdhs1Et0pB32AcViN7n1rw,4094
71
- pulse/messages.py,sha256=yrKbJhQagNuwlPq3OOMFNRv5tl4fQWB7MDBlBSOXZBA,3895
75
+ pulse/messages.py,sha256=03It_vMMLRDpDeXkxiwV_5LO_vcYUA79-SWw0dVX6MA,3936
72
76
  pulse/middleware.py,sha256=9uyAhVUEGMSwqWC3WXqs7x5JMMNEcSTTu3g7DjsR8w8,9812
73
77
  pulse/plugin.py,sha256=RfGl6Vtr7VRHb8bp4Ob4dOX9dVzvc4Riu7HWnStMPpk,580
74
- pulse/proxy.py,sha256=jv2IdOEbF-qbtN5hmSqnyhZedOX1597XBye8cerWIyE,7253
78
+ pulse/proxy.py,sha256=Rj0hOVnwyI36lrkK9fEKAgFK-WCwt5X526J87A2EvMs,7773
75
79
  pulse/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
80
  pulse/queries/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
81
  pulse/queries/client.py,sha256=GGckE0P3YCBO4Mj-08AO_I9eXVC4sIDSNw_xTLrBFuE,15224
@@ -85,36 +89,39 @@ pulse/queries/store.py,sha256=Ct7a-h1-Cq07zEfe9vw-LM85Fm7jIJx7CLAIlsiznlU,3444
85
89
  pulse/react_component.py,sha256=7uspzLhjQrosVFFHVMmeE3_P8XnAbMAt56i8116TQcw,197
86
90
  pulse/reactive.py,sha256=v8a9IttkabeWwYrrHAx33zqzW9WC4WlS4iXbIh2KQkU,24374
87
91
  pulse/reactive_extensions.py,sha256=T1V3AasHtvJkmGO55miC9RVPxDFIj7qrooMsn89x5SI,32076
88
- pulse/render_session.py,sha256=azNbLpMZmHt4AqX1zXoLNCicVXWUH1kRBPshD7VdgFQ,18478
89
- pulse/renderer.py,sha256=87_f2vpwzVXmRwU-QXlxq0O4Z6rhGy-P_pWyMB2bKZI,16982
92
+ pulse/render_session.py,sha256=oEKJ-RXqUUm1Dvc-7sgHIqfkVgayywvl3jcHb-bEQQo,17343
93
+ pulse/renderer.py,sha256=bH7MWaQB1BVk6s60yEgZhUIoAuXO9olY5IA8dUqc_64,16002
90
94
  pulse/request.py,sha256=sPsSRWi5KvReSPBLIs_kzqomn1wlRk1BTLZ5s0chQr4,4979
91
95
  pulse/routing.py,sha256=BObgI9cRPCXy24Gir-KeOdMh-Yxnh88hET2qddC0Fss,12847
92
- pulse/serializer.py,sha256=7YF8ZjDZYgA5Wmxd9CT-lPvakSb4zjUI1YbTd9m4jQM,5733
96
+ pulse/serializer.py,sha256=SQaoUsYLj2hkSleAJ5ML1BzSKt04lwGKlCAw15_MaOA,5838
93
97
  pulse/state.py,sha256=ikQbK4R8PieV96qd4uWREUvs0jXo9sCapawY7i6oCYo,10776
94
- pulse/transpiler/__init__.py,sha256=WiC1SHcrkHTo5tiM1KynPWDkvFl5I_hkna28BoAKB1o,4226
95
- pulse/transpiler/builtins.py,sha256=u0r458I9BwlQ0mjAl6xydmTKx4Cr98Vvcq07H9JsAOA,31389
96
- pulse/transpiler/errors.py,sha256=stChy-qs1hKsQPpF2Hf0Y7GqJs9CjRYHISRRChvqA6w,2158
97
- pulse/transpiler/function.py,sha256=psXqIAa2UO3smoGyoXYytBVVa6Xdw__khrjScFcll2g,16134
98
+ pulse/transpiler/__init__.py,sha256=BKemf-3llEAuiN0DID8gmz03qlC0T9GxvPZC19W3DGY,4840
99
+ pulse/transpiler/assets.py,sha256=FHielogI5NrFwst5H94E49YWYFX7Tp1rwJHCcowT3P0,1974
100
+ pulse/transpiler/builtins.py,sha256=QZrow7XJ2wxGMAE-mgZmaUD03egOnXCbikOg8yMx9vQ,30807
101
+ pulse/transpiler/dynamic_import.py,sha256=wyIA-QzRi2-1cdzxGuFJleVKyVp5dEud6M-eP9SA_EY,3464
102
+ pulse/transpiler/emit_context.py,sha256=GyK6VdsBSTVIewQRhBagaV0hlqLTlPZ1i8EAZGi8SaY,1321
103
+ pulse/transpiler/errors.py,sha256=LSBjLBnMglbl2D94p9JR4y-3jDefk6iHSlUVBaBOTu4,2823
104
+ pulse/transpiler/function.py,sha256=Pf5eoyzKHpn3d2EvCCYtARMnn_ixpAl7IZmY1fhmDIk,17036
98
105
  pulse/transpiler/id.py,sha256=CdgA1NndBpZjv0Hp4XiYbKn7wi-x4zWsFSjEiViKxVk,434
99
- pulse/transpiler/imports.py,sha256=SpiZDLOdml3TTEz04mVJbX4y7owVqqTBSWollncZQsg,9255
100
- pulse/transpiler/js_module.py,sha256=Mx0FcM4WnX6b8ttnvXqlQ8ty3DNetMIZLd7Tl7umbxo,9215
106
+ pulse/transpiler/imports.py,sha256=2pxKZzjmMyAMgkfs_gBc01mxbAv8euyW8FTBBy5GaNw,9420
107
+ pulse/transpiler/js_module.py,sha256=EWX8ZZ248H6kMQs9u6zsve3SPLy4lzf9F1cNEDdY1bA,11193
101
108
  pulse/transpiler/modules/__init__.py,sha256=JGi3CuZoF4sug4dNhQg3MFhpEQqnXec4xRJM2cHNP3c,1184
102
109
  pulse/transpiler/modules/asyncio.py,sha256=kWMuFU2vZbqutCM_EXJMvy5SdlB66XiT0czs8lELj_o,1584
103
110
  pulse/transpiler/modules/json.py,sha256=Zxe8dsaQ0Eoq3yHUiJeKEx6ibiN36HCT61ScFkLFCeY,676
104
111
  pulse/transpiler/modules/math.py,sha256=8gjvdYTMqtuOnXrvX_Lwuo0ywAdSl7cpss4TMk6mQtQ,7044
105
112
  pulse/transpiler/modules/pulse/__init__.py,sha256=TfMsiiB53ZFlxdNl7jfCAiMZs-vSRUTxUmqzkLTj-po,91
106
- pulse/transpiler/modules/pulse/tags.py,sha256=4IWxjTvFvDRJxXzBdl_Aj0qyIGvvjf0FprcPo1uUcDk,5929
113
+ pulse/transpiler/modules/pulse/tags.py,sha256=YFodKrhmt4DH7QtjTBdVvK5J6Qq2ntfhzb50tP-PTac,6273
107
114
  pulse/transpiler/modules/typing.py,sha256=hMGff6gBscFJE2GPV9xUFNfLuff2QCMIbMJUs3f24BY,1771
108
- pulse/transpiler/nodes.py,sha256=uOOBoPQnSuOwp2oEX99YVhoBj4KBbMWHIUFYGtIRe28,47568
109
- pulse/transpiler/py_module.py,sha256=Ez6jTgqeaBxpHVYGTbomuZfRgTnqrPDNOaqsDSwVD6c,4628
110
- pulse/transpiler/react_component.py,sha256=Fqi51YpmfG3jILN5VB2OSU9WIWx9TQ-TeyFwoxj5H3E,1434
111
- pulse/transpiler/transpiler.py,sha256=RUi7T9d7pd2lJKqgOkUIKvUe5eJV8di1wnTgrriFRiM,32273
115
+ pulse/transpiler/nodes.py,sha256=PvTHSLlau4xaf35UjI24FV_L4jhT2BwiIRmCtGowQ8A,50392
116
+ pulse/transpiler/py_module.py,sha256=z971TX958GEai8bP--4fnsMvE8ZhTWfWkIImUQwRpSo,4628
117
+ pulse/transpiler/react_component.py,sha256=GnATqqnDu55W6QbfHAXwhoE-B5k1CVA5t8FVdd7jBWc,1350
118
+ pulse/transpiler/transpiler.py,sha256=28diEp1yZTs3RsUEJZZdCv1DfzgO9WyOGI-xSHe7y_4,32562
112
119
  pulse/transpiler/vdom.py,sha256=l4CKQlt-wSSFJ7j7cF4dVwqYHWyAT1uAmbgsx0Kk4Jc,6310
113
120
  pulse/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
114
121
  pulse/types/event_handler.py,sha256=psQCydj-WEtBcFU5JU4mDwvyzkW8V2O0g_VFRU2EOHI,1618
115
- pulse/user_session.py,sha256=FITxLSEl3JU-jod6UWuUYC6EpnPG2rbaLCnIOdkQPtg,7803
122
+ pulse/user_session.py,sha256=1xVui3jjom4mtECqGLbIbQyPNsDVKquqq1NECI6yRa0,8129
116
123
  pulse/version.py,sha256=711vaM1jVIQPgkisGgKZqwmw019qZIsc_QTae75K2pg,1895
117
- pulse_framework-0.1.53.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
118
- pulse_framework-0.1.53.dist-info/entry_points.txt,sha256=i7aohd3QaPu5IcuGKKvsQQEiMYMe5HcF56QEsaLVO64,46
119
- pulse_framework-0.1.53.dist-info/METADATA,sha256=2yk7IHYAyEZNlF7EMJs9FsRlWaLPcneIt0nU9ZVsVGk,580
120
- pulse_framework-0.1.53.dist-info/RECORD,,
124
+ pulse_framework-0.1.55.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
125
+ pulse_framework-0.1.55.dist-info/entry_points.txt,sha256=i7aohd3QaPu5IcuGKKvsQQEiMYMe5HcF56QEsaLVO64,46
126
+ pulse_framework-0.1.55.dist-info/METADATA,sha256=MO26KPIrV8TuADZl8JaGkGVPqlquzRLwydm66XiEXfY,8176
127
+ pulse_framework-0.1.55.dist-info/RECORD,,
pulse/hooks/states.py DELETED
@@ -1,285 +0,0 @@
1
- from collections.abc import Callable
2
- from typing import TypeVar, overload, override
3
-
4
- from pulse.hooks.core import HookMetadata, HookState, hooks
5
- from pulse.state import State
6
-
7
- S = TypeVar("S", bound=State)
8
- S1 = TypeVar("S1", bound=State)
9
- S2 = TypeVar("S2", bound=State)
10
- S3 = TypeVar("S3", bound=State)
11
- S4 = TypeVar("S4", bound=State)
12
- S5 = TypeVar("S5", bound=State)
13
- S6 = TypeVar("S6", bound=State)
14
- S7 = TypeVar("S7", bound=State)
15
- S8 = TypeVar("S8", bound=State)
16
- S9 = TypeVar("S9", bound=State)
17
- S10 = TypeVar("S10", bound=State)
18
-
19
-
20
- class StateNamespace:
21
- __slots__ = ("states", "key", "called") # pyright: ignore[reportUnannotatedClassAttribute]
22
- states: tuple[State, ...]
23
- key: str | None
24
- called: bool
25
-
26
- def __init__(self, key: str | None) -> None:
27
- self.states = ()
28
- self.key = key
29
- self.called = False
30
-
31
- def ensure_not_called(self) -> None:
32
- if self.called:
33
- key_msg = (
34
- f" with key='{self.key}'" if self.key is not None else " without a key"
35
- )
36
- raise RuntimeError(
37
- f"`pulse.states` can only be called once per component render{key_msg}"
38
- )
39
-
40
- def get_or_create_states(
41
- self, args: tuple[State | Callable[[], State], ...]
42
- ) -> tuple[State, ...]:
43
- if len(self.states) > 0:
44
- # Reuse existing states
45
- existing_states = self.states
46
- # Validate that the number of arguments matches
47
- if len(args) != len(existing_states):
48
- key_msg = (
49
- f" with key='{self.key}'"
50
- if self.key is not None
51
- else " without a key"
52
- )
53
- raise RuntimeError(
54
- f"`pulse.states` called with {len(args)} argument(s) but was previously "
55
- + f"called with {len(existing_states)} argument(s){key_msg}. "
56
- + "The number of arguments must remain consistent across renders."
57
- )
58
- # Dispose any State instances passed directly as args that aren't being used
59
- existing_set = set(existing_states)
60
- for arg in args:
61
- if isinstance(arg, State) and arg not in existing_set:
62
- try:
63
- if not arg.__disposed__:
64
- arg.dispose()
65
- except RuntimeError:
66
- # Already disposed, ignore
67
- pass
68
- return existing_states
69
-
70
- # Create new states
71
- instances = tuple(_instantiate_state(arg) for arg in args)
72
- self.states = instances
73
- return instances
74
-
75
- def dispose(self) -> None:
76
- for state in self.states:
77
- try:
78
- if not state.__disposed__:
79
- state.dispose()
80
- except RuntimeError:
81
- # Already disposed, ignore
82
- pass
83
- self.states = ()
84
-
85
-
86
- class StatesHookState(HookState):
87
- __slots__ = ("namespaces",) # pyright: ignore[reportUnannotatedClassAttribute]
88
- namespaces: dict[str | None, StateNamespace]
89
-
90
- def __init__(self) -> None:
91
- super().__init__()
92
- self.namespaces = {}
93
-
94
- @override
95
- def on_render_start(self, render_cycle: int) -> None:
96
- super().on_render_start(render_cycle)
97
- if self.namespaces:
98
- for namespace in self.namespaces.values():
99
- namespace.called = False
100
-
101
- def get_namespace(self, key: str | None) -> StateNamespace:
102
- if key not in self.namespaces:
103
- self.namespaces[key] = StateNamespace(key)
104
- return self.namespaces[key]
105
-
106
- def get_or_create_states(
107
- self, args: tuple[State | Callable[[], State], ...], key: str | None
108
- ) -> tuple[State, ...]:
109
- namespace = self.get_namespace(key)
110
- namespace.ensure_not_called()
111
- result = namespace.get_or_create_states(args)
112
- namespace.called = True
113
- return result
114
-
115
- @override
116
- def dispose(self) -> None:
117
- for namespace in self.namespaces.values():
118
- namespace.dispose()
119
- self.namespaces.clear()
120
-
121
-
122
- def _instantiate_state(arg: State | Callable[[], State]) -> State:
123
- state = arg() if callable(arg) else arg
124
- if not isinstance(state, State):
125
- raise TypeError(
126
- "`pulse.states` expects State instances or callables returning State instances"
127
- )
128
- return state
129
-
130
-
131
- def _states_factory():
132
- return StatesHookState()
133
-
134
-
135
- _states_hook = hooks.create(
136
- "pulse:core.states",
137
- _states_factory,
138
- metadata=HookMetadata(
139
- owner="pulse.core",
140
- description="Internal storage for pulse.states hook",
141
- ),
142
- )
143
-
144
-
145
- @overload
146
- def states(s1: S1 | Callable[[], S1], /, *, key: str | None = ...) -> S1: ... # pyright: ignore[reportOverlappingOverload]
147
-
148
-
149
- @overload
150
- def states(
151
- s1: S1 | Callable[[], S1],
152
- s2: S2 | Callable[[], S2],
153
- /,
154
- *,
155
- key: str | None = ...,
156
- ) -> tuple[S1, S2]: ...
157
-
158
-
159
- @overload
160
- def states(
161
- s1: S1 | Callable[[], S1],
162
- s2: S2 | Callable[[], S2],
163
- s3: S3 | Callable[[], S3],
164
- /,
165
- *,
166
- key: str | None = ...,
167
- ) -> tuple[S1, S2, S3]: ...
168
-
169
-
170
- @overload
171
- def states(
172
- s1: S1 | Callable[[], S1],
173
- s2: S2 | Callable[[], S2],
174
- s3: S3 | Callable[[], S3],
175
- s4: S4 | Callable[[], S4],
176
- /,
177
- *,
178
- key: str | None = ...,
179
- ) -> tuple[S1, S2, S3, S4]: ...
180
-
181
-
182
- @overload
183
- def states(
184
- s1: S1 | Callable[[], S1],
185
- s2: S2 | Callable[[], S2],
186
- s3: S3 | Callable[[], S3],
187
- s4: S4 | Callable[[], S4],
188
- s5: S5 | Callable[[], S5],
189
- /,
190
- *,
191
- key: str | None = ...,
192
- ) -> tuple[S1, S2, S3, S4, S5]: ...
193
-
194
-
195
- @overload
196
- def states(
197
- s1: S1 | Callable[[], S1],
198
- s2: S2 | Callable[[], S2],
199
- s3: S3 | Callable[[], S3],
200
- s4: S4 | Callable[[], S4],
201
- s5: S5 | Callable[[], S5],
202
- s6: S6 | Callable[[], S6],
203
- /,
204
- *,
205
- key: str | None = ...,
206
- ) -> tuple[S1, S2, S3, S4, S5, S6]: ...
207
-
208
-
209
- @overload
210
- def states(
211
- s1: S1 | Callable[[], S1],
212
- s2: S2 | Callable[[], S2],
213
- s3: S3 | Callable[[], S3],
214
- s4: S4 | Callable[[], S4],
215
- s5: S5 | Callable[[], S5],
216
- s6: S6 | Callable[[], S6],
217
- s7: S7 | Callable[[], S7],
218
- /,
219
- *,
220
- key: str | None = ...,
221
- ) -> tuple[S1, S2, S3, S4, S5, S6, S7]: ...
222
-
223
-
224
- @overload
225
- def states(
226
- s1: S1 | Callable[[], S1],
227
- s2: S2 | Callable[[], S2],
228
- s3: S3 | Callable[[], S3],
229
- s4: S4 | Callable[[], S4],
230
- s5: S5 | Callable[[], S5],
231
- s6: S6 | Callable[[], S6],
232
- s7: S7 | Callable[[], S7],
233
- s8: S8 | Callable[[], S8],
234
- /,
235
- *,
236
- key: str | None = ...,
237
- ) -> tuple[S1, S2, S3, S4, S5, S6, S7, S8]: ...
238
-
239
-
240
- @overload
241
- def states(
242
- s1: S1 | Callable[[], S1],
243
- s2: S2 | Callable[[], S2],
244
- s3: S3 | Callable[[], S3],
245
- s4: S4 | Callable[[], S4],
246
- s5: S5 | Callable[[], S5],
247
- s6: S6 | Callable[[], S6],
248
- s7: S7 | Callable[[], S7],
249
- s8: S8 | Callable[[], S8],
250
- s9: S9 | Callable[[], S9],
251
- /,
252
- *,
253
- key: str | None = ...,
254
- ) -> tuple[S1, S2, S3, S4, S5, S6, S7, S8, S9]: ...
255
-
256
-
257
- @overload
258
- def states(
259
- s1: S1 | Callable[[], S1],
260
- s2: S2 | Callable[[], S2],
261
- s3: S3 | Callable[[], S3],
262
- s4: S4 | Callable[[], S4],
263
- s5: S5 | Callable[[], S5],
264
- s6: S6 | Callable[[], S6],
265
- s7: S7 | Callable[[], S7],
266
- s8: S8 | Callable[[], S8],
267
- s9: S9 | Callable[[], S9],
268
- s10: S10 | Callable[[], S10],
269
- /,
270
- *,
271
- key: str | None = ...,
272
- ) -> tuple[S1, S2, S3, S4, S5, S6, S7, S8, S9, S10]: ...
273
-
274
-
275
- @overload
276
- def states(*args: S | Callable[[], S], key: str | None = ...) -> tuple[S, ...]: ...
277
-
278
-
279
- def states(*args: State | Callable[[], State], key: str | None = None):
280
- hook_state = _states_hook()
281
- result = hook_state.get_or_create_states(args, key)
282
- return result[0] if len(result) == 1 else result
283
-
284
-
285
- __all__ = ["states", "StatesHookState"]
@@ -1,18 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: pulse-framework
3
- Version: 0.1.53
4
- Summary: Pulse - Full-stack framework for building real-time React applications in Python
5
- Requires-Dist: websockets>=12.0
6
- Requires-Dist: fastapi>=0.104.0
7
- Requires-Dist: uvicorn>=0.24.0
8
- Requires-Dist: mako>=1.3.10
9
- Requires-Dist: typer>=0.16.0
10
- Requires-Dist: python-socketio>=5.13.0
11
- Requires-Dist: rich>=13.7.1
12
- Requires-Dist: python-multipart>=0.0.20
13
- Requires-Dist: python-dateutil>=2.9.0.post0
14
- Requires-Dist: watchfiles>=1.1.0
15
- Requires-Dist: httpx>=0.28.1
16
- Requires-Python: >=3.11
17
- Description-Content-Type: text/markdown
18
-