pulse-framework 0.1.62__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 (126) hide show
  1. pulse/__init__.py +1493 -0
  2. pulse/_examples.py +29 -0
  3. pulse/app.py +1086 -0
  4. pulse/channel.py +607 -0
  5. pulse/cli/__init__.py +0 -0
  6. pulse/cli/cmd.py +575 -0
  7. pulse/cli/dependencies.py +181 -0
  8. pulse/cli/folder_lock.py +134 -0
  9. pulse/cli/helpers.py +271 -0
  10. pulse/cli/logging.py +102 -0
  11. pulse/cli/models.py +35 -0
  12. pulse/cli/packages.py +262 -0
  13. pulse/cli/processes.py +292 -0
  14. pulse/cli/secrets.py +39 -0
  15. pulse/cli/uvicorn_log_config.py +87 -0
  16. pulse/code_analysis.py +38 -0
  17. pulse/codegen/__init__.py +0 -0
  18. pulse/codegen/codegen.py +359 -0
  19. pulse/codegen/templates/__init__.py +0 -0
  20. pulse/codegen/templates/layout.py +106 -0
  21. pulse/codegen/templates/route.py +345 -0
  22. pulse/codegen/templates/routes_ts.py +42 -0
  23. pulse/codegen/utils.py +20 -0
  24. pulse/component.py +237 -0
  25. pulse/components/__init__.py +0 -0
  26. pulse/components/for_.py +83 -0
  27. pulse/components/if_.py +86 -0
  28. pulse/components/react_router.py +94 -0
  29. pulse/context.py +108 -0
  30. pulse/cookies.py +322 -0
  31. pulse/decorators.py +344 -0
  32. pulse/dom/__init__.py +0 -0
  33. pulse/dom/elements.py +1024 -0
  34. pulse/dom/events.py +445 -0
  35. pulse/dom/props.py +1250 -0
  36. pulse/dom/svg.py +0 -0
  37. pulse/dom/tags.py +328 -0
  38. pulse/dom/tags.pyi +480 -0
  39. pulse/env.py +178 -0
  40. pulse/form.py +538 -0
  41. pulse/helpers.py +541 -0
  42. pulse/hooks/__init__.py +0 -0
  43. pulse/hooks/core.py +452 -0
  44. pulse/hooks/effects.py +88 -0
  45. pulse/hooks/init.py +668 -0
  46. pulse/hooks/runtime.py +464 -0
  47. pulse/hooks/setup.py +254 -0
  48. pulse/hooks/stable.py +138 -0
  49. pulse/hooks/state.py +192 -0
  50. pulse/js/__init__.py +125 -0
  51. pulse/js/__init__.pyi +115 -0
  52. pulse/js/_types.py +299 -0
  53. pulse/js/array.py +339 -0
  54. pulse/js/console.py +50 -0
  55. pulse/js/date.py +119 -0
  56. pulse/js/document.py +145 -0
  57. pulse/js/error.py +140 -0
  58. pulse/js/json.py +66 -0
  59. pulse/js/map.py +97 -0
  60. pulse/js/math.py +69 -0
  61. pulse/js/navigator.py +79 -0
  62. pulse/js/number.py +57 -0
  63. pulse/js/obj.py +81 -0
  64. pulse/js/object.py +172 -0
  65. pulse/js/promise.py +172 -0
  66. pulse/js/pulse.py +115 -0
  67. pulse/js/react.py +495 -0
  68. pulse/js/regexp.py +57 -0
  69. pulse/js/set.py +124 -0
  70. pulse/js/string.py +38 -0
  71. pulse/js/weakmap.py +53 -0
  72. pulse/js/weakset.py +48 -0
  73. pulse/js/window.py +205 -0
  74. pulse/messages.py +202 -0
  75. pulse/middleware.py +471 -0
  76. pulse/plugin.py +96 -0
  77. pulse/proxy.py +242 -0
  78. pulse/py.typed +0 -0
  79. pulse/queries/__init__.py +0 -0
  80. pulse/queries/client.py +609 -0
  81. pulse/queries/common.py +101 -0
  82. pulse/queries/effect.py +55 -0
  83. pulse/queries/infinite_query.py +1418 -0
  84. pulse/queries/mutation.py +295 -0
  85. pulse/queries/protocol.py +136 -0
  86. pulse/queries/query.py +1314 -0
  87. pulse/queries/store.py +120 -0
  88. pulse/react_component.py +88 -0
  89. pulse/reactive.py +1208 -0
  90. pulse/reactive_extensions.py +1172 -0
  91. pulse/render_session.py +768 -0
  92. pulse/renderer.py +584 -0
  93. pulse/request.py +205 -0
  94. pulse/routing.py +598 -0
  95. pulse/serializer.py +279 -0
  96. pulse/state.py +556 -0
  97. pulse/test_helpers.py +15 -0
  98. pulse/transpiler/__init__.py +111 -0
  99. pulse/transpiler/assets.py +81 -0
  100. pulse/transpiler/builtins.py +1029 -0
  101. pulse/transpiler/dynamic_import.py +130 -0
  102. pulse/transpiler/emit_context.py +49 -0
  103. pulse/transpiler/errors.py +96 -0
  104. pulse/transpiler/function.py +611 -0
  105. pulse/transpiler/id.py +18 -0
  106. pulse/transpiler/imports.py +341 -0
  107. pulse/transpiler/js_module.py +336 -0
  108. pulse/transpiler/modules/__init__.py +33 -0
  109. pulse/transpiler/modules/asyncio.py +57 -0
  110. pulse/transpiler/modules/json.py +24 -0
  111. pulse/transpiler/modules/math.py +265 -0
  112. pulse/transpiler/modules/pulse/__init__.py +5 -0
  113. pulse/transpiler/modules/pulse/tags.py +250 -0
  114. pulse/transpiler/modules/typing.py +63 -0
  115. pulse/transpiler/nodes.py +1987 -0
  116. pulse/transpiler/py_module.py +135 -0
  117. pulse/transpiler/transpiler.py +1100 -0
  118. pulse/transpiler/vdom.py +256 -0
  119. pulse/types/__init__.py +0 -0
  120. pulse/types/event_handler.py +50 -0
  121. pulse/user_session.py +386 -0
  122. pulse/version.py +69 -0
  123. pulse_framework-0.1.62.dist-info/METADATA +198 -0
  124. pulse_framework-0.1.62.dist-info/RECORD +126 -0
  125. pulse_framework-0.1.62.dist-info/WHEEL +4 -0
  126. pulse_framework-0.1.62.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,81 @@
1
+ """Unified asset registry for local files that need copying.
2
+
3
+ Used by both Import (static imports) and DynamicImport (inline dynamic imports)
4
+ to track local files that should be copied to the assets folder during codegen.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import posixpath
10
+ from dataclasses import dataclass
11
+ from pathlib import Path
12
+
13
+ from pulse.transpiler.emit_context import EmitContext
14
+ from pulse.transpiler.id import next_id
15
+
16
+ _CSS_MODULE_EXTS = (
17
+ ".css",
18
+ ".scss",
19
+ ".sass",
20
+ ".less",
21
+ ".styl",
22
+ ".stylus",
23
+ )
24
+
25
+
26
+ @dataclass(slots=True)
27
+ class LocalAsset:
28
+ """A local file registered for copying to assets."""
29
+
30
+ source_path: Path
31
+ id: str
32
+
33
+ @property
34
+ def asset_filename(self) -> str:
35
+ """Filename in assets folder: stem_id.ext (preserve .module.*)."""
36
+ name = self.source_path.name
37
+ for ext in _CSS_MODULE_EXTS:
38
+ module_suffix = f".module{ext}"
39
+ if name.endswith(module_suffix):
40
+ base = name[: -len(module_suffix)]
41
+ return f"{base}_{self.id}{module_suffix}"
42
+ return f"{self.source_path.stem}_{self.id}{self.source_path.suffix}"
43
+
44
+ def import_path(self) -> str:
45
+ """Get import path for this asset.
46
+
47
+ If EmitContext is set, returns path relative to route file.
48
+ Otherwise returns the absolute source path (useful for tests/debugging).
49
+ """
50
+ ctx = EmitContext.get()
51
+ if ctx is None:
52
+ return str(self.source_path)
53
+ # Compute relative path from route file directory to asset
54
+ # route_file_path is like "routes/users/index.tsx"
55
+ # asset is in "assets/{asset_filename}"
56
+ route_dir = posixpath.dirname(ctx.route_file_path)
57
+ asset_path = f"assets/{self.asset_filename}"
58
+ return posixpath.relpath(asset_path, route_dir)
59
+
60
+
61
+ # Registry keyed by resolved source_path (dedupes same file)
62
+ _ASSET_REGISTRY: dict[Path, LocalAsset] = {}
63
+
64
+
65
+ def register_local_asset(source_path: Path) -> LocalAsset:
66
+ """Register a local file for copying. Returns existing if already registered."""
67
+ if source_path in _ASSET_REGISTRY:
68
+ return _ASSET_REGISTRY[source_path]
69
+ asset = LocalAsset(source_path, next_id())
70
+ _ASSET_REGISTRY[source_path] = asset
71
+ return asset
72
+
73
+
74
+ def get_registered_assets() -> list[LocalAsset]:
75
+ """Get all registered local assets."""
76
+ return list(_ASSET_REGISTRY.values())
77
+
78
+
79
+ def clear_asset_registry() -> None:
80
+ """Clear asset registry (for tests)."""
81
+ _ASSET_REGISTRY.clear()