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
pulse/js/react.py ADDED
@@ -0,0 +1,495 @@
1
+ """
2
+ JavaScript React module.
3
+
4
+ Usage:
5
+
6
+ ```python
7
+ from pulse.js.react import useState, useEffect, useRef
8
+ state, setState = useState(0) # -> const [state, setState] = useState(0)
9
+ useEffect(lambda: print("hi"), []) # -> useEffect(() => console.log("hi"), [])
10
+ ref = useRef(None) # -> const ref = useRef(null)
11
+
12
+ # Also available as namespace:
13
+ import pulse.js.react as React
14
+ React.useState(0) # -> React.useState(0)
15
+ ```
16
+ """
17
+
18
+ import ast as _ast
19
+ from collections.abc import Callable as _Callable
20
+ from typing import TYPE_CHECKING as _TYPE_CHECKING
21
+ from typing import Any as _Any
22
+ from typing import Protocol as _Protocol
23
+ from typing import TypeVar as _TypeVar
24
+ from typing import override as _override
25
+
26
+ from pulse.component import component as _component
27
+ from pulse.transpiler import Import as _Import
28
+ from pulse.transpiler.errors import TranspileError as _TranspileError
29
+ from pulse.transpiler.function import Constant as _Constant
30
+ from pulse.transpiler.js_module import JsModule
31
+ from pulse.transpiler.nodes import Call as _Call
32
+ from pulse.transpiler.nodes import Expr as _Expr
33
+ from pulse.transpiler.nodes import Jsx as _Jsx
34
+ from pulse.transpiler.nodes import Node as _PulseNode
35
+
36
+ if _TYPE_CHECKING:
37
+ from pulse.transpiler.transpiler import Transpiler as _Transpiler
38
+
39
+ # Type variables for hooks
40
+ T = _TypeVar("T")
41
+ T_co = _TypeVar("T_co", covariant=True)
42
+ T_contra = _TypeVar("T_contra", contravariant=True)
43
+ S = _TypeVar("S")
44
+ A = _TypeVar("A")
45
+
46
+
47
+ # =============================================================================
48
+ # React Types
49
+ # =============================================================================
50
+
51
+
52
+ class RefObject(_Protocol[T_co]):
53
+ """Type for useRef return value."""
54
+
55
+ @property
56
+ def current(self) -> T_co: ...
57
+
58
+
59
+ class MutableRefObject(_Protocol[T]):
60
+ """Type for useRef return value with mutable current."""
61
+
62
+ @property
63
+ def current(self) -> T: ...
64
+
65
+ @current.setter
66
+ def current(self, value: T) -> None: ...
67
+
68
+
69
+ class Dispatch(_Protocol[T_contra]):
70
+ """Type for setState/dispatch functions."""
71
+
72
+ def __call__(self, action: T_contra, /) -> None: ...
73
+
74
+
75
+ class TransitionStartFunction(_Protocol):
76
+ """Type for startTransition callback."""
77
+
78
+ def __call__(self, callback: _Callable[[], None], /) -> None: ...
79
+
80
+
81
+ class Context(_Protocol[T_co]):
82
+ """Type for React Context."""
83
+
84
+ @property
85
+ def Provider(self) -> _Any: ...
86
+
87
+ @property
88
+ def Consumer(self) -> _Any: ...
89
+
90
+
91
+ class ReactNode(_Protocol):
92
+ """Type for React children."""
93
+
94
+ ...
95
+
96
+
97
+ class ReactElement(_Protocol):
98
+ """Type for React element."""
99
+
100
+ @property
101
+ def type(self) -> _Any: ...
102
+
103
+ @property
104
+ def props(self) -> _Any: ...
105
+
106
+ @property
107
+ def key(self) -> str | None: ...
108
+
109
+
110
+ # =============================================================================
111
+ # State Hooks
112
+ # =============================================================================
113
+
114
+
115
+ def useState(
116
+ initial_state: S | _Callable[[], S],
117
+ ) -> tuple[S, Dispatch[S | _Callable[[S], S]]]:
118
+ """Returns a stateful value and a function to update it.
119
+
120
+ Example:
121
+
122
+ ```python
123
+ count, set_count = useState(0)
124
+ set_count(count + 1)
125
+ set_count(lambda prev: prev + 1)
126
+ ```
127
+ """
128
+ ...
129
+
130
+
131
+ def useReducer(
132
+ reducer: _Callable[[S, A], S],
133
+ initial_arg: S,
134
+ init: _Callable[[S], S] | None = None,
135
+ ) -> tuple[S, Dispatch[A]]:
136
+ """An alternative to `useState` for complex state logic.
137
+
138
+ Example:
139
+
140
+ ```python
141
+ def reducer(state, action):
142
+ if action['type'] == 'increment':
143
+ return {'count': state['count'] + 1}
144
+ return state
145
+
146
+ state, dispatch = useReducer(reducer, {'count': 0})
147
+ dispatch({'type': 'increment'})
148
+ ```
149
+ """
150
+ ...
151
+
152
+
153
+ # =============================================================================
154
+ # Effect Hooks
155
+ # =============================================================================
156
+
157
+
158
+ def useEffect(
159
+ effect: _Callable[[], None | _Callable[[], None]],
160
+ deps: list[_Any] | None = None,
161
+ ) -> None:
162
+ """Accepts a function that contains imperative, possibly effectful code.
163
+
164
+ Example:
165
+
166
+ ```python
167
+ useEffect(lambda: print("mounted"), [])
168
+ useEffect(lambda: (print("update"), lambda: print("cleanup"))[-1], [dep])
169
+ ```
170
+ """
171
+ ...
172
+
173
+
174
+ def useLayoutEffect(
175
+ effect: _Callable[[], None | _Callable[[], None]],
176
+ deps: list[_Any] | None = None,
177
+ ) -> None:
178
+ """Like `useEffect`, but fires synchronously after all DOM mutations.
179
+
180
+ Example:
181
+
182
+ ```python
183
+ useLayoutEffect(lambda: measure_element(), [])
184
+ ```
185
+ """
186
+ ...
187
+
188
+
189
+ def useInsertionEffect(
190
+ effect: _Callable[[], None | _Callable[[], None]],
191
+ deps: list[_Any] | None = None,
192
+ ) -> None:
193
+ """Like useLayoutEffect, but fires before any DOM mutations.
194
+ Use for CSS-in-JS libraries.
195
+ """
196
+ ...
197
+
198
+
199
+ # =============================================================================
200
+ # Ref Hooks
201
+ # =============================================================================
202
+
203
+
204
+ def useRef(initial_value: T) -> MutableRefObject[T]:
205
+ """Returns a mutable ref object.
206
+
207
+ Example:
208
+
209
+ ```python
210
+ input_ref = useRef(None)
211
+ # In JSX: <input ref={input_ref} />
212
+ input_ref.current.focus()
213
+ ```
214
+ """
215
+ ...
216
+
217
+
218
+ def useImperativeHandle(
219
+ ref: RefObject[T] | _Callable[[T | None], None] | None,
220
+ create_handle: _Callable[[], T],
221
+ deps: list[_Any] | None = None,
222
+ ) -> None:
223
+ """Customizes the instance value exposed to parent components when using ref."""
224
+ ...
225
+
226
+
227
+ # =============================================================================
228
+ # Performance Hooks
229
+ # =============================================================================
230
+
231
+
232
+ def useMemo(factory: _Callable[[], T], deps: list[_Any]) -> T:
233
+ """Returns a memoized value.
234
+
235
+ Example:
236
+
237
+ ```python
238
+ expensive = useMemo(lambda: compute_expensive(a, b), [a, b])
239
+ ```
240
+ """
241
+ ...
242
+
243
+
244
+ def useCallback(callback: T, deps: list[_Any]) -> T:
245
+ """Returns a memoized callback.
246
+
247
+ Example:
248
+
249
+ ```python
250
+ handle_click = useCallback(lambda e: print(e), [])
251
+ ```
252
+ """
253
+ ...
254
+
255
+
256
+ def useDeferredValue(value: T) -> T:
257
+ """Defers updating a part of the UI. Returns a deferred version of the value."""
258
+ ...
259
+
260
+
261
+ def useTransition() -> tuple[bool, TransitionStartFunction]:
262
+ """Returns a stateful value for pending state and a function to start transition.
263
+
264
+ Example:
265
+
266
+ ```python
267
+ is_pending, start_transition = useTransition()
268
+ start_transition(lambda: set_state(new_value))
269
+ ```
270
+ """
271
+ ...
272
+
273
+
274
+ # =============================================================================
275
+ # Context Hooks
276
+ # =============================================================================
277
+
278
+
279
+ def useContext(context: Context[T]) -> T:
280
+ """Returns the current context value for the given context.
281
+
282
+ Example:
283
+
284
+ ```python
285
+ theme = useContext(ThemeContext)
286
+ ```
287
+ """
288
+ ...
289
+
290
+
291
+ # =============================================================================
292
+ # Other Hooks
293
+ # =============================================================================
294
+
295
+
296
+ def useId() -> str:
297
+ """Generates a unique ID that is stable across server and client.
298
+
299
+ Example:
300
+
301
+ ```python
302
+ id = useId()
303
+ # <label htmlFor={id}>Name</label>
304
+ # <input id={id} />
305
+ ```
306
+ """
307
+ ...
308
+
309
+
310
+ def useDebugValue(value: T, format_fn: _Callable[[T], _Any] | None = None) -> None:
311
+ """Displays a label in React DevTools for custom hooks."""
312
+ ...
313
+
314
+
315
+ def useSyncExternalStore(
316
+ subscribe: _Callable[[_Callable[[], None]], _Callable[[], None]],
317
+ get_snapshot: _Callable[[], T],
318
+ get_server_snapshot: _Callable[[], T] | None = None,
319
+ ) -> T:
320
+ """Subscribe to an external store.
321
+
322
+ Example:
323
+
324
+ ```python
325
+ width = useSyncExternalStore(
326
+ subscribe_to_resize,
327
+ lambda: window.innerWidth
328
+ )
329
+ ```
330
+ """
331
+ ...
332
+
333
+
334
+ # =============================================================================
335
+ # React Components and Elements
336
+ # =============================================================================
337
+
338
+
339
+ def createElement(
340
+ type: _Any,
341
+ props: dict[str, _Any] | None = None,
342
+ *children: _Any,
343
+ ) -> ReactElement:
344
+ """Creates a React element."""
345
+ ...
346
+
347
+
348
+ def cloneElement(
349
+ element: ReactElement,
350
+ props: dict[str, _Any] | None = None,
351
+ *children: _Any,
352
+ ) -> ReactElement:
353
+ """Clones and returns a new React element."""
354
+ ...
355
+
356
+
357
+ def isValidElement(obj: _Any) -> bool:
358
+ """Checks if the object is a React element."""
359
+ ...
360
+
361
+
362
+ def memo(component: T, are_equal: _Callable[[_Any, _Any], bool] | None = None) -> T:
363
+ """Memoizes a component to skip re-rendering when props are unchanged."""
364
+ ...
365
+
366
+
367
+ def forwardRef(
368
+ render: _Callable[[_Any, _Any], ReactElement | None],
369
+ ) -> _Callable[..., ReactElement | None]:
370
+ """Lets your component expose a DOM node to a parent component with a ref."""
371
+ ...
372
+
373
+
374
+ class _LazyComponentFactory(_Expr):
375
+ """React.lazy binding that works both at definition time and in `@javascript`.
376
+
377
+ This Expr represents React's `lazy` function. It can be:
378
+ - Called at Python definition time: `lazy(factory)` → `Jsx(Constant(...))`
379
+ - Used as a reference in `@javascript`: `some_fn(lazy)` → `some_fn(lazy)`
380
+ - Called inside `@javascript`: `lazy(factory)` → creates `Constant+Jsx`
381
+
382
+ Usage:
383
+
384
+ ```python
385
+ # At definition time (Python executes this)
386
+ LazyChart = lazy(Import("./Chart", lazy=True))
387
+
388
+ # As reference in transpiled code
389
+ @javascript
390
+ def foo():
391
+ return higher_order_fn(lazy) # → higher_order_fn(lazy)
392
+
393
+ # Called in transpiled code
394
+ @javascript
395
+ def bar():
396
+ LazyComp = lazy(factory) # → const LazyComp_1 = lazy(factory)
397
+ return LazyComp()
398
+ ```
399
+ """
400
+
401
+ __slots__: tuple[str, ...] = ("_lazy_import",)
402
+ _lazy_import: _Import | None
403
+
404
+ def __init__(self) -> None:
405
+ # Defer Import creation to avoid polluting global import registry at module load
406
+ self._lazy_import = None
407
+
408
+ @property
409
+ def _import(self) -> _Import:
410
+ """Lazily create the React.lazy import."""
411
+ if self._lazy_import is None:
412
+ self._lazy_import = _Import("lazy", "react")
413
+ return self._lazy_import
414
+
415
+ def _create_lazy_component(self, factory: _Expr) -> _Jsx:
416
+ """Create a lazy-loaded component from a factory expression.
417
+
418
+ Args:
419
+ factory: An Expr that evaluates to a dynamic import factory
420
+
421
+ Returns:
422
+ A Jsx-wrapped lazy component
423
+ """
424
+ lazy_call = _Call(self._import, [factory])
425
+ const = _Constant(lazy_call, lazy_call)
426
+ return _Jsx(const)
427
+
428
+ @_override
429
+ def emit(self, out: list[str]) -> None:
430
+ """Emit as reference to the lazy import."""
431
+ self._import.emit(out)
432
+
433
+ @_override
434
+ def render(self):
435
+ raise TypeError("lazy cannot be rendered to VDOM")
436
+
437
+ @_override
438
+ def transpile_call(
439
+ self,
440
+ args: list[_ast.expr],
441
+ keywords: list[_ast.keyword],
442
+ ctx: "_Transpiler",
443
+ ) -> _Expr:
444
+ """Handle lazy(factory) calls in @javascript functions."""
445
+ if keywords:
446
+ raise _TranspileError("lazy() does not accept keyword arguments")
447
+ if len(args) != 1:
448
+ raise _TranspileError("lazy() takes exactly 1 argument")
449
+
450
+ factory = ctx.emit_expr(args[0])
451
+ return self._create_lazy_component(factory)
452
+
453
+ @_override
454
+ def __call__(self, factory: _Import) -> _Jsx: # pyright: ignore[reportIncompatibleMethodOverride]
455
+ """Python-time call: create a lazy-loaded component.
456
+
457
+ Args:
458
+ factory: An Import with lazy=True that generates a dynamic import factory
459
+
460
+ Returns:
461
+ A Jsx-wrapped lazy component that can be used as LazyChart(props)[children]
462
+ """
463
+ return self._create_lazy_component(factory)
464
+
465
+
466
+ # Singleton instance - use as: lazy(Import(...))
467
+ lazy: _LazyComponentFactory = _LazyComponentFactory()
468
+ # Register so transpiler can resolve it from closure
469
+ _Expr.register(lazy, lazy)
470
+
471
+
472
+ def createContext(default_value: T) -> Context[T]:
473
+ """Creates a Context object."""
474
+ ...
475
+
476
+
477
+ # =============================================================================
478
+ # Components (stub declarations become Jsx-wrapped imports)
479
+ # =============================================================================
480
+
481
+
482
+ @_component
483
+ def Suspense(
484
+ *, fallback: ReactNode | _PulseNode | None = None, name: str | None = None
485
+ ) -> ReactElement:
486
+ """Lets you display a fallback while its children are loading."""
487
+ ...
488
+
489
+
490
+ # =============================================================================
491
+ # Registration
492
+ # =============================================================================
493
+
494
+ # React is a namespace module where each hook is a named import
495
+ JsModule.register(name="React", src="react", kind="namespace", values="named_import")
pulse/js/regexp.py ADDED
@@ -0,0 +1,57 @@
1
+ """
2
+ JavaScript RegExp builtin module.
3
+
4
+ Usage:
5
+
6
+ ```python
7
+ from pulse.js import RegExp
8
+ RegExp(pattern, flags) # -> new RegExp(pattern, flags)
9
+
10
+ # Or import from module directly:
11
+ from pulse.js.regexp import RegExp
12
+ ```
13
+ """
14
+
15
+ from pulse.transpiler.js_module import JsModule
16
+
17
+
18
+ class RegExp:
19
+ """Class for JavaScript RegExp instances."""
20
+
21
+ def __init__(self, pattern: str, flags: str | None = None, /): ...
22
+
23
+ def exec(self, string: str) -> list[str] | None: ...
24
+ def test(self, string: str) -> bool: ...
25
+
26
+ @property
27
+ def source(self) -> str: ...
28
+
29
+ @property
30
+ def flags(self) -> str: ...
31
+
32
+ @property
33
+ def glob(self) -> bool: ... # JavaScript 'global' property
34
+
35
+ @property
36
+ def ignoreCase(self) -> bool: ...
37
+
38
+ @property
39
+ def multiline(self) -> bool: ...
40
+
41
+ @property
42
+ def dotAll(self) -> bool: ...
43
+
44
+ @property
45
+ def unicode(self) -> bool: ...
46
+
47
+ @property
48
+ def sticky(self) -> bool: ...
49
+
50
+ @property
51
+ def lastIndex(self) -> int: ...
52
+
53
+ def toString(self) -> str: ...
54
+
55
+
56
+ # Self-register this module as a JS builtin (global identifiers)
57
+ JsModule.register(name=None)
pulse/js/set.py ADDED
@@ -0,0 +1,124 @@
1
+ """
2
+ JavaScript Set builtin module.
3
+
4
+ Usage:
5
+
6
+ ```python
7
+ from pulse.js import Set
8
+ Set() # -> new Set()
9
+ Set([1, 2, 3]) # -> new Set([1, 2, 3])
10
+
11
+ # Or import from module directly:
12
+ from pulse.js.set import Set
13
+ ```
14
+ """
15
+
16
+ from collections.abc import Callable as _Callable
17
+ from collections.abc import Iterable as _Iterable
18
+ from collections.abc import Iterator as _Iterator
19
+ from typing import Any as _Any
20
+ from typing import Generic as _Generic
21
+ from typing import TypeVar as _TypeVar
22
+
23
+ from pulse.transpiler.js_module import JsModule
24
+
25
+ T = _TypeVar("T")
26
+
27
+
28
+ class Set(_Generic[T]):
29
+ """JavaScript Set - a collection of unique values.
30
+
31
+ Set[T] stores unique values of type T in insertion order.
32
+ """
33
+
34
+ def __init__(self, iterable: _Iterable[T] | None = None, /) -> None: ...
35
+
36
+ @property
37
+ def size(self) -> int:
38
+ """The number of values in the Set."""
39
+ ...
40
+
41
+ def add(self, value: T) -> "Set[T]":
42
+ """Add a value to the Set. Returns the Set for chaining."""
43
+ ...
44
+
45
+ def clear(self) -> None:
46
+ """Remove all values from the Set."""
47
+ ...
48
+
49
+ def delete(self, value: T) -> bool:
50
+ """Remove a value. Returns True if the value existed."""
51
+ ...
52
+
53
+ def has(self, value: T) -> bool:
54
+ """Return True if the value exists in the Set."""
55
+ ...
56
+
57
+ def forEach(
58
+ self,
59
+ callback: _Callable[[T, T, "Set[T]"], None],
60
+ thisArg: _Any | None = None,
61
+ /,
62
+ ) -> None:
63
+ """Execute a function for each value.
64
+
65
+ Note: callback receives (value, value, set) for compatibility with Map.
66
+ """
67
+ ...
68
+
69
+ def keys(self) -> _Iterable[T]:
70
+ """Return an iterator of values (same as values())."""
71
+ ...
72
+
73
+ def values(self) -> _Iterable[T]:
74
+ """Return an iterator of values."""
75
+ ...
76
+
77
+ def entries(self) -> _Iterable[tuple[T, T]]:
78
+ """Return an iterator of [value, value] pairs."""
79
+ ...
80
+
81
+ def __iter__(self) -> _Iterator[T]:
82
+ """Iterate over values."""
83
+ ...
84
+
85
+ def __len__(self) -> int:
86
+ """Return the number of values (same as size)."""
87
+ ...
88
+
89
+ def __contains__(self, value: T) -> bool:
90
+ """Check if value exists in the Set (same as has)."""
91
+ ...
92
+
93
+ # ES2024 Set methods
94
+ def union(self, other: "Set[T]") -> "Set[T]":
95
+ """Return a new Set with values from both sets (ES2024)."""
96
+ ...
97
+
98
+ def intersection(self, other: "Set[T]") -> "Set[T]":
99
+ """Return a new Set with values in both sets (ES2024)."""
100
+ ...
101
+
102
+ def difference(self, other: "Set[T]") -> "Set[T]":
103
+ """Return a new Set with values in this but not other (ES2024)."""
104
+ ...
105
+
106
+ def symmetricDifference(self, other: "Set[T]") -> "Set[T]":
107
+ """Return a new Set with values in either but not both (ES2024)."""
108
+ ...
109
+
110
+ def isSubsetOf(self, other: "Set[T]") -> bool:
111
+ """Return True if all values are in other (ES2024)."""
112
+ ...
113
+
114
+ def isSupersetOf(self, other: "Set[T]") -> bool:
115
+ """Return True if all values of other are in this (ES2024)."""
116
+ ...
117
+
118
+ def isDisjointFrom(self, other: "Set[T]") -> bool:
119
+ """Return True if no values are in common (ES2024)."""
120
+ ...
121
+
122
+
123
+ # Self-register this module as a JS builtin (global identifiers)
124
+ JsModule.register(name=None)
pulse/js/string.py ADDED
@@ -0,0 +1,38 @@
1
+ """
2
+ JavaScript String builtin module.
3
+
4
+ Usage:
5
+
6
+ ```python
7
+ from pulse.js import String
8
+ String(x) # -> new String(x)
9
+ String.fromCharCode(65) # -> String.fromCharCode(65)
10
+ String.fromCodePoint(0x1F600) # -> String.fromCodePoint(0x1F600)
11
+
12
+ # Or import from module directly:
13
+ from pulse.js.string import String
14
+ ```
15
+ """
16
+
17
+ from typing import Any as _Any
18
+
19
+ from pulse.transpiler.js_module import JsModule
20
+
21
+
22
+ class String:
23
+ """JavaScript String constructor."""
24
+
25
+ def __init__(self, value: _Any) -> None: ...
26
+
27
+ @staticmethod
28
+ def fromCharCode(*codes: int) -> str: ...
29
+
30
+ @staticmethod
31
+ def fromCodePoint(*codePoints: int) -> str: ...
32
+
33
+ @staticmethod
34
+ def raw(template: str, *substitutions: str) -> str: ...
35
+
36
+
37
+ # Self-register this module as a JS builtin (global identifier)
38
+ JsModule.register(name=None)