pulse-framework 0.1.38a7__py3-none-any.whl → 0.1.38a9__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/cli/cmd.py CHANGED
@@ -204,7 +204,10 @@ def run(
204
204
  )
205
205
  )
206
206
 
207
- tag_colors = {"server": "cyan", "web": "orange1"}
207
+ # Only add tags in dev mode to avoid breaking structured output (e.g., CloudWatch EMF metrics)
208
+ tag_colors = (
209
+ {"server": "cyan", "web": "orange1"} if env.pulse_env == "dev" else None
210
+ )
208
211
 
209
212
  with FolderLock(web_root):
210
213
  try:
@@ -249,7 +252,15 @@ def generate(
249
252
  app = app_ctx.app
250
253
  console.log(f"📋 Found {len(app.routes.flat_tree)} routes")
251
254
 
252
- addr = app.server_address or "localhost:8000"
255
+ # In CI or prod mode, server_address must be provided
256
+ if (ci or prod) and not app.server_address:
257
+ typer.echo(
258
+ "❌ server_address must be provided when generating in CI or production mode. "
259
+ + "Set it in your App constructor or via the PULSE_SERVER_ADDRESS environment variable."
260
+ )
261
+ raise typer.Exit(1)
262
+
263
+ addr = app.server_address or "http://localhost:8000"
253
264
  app.run_codegen(addr)
254
265
 
255
266
  if len(app.routes.flat_tree) > 0:
pulse/cli/processes.py CHANGED
@@ -215,8 +215,12 @@ def _run_without_pty(
215
215
 
216
216
 
217
217
  def _write_tagged_line(name: str, message: str, colors: Mapping[str, str]) -> None:
218
- color = ANSI_CODES.get(colors.get(name, ""), ANSI_CODES["default"])
219
- sys.stdout.write(f"{color}[{name}]\033[0m {message}\n")
218
+ # Only add tags if colors dict is not empty (i.e., tagging is enabled)
219
+ if colors:
220
+ color = ANSI_CODES.get(colors.get(name, ""), ANSI_CODES["default"])
221
+ sys.stdout.write(f"{color}[{name}]\033[0m {message}\n")
222
+ else:
223
+ sys.stdout.write(f"{message}\n")
220
224
  sys.stdout.flush()
221
225
 
222
226
 
pulse/state.py CHANGED
@@ -206,6 +206,15 @@ class State(ABC, metaclass=StateMeta):
206
206
  ```
207
207
 
208
208
  Properties will automatically trigger re-renders when changed.
209
+
210
+ Override `on_dispose()` to run cleanup code when the state is disposed:
211
+ ```python
212
+ class MyState(ps.State):
213
+ def on_dispose(self):
214
+ # Clean up timers, connections, etc.
215
+ self.timer.cancel()
216
+ self.connection.close()
217
+ ```
209
218
  """
210
219
 
211
220
  @override
@@ -310,7 +319,19 @@ class State(ABC, metaclass=StateMeta):
310
319
  # if isinstance(value,QueryProperty):
311
320
  # value.
312
321
 
322
+ def on_dispose(self) -> None:
323
+ """
324
+ Override this method to run cleanup code when the state is disposed.
325
+
326
+ This is called automatically when `dispose()` is called, before effects are disposed.
327
+ Use this to clean up timers, connections, or other resources.
328
+ """
329
+ pass
330
+
313
331
  def dispose(self):
332
+ # Call user-defined cleanup hook first
333
+ self.on_dispose()
334
+
314
335
  disposed = set()
315
336
  for value in self.__dict__.values():
316
337
  if isinstance(value, Effect):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pulse-framework
3
- Version: 0.1.38a7
3
+ Version: 0.1.38a9
4
4
  Summary: Pulse - Full-stack framework for building real-time React applications in Python
5
5
  Requires-Dist: websockets>=12.0
6
6
  Requires-Dist: fastapi>=0.104.0
@@ -2,13 +2,13 @@ pulse/__init__.py,sha256=P2CLvFxP8IPiUsy3Z-hZD-1tbsvhd4eVlMNYg5WOPjE,31709
2
2
  pulse/app.py,sha256=a-fHuX1MfA0Whjyy8l2JxroRkJd5VG0Aba31xfKcuFY,29871
3
3
  pulse/channel.py,sha256=DuD1mg_xWvkpAWSKZ-EtBYdUzJ8IuKH0fxdgGOvFXpg,13041
4
4
  pulse/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- pulse/cli/cmd.py,sha256=PpThGpbvDNn9c9I2sPK8O-XMU1P0eHDoIODed9Q8rQg,13548
5
+ pulse/cli/cmd.py,sha256=jA1kgw6Dibj8jC_amcRL4mCzfboszLTnVAQtJA3_G-4,14011
6
6
  pulse/cli/dependencies.py,sha256=ZBqBAfMvMBQUvh4THdPDztTMQ_dyR52S1IuotP_eEZs,5623
7
7
  pulse/cli/folder_lock.py,sha256=kvUmZBg869lwCTIZFoge9dhorv8qPXHTWwVv_jQg1k8,3477
8
8
  pulse/cli/helpers.py,sha256=8bRlV3d7w3w-jHaFvFYt9Pzue6_CbKOq_Z3jBsBOeUk,8820
9
9
  pulse/cli/models.py,sha256=hRmIWmhXmGf2otzVm1do4Dm19rkWkmTwAA3Am3kw2tE,692
10
10
  pulse/cli/packages.py,sha256=e7ycwwJfdmB4pzrai4DHos6-JzyUgmE4DCZp0BqjdeI,6792
11
- pulse/cli/processes.py,sha256=rv1FZ0aynNsYwAbyirqOOeTp-6gqfks8CETOAVPGwS0,5599
11
+ pulse/cli/processes.py,sha256=yJg2hHY2JggLkvQS9XrVwdl7reQhF333qxATPnPkmrU,5727
12
12
  pulse/cli/secrets.py,sha256=dNfQe6AzSYhZuWveesjCRHIbvaPd3-F9lEJ-kZA7ROw,921
13
13
  pulse/cli/uvicorn_log_config.py,sha256=Ip0iCeMUoY1ruv3Amf2SF84lW2DDpJFqdsLflZNxmeY,2407
14
14
  pulse/codegen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -59,13 +59,13 @@ pulse/renderer.py,sha256=dJiX9VeHr9kC1UBw5oaKB8Mv-3OCMGTrHiKgLJ5FL50,16759
59
59
  pulse/request.py,sha256=sPsSRWi5KvReSPBLIs_kzqomn1wlRk1BTLZ5s0chQr4,4979
60
60
  pulse/routing.py,sha256=o3xmWpoMgJMkI1W7nFJpDkCT30ejTG2MnCV42OwgLaI,12492
61
61
  pulse/serializer.py,sha256=8RAITNoSNm5-U38elHpWmkBpcM_rxZFMCluJSfldfk4,5420
62
- pulse/state.py,sha256=nbnN9wGrHTP0AOFBfb4zKNzYaSkmLR5u0t4TVHg-UDA,9972
62
+ pulse/state.py,sha256=y9Z-KBYQVd63fb1wF8gQ4KilK7c2ElYLf6U-miWteM8,10560
63
63
  pulse/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
64
  pulse/types/event_handler.py,sha256=OF7sOgYBb6iUs59RH1vQIH7aOrGPfs3nAaF7how-4PQ,1658
65
65
  pulse/user_session.py,sha256=kCZtQpYZe2keDXzusd6jsjjw075am0dXrb25jKLg5JU,7578
66
66
  pulse/vdom.py,sha256=KTNBh2dVvDy9eXRzhneBJgk7F35MyWec8R_puQ4tSRY,12420
67
67
  pulse/version.py,sha256=711vaM1jVIQPgkisGgKZqwmw019qZIsc_QTae75K2pg,1895
68
- pulse_framework-0.1.38a7.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
69
- pulse_framework-0.1.38a7.dist-info/entry_points.txt,sha256=i7aohd3QaPu5IcuGKKvsQQEiMYMe5HcF56QEsaLVO64,46
70
- pulse_framework-0.1.38a7.dist-info/METADATA,sha256=fxno0AsA_hH9_w_nI7Vd5dQemHgDn6rxyNKaFdfW5fQ,582
71
- pulse_framework-0.1.38a7.dist-info/RECORD,,
68
+ pulse_framework-0.1.38a9.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
69
+ pulse_framework-0.1.38a9.dist-info/entry_points.txt,sha256=i7aohd3QaPu5IcuGKKvsQQEiMYMe5HcF56QEsaLVO64,46
70
+ pulse_framework-0.1.38a9.dist-info/METADATA,sha256=aNlTOGPVKDCkzoYDtRCHP3SppJDYfeP2w4SQpPWxS0E,582
71
+ pulse_framework-0.1.38a9.dist-info/RECORD,,