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.
- pulse/__init__.py +3 -3
- pulse/app.py +34 -20
- pulse/code_analysis.py +38 -0
- pulse/codegen/codegen.py +18 -50
- pulse/codegen/templates/route.py +100 -56
- pulse/component.py +24 -6
- pulse/components/for_.py +17 -2
- pulse/cookies.py +38 -2
- pulse/env.py +4 -4
- pulse/hooks/init.py +174 -14
- pulse/hooks/state.py +105 -0
- pulse/js/__init__.py +12 -9
- pulse/js/obj.py +79 -0
- pulse/js/pulse.py +112 -0
- pulse/js/react.py +457 -0
- pulse/messages.py +13 -13
- pulse/proxy.py +18 -5
- pulse/render_session.py +282 -266
- pulse/renderer.py +36 -73
- pulse/serializer.py +5 -2
- pulse/transpiler/__init__.py +13 -0
- pulse/transpiler/assets.py +66 -0
- pulse/transpiler/builtins.py +0 -20
- pulse/transpiler/dynamic_import.py +131 -0
- pulse/transpiler/emit_context.py +49 -0
- pulse/transpiler/errors.py +29 -11
- pulse/transpiler/function.py +36 -5
- pulse/transpiler/imports.py +33 -27
- pulse/transpiler/js_module.py +73 -20
- pulse/transpiler/modules/pulse/tags.py +35 -15
- pulse/transpiler/nodes.py +121 -36
- pulse/transpiler/py_module.py +1 -1
- pulse/transpiler/react_component.py +4 -11
- pulse/transpiler/transpiler.py +32 -26
- pulse/user_session.py +10 -0
- pulse_framework-0.1.55.dist-info/METADATA +196 -0
- {pulse_framework-0.1.53.dist-info → pulse_framework-0.1.55.dist-info}/RECORD +39 -32
- pulse/hooks/states.py +0 -285
- pulse_framework-0.1.53.dist-info/METADATA +0 -18
- {pulse_framework-0.1.53.dist-info → pulse_framework-0.1.55.dist-info}/WHEEL +0 -0
- {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=
|
|
1
|
+
pulse/__init__.py,sha256=WN17B77pSD_Slz75YV3b1ove8GXsqeXhO-b1S_ZIrVE,31983
|
|
2
2
|
pulse/_examples.py,sha256=dFuhD2EVXsbvAeexoG57s4VuN4gWLaTMOEMNYvlPm9A,561
|
|
3
|
-
pulse/app.py,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
25
|
+
pulse/component.py,sha256=QiIFNtYraljwDmTCCjYiuGT9BlOjO8VgHpFCj1GO2i0,3543
|
|
25
26
|
pulse/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
-
pulse/components/for_.py,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
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/
|
|
50
|
-
pulse/js/__init__.py,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
89
|
-
pulse/renderer.py,sha256=
|
|
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=
|
|
96
|
+
pulse/serializer.py,sha256=SQaoUsYLj2hkSleAJ5ML1BzSKt04lwGKlCAw15_MaOA,5838
|
|
93
97
|
pulse/state.py,sha256=ikQbK4R8PieV96qd4uWREUvs0jXo9sCapawY7i6oCYo,10776
|
|
94
|
-
pulse/transpiler/__init__.py,sha256=
|
|
95
|
-
pulse/transpiler/
|
|
96
|
-
pulse/transpiler/
|
|
97
|
-
pulse/transpiler/
|
|
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=
|
|
100
|
-
pulse/transpiler/js_module.py,sha256=
|
|
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=
|
|
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=
|
|
109
|
-
pulse/transpiler/py_module.py,sha256=
|
|
110
|
-
pulse/transpiler/react_component.py,sha256=
|
|
111
|
-
pulse/transpiler/transpiler.py,sha256=
|
|
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=
|
|
122
|
+
pulse/user_session.py,sha256=1xVui3jjom4mtECqGLbIbQyPNsDVKquqq1NECI6yRa0,8129
|
|
116
123
|
pulse/version.py,sha256=711vaM1jVIQPgkisGgKZqwmw019qZIsc_QTae75K2pg,1895
|
|
117
|
-
pulse_framework-0.1.
|
|
118
|
-
pulse_framework-0.1.
|
|
119
|
-
pulse_framework-0.1.
|
|
120
|
-
pulse_framework-0.1.
|
|
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
|
-
|
|
File without changes
|
|
File without changes
|