quantum-framework 0.9.0__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.
- quantum/__init__.py +1 -0
- quantum/cli/__init__.py +2 -0
- quantum/cli/commands/__init__.py +15 -0
- quantum/cli/commands/build.py +417 -0
- quantum/cli/commands/dev.py +185 -0
- quantum/cli/commands/docs.py +329 -0
- quantum/cli/commands/lint.py +523 -0
- quantum/cli/commands/migrate.py +527 -0
- quantum/cli/commands/new.py +622 -0
- quantum/cli/commands/serve.py +190 -0
- quantum/cli/commands/test.py +193 -0
- quantum/cli/deploy.py +810 -0
- quantum/cli/hot_reload.py +951 -0
- quantum/cli/jobs.py +356 -0
- quantum/cli/mq.py +582 -0
- quantum/cli/pkg.py +390 -0
- quantum/cli/runner.py +547 -0
- quantum/cli/server_process.py +159 -0
- quantum/cli/utils.py +334 -0
- quantum/compiler/__init__.py +30 -0
- quantum/compiler/base_generator.py +367 -0
- quantum/compiler/cli.py +295 -0
- quantum/compiler/expression_transformer.py +444 -0
- quantum/compiler/javascript/__init__.py +10 -0
- quantum/compiler/javascript/generator.py +659 -0
- quantum/compiler/optimizer.py +270 -0
- quantum/compiler/python/__init__.py +10 -0
- quantum/compiler/python/generator.py +883 -0
- quantum/compiler/python/runtime.py +863 -0
- quantum/compiler/transpiler.py +330 -0
- quantum/core/__init__.py +3 -0
- quantum/core/ast_nodes.py +2611 -0
- quantum/core/expression_diagnostics.py +87 -0
- quantum/core/expression_stdlib.py +148 -0
- quantum/core/expressions.py +591 -0
- quantum/core/features/agents/src/__init__.py +30 -0
- quantum/core/features/agents/src/ast_node.py +540 -0
- quantum/core/features/conditionals/src/__init__.py +8 -0
- quantum/core/features/conditionals/src/ast_node.py +68 -0
- quantum/core/features/data_fetching/src/__init__.py +21 -0
- quantum/core/features/data_fetching/src/ast_node.py +312 -0
- quantum/core/features/data_fetching/src/desktop_adapter.py +351 -0
- quantum/core/features/data_fetching/src/html_adapter.py +474 -0
- quantum/core/features/data_fetching/src/parser.py +225 -0
- quantum/core/features/data_import/src/__init__.py +0 -0
- quantum/core/features/data_import/src/ast_node.py +291 -0
- quantum/core/features/data_import/src/runtime.py +538 -0
- quantum/core/features/dump/src/__init__.py +12 -0
- quantum/core/features/dump/src/ast_node.py +106 -0
- quantum/core/features/dump/src/parser.py +61 -0
- quantum/core/features/dump/src/runtime.py +246 -0
- quantum/core/features/functions/src/__init__.py +8 -0
- quantum/core/features/functions/src/ast_node.py +149 -0
- quantum/core/features/game_engine_2d/src/__init__.py +19 -0
- quantum/core/features/game_engine_2d/src/ast_nodes.py +1719 -0
- quantum/core/features/game_engine_2d/src/parser.py +983 -0
- quantum/core/features/invocation/src/__init__.py +0 -0
- quantum/core/features/invocation/src/ast_node.py +146 -0
- quantum/core/features/invocation/src/runtime.py +327 -0
- quantum/core/features/knowledge_base/src/__init__.py +6 -0
- quantum/core/features/knowledge_base/src/ast_node.py +113 -0
- quantum/core/features/knowledge_base/src/parser.py +82 -0
- quantum/core/features/logging/src/__init__.py +12 -0
- quantum/core/features/logging/src/ast_node.py +111 -0
- quantum/core/features/logging/src/parser.py +50 -0
- quantum/core/features/logging/src/runtime.py +190 -0
- quantum/core/features/loops/src/__init__.py +8 -0
- quantum/core/features/loops/src/ast_node.py +60 -0
- quantum/core/features/query/src/__init__.py +0 -0
- quantum/core/features/query/src/database_service.py +322 -0
- quantum/core/features/query/src/query_validators.py +20 -0
- quantum/core/features/state_management/src/__init__.py +11 -0
- quantum/core/features/state_management/src/ast_node.py +228 -0
- quantum/core/features/terminal_engine/src/__init__.py +21 -0
- quantum/core/features/terminal_engine/src/ast_nodes.py +560 -0
- quantum/core/features/terminal_engine/src/parser.py +361 -0
- quantum/core/features/testing_engine/src/__init__.py +41 -0
- quantum/core/features/testing_engine/src/ast_nodes.py +1212 -0
- quantum/core/features/testing_engine/src/parser.py +604 -0
- quantum/core/features/theming/src/__init__.py +48 -0
- quantum/core/features/theming/src/ast_node.py +137 -0
- quantum/core/features/theming/src/presets.py +405 -0
- quantum/core/features/ui_engine/src/__init__.py +20 -0
- quantum/core/features/ui_engine/src/ast_nodes.py +1854 -0
- quantum/core/features/ui_engine/src/parser.py +1106 -0
- quantum/core/features/websocket/src/__init__.py +24 -0
- quantum/core/features/websocket/src/ast_node.py +247 -0
- quantum/core/html_compat.py +299 -0
- quantum/core/parser.py +1235 -0
- quantum/core/parser_registry.py +213 -0
- quantum/core/parsers/__init__.py +76 -0
- quantum/core/parsers/ai/__init__.py +12 -0
- quantum/core/parsers/ai/agent_parser.py +106 -0
- quantum/core/parsers/ai/knowledge_parser.py +86 -0
- quantum/core/parsers/ai/llm_parser.py +78 -0
- quantum/core/parsers/ai/team_parser.py +88 -0
- quantum/core/parsers/base.py +322 -0
- quantum/core/parsers/composition/__init__.py +10 -0
- quantum/core/parsers/composition/import_parser.py +50 -0
- quantum/core/parsers/composition/slot_parser.py +48 -0
- quantum/core/parsers/control_flow/__init__.py +11 -0
- quantum/core/parsers/control_flow/if_parser.py +68 -0
- quantum/core/parsers/control_flow/loop_parser.py +105 -0
- quantum/core/parsers/control_flow/set_parser.py +89 -0
- quantum/core/parsers/data/__init__.py +12 -0
- quantum/core/parsers/data/data_parser.py +217 -0
- quantum/core/parsers/data/invoke_parser.py +116 -0
- quantum/core/parsers/data/query_parser.py +188 -0
- quantum/core/parsers/data/transaction_parser.py +77 -0
- quantum/core/parsers/events/__init__.py +9 -0
- quantum/core/parsers/events/dispatch_event_parser.py +44 -0
- quantum/core/parsers/forms/__init__.py +11 -0
- quantum/core/parsers/forms/action_parser.py +54 -0
- quantum/core/parsers/forms/flash_parser.py +34 -0
- quantum/core/parsers/forms/redirect_parser.py +33 -0
- quantum/core/parsers/functions/__init__.py +11 -0
- quantum/core/parsers/functions/function_parser.py +137 -0
- quantum/core/parsers/functions/param_parser.py +66 -0
- quantum/core/parsers/functions/return_parser.py +31 -0
- quantum/core/parsers/html/__init__.py +10 -0
- quantum/core/parsers/html/component_call_parser.py +130 -0
- quantum/core/parsers/html/html_parser.py +115 -0
- quantum/core/parsers/jobs/__init__.py +11 -0
- quantum/core/parsers/jobs/job_parser.py +71 -0
- quantum/core/parsers/jobs/schedule_parser.py +62 -0
- quantum/core/parsers/jobs/thread_parser.py +57 -0
- quantum/core/parsers/messaging/__init__.py +17 -0
- quantum/core/parsers/messaging/message_ack_parser.py +30 -0
- quantum/core/parsers/messaging/message_nack_parser.py +30 -0
- quantum/core/parsers/messaging/message_parser.py +114 -0
- quantum/core/parsers/messaging/queue_parser.py +61 -0
- quantum/core/parsers/messaging/websocket_parser.py +121 -0
- quantum/core/parsers/persistence/__init__.py +9 -0
- quantum/core/parsers/persistence/persist_parser.py +64 -0
- quantum/core/parsers/routing/__init__.py +9 -0
- quantum/core/parsers/routing/route_parser.py +41 -0
- quantum/core/parsers/scripting/__init__.py +12 -0
- quantum/core/parsers/scripting/pyclass_parser.py +62 -0
- quantum/core/parsers/scripting/pydecorator_parser.py +68 -0
- quantum/core/parsers/scripting/pyimport_parser.py +52 -0
- quantum/core/parsers/scripting/python_parser.py +49 -0
- quantum/core/parsers/services/__init__.py +12 -0
- quantum/core/parsers/services/dump_parser.py +52 -0
- quantum/core/parsers/services/file_parser.py +48 -0
- quantum/core/parsers/services/log_parser.py +46 -0
- quantum/core/parsers/services/mail_parser.py +65 -0
- quantum/core/tiers.py +82 -0
- quantum/packages/__init__.py +28 -0
- quantum/packages/manager.py +413 -0
- quantum/packages/manifest.py +351 -0
- quantum/packages/registry.py +399 -0
- quantum/packages/resolver.py +336 -0
- quantum/plugins/__init__.py +33 -0
- quantum/plugins/hooks.py +329 -0
- quantum/plugins/loader.py +479 -0
- quantum/plugins/manifest.py +336 -0
- quantum/plugins/registry.py +371 -0
- quantum/runtime/__init__.py +28 -0
- quantum/runtime/action_handler.py +443 -0
- quantum/runtime/adapters/__init__.py +88 -0
- quantum/runtime/adapters/memory_adapter.py +690 -0
- quantum/runtime/adapters/rabbitmq_adapter.py +715 -0
- quantum/runtime/adapters/redis_adapter.py +582 -0
- quantum/runtime/adapters/sqlite_adapter.py +414 -0
- quantum/runtime/agent_service.py +1133 -0
- quantum/runtime/api_server.py +86 -0
- quantum/runtime/ast_cache.py +506 -0
- quantum/runtime/auth_service.py +267 -0
- quantum/runtime/component.py +990 -0
- quantum/runtime/component_composer.py +319 -0
- quantum/runtime/component_resolver.py +174 -0
- quantum/runtime/database_service.py +598 -0
- quantum/runtime/email_service.py +162 -0
- quantum/runtime/error_handler.py +295 -0
- quantum/runtime/execution_context.py +286 -0
- quantum/runtime/executor_registry.py +171 -0
- quantum/runtime/executors/__init__.py +71 -0
- quantum/runtime/executors/ai/__init__.py +12 -0
- quantum/runtime/executors/ai/agent_executor.py +217 -0
- quantum/runtime/executors/ai/knowledge_executor.py +114 -0
- quantum/runtime/executors/ai/llm_executor.py +153 -0
- quantum/runtime/executors/ai/team_executor.py +171 -0
- quantum/runtime/executors/base.py +262 -0
- quantum/runtime/executors/control_flow/__init__.py +11 -0
- quantum/runtime/executors/control_flow/if_executor.py +93 -0
- quantum/runtime/executors/control_flow/loop_executor.py +307 -0
- quantum/runtime/executors/control_flow/set_executor.py +412 -0
- quantum/runtime/executors/data/__init__.py +12 -0
- quantum/runtime/executors/data/data_executor.py +145 -0
- quantum/runtime/executors/data/invoke_executor.py +176 -0
- quantum/runtime/executors/data/query_executor.py +256 -0
- quantum/runtime/executors/data/transaction_executor.py +91 -0
- quantum/runtime/executors/jobs/__init__.py +11 -0
- quantum/runtime/executors/jobs/job_executor.py +190 -0
- quantum/runtime/executors/jobs/schedule_executor.py +132 -0
- quantum/runtime/executors/jobs/thread_executor.py +127 -0
- quantum/runtime/executors/messaging/__init__.py +17 -0
- quantum/runtime/executors/messaging/message_ack_executor.py +51 -0
- quantum/runtime/executors/messaging/message_executor.py +174 -0
- quantum/runtime/executors/messaging/queue_executor.py +103 -0
- quantum/runtime/executors/messaging/websocket_executor.py +197 -0
- quantum/runtime/executors/scripting/__init__.py +11 -0
- quantum/runtime/executors/scripting/pyclass_executor.py +90 -0
- quantum/runtime/executors/scripting/pyimport_executor.py +81 -0
- quantum/runtime/executors/scripting/python_executor.py +249 -0
- quantum/runtime/executors/services/__init__.py +12 -0
- quantum/runtime/executors/services/dump_executor.py +72 -0
- quantum/runtime/executors/services/file_executor.py +89 -0
- quantum/runtime/executors/services/log_executor.py +77 -0
- quantum/runtime/executors/services/mail_executor.py +81 -0
- quantum/runtime/expression_cache.py +498 -0
- quantum/runtime/file_upload_service.py +326 -0
- quantum/runtime/function_registry.py +118 -0
- quantum/runtime/game_builder.py +166 -0
- quantum/runtime/game_code_generator.py +2371 -0
- quantum/runtime/game_templates.py +2006 -0
- quantum/runtime/godot_code_generator.py +4681 -0
- quantum/runtime/godot_templates.py +1449 -0
- quantum/runtime/job_executor.py +1599 -0
- quantum/runtime/knowledge_service.py +500 -0
- quantum/runtime/llm_cache.py +100 -0
- quantum/runtime/llm_providers.py +704 -0
- quantum/runtime/llm_service.py +287 -0
- quantum/runtime/logging_setup.py +140 -0
- quantum/runtime/message_broker.py +364 -0
- quantum/runtime/message_queue_service.py +571 -0
- quantum/runtime/param_validation.py +184 -0
- quantum/runtime/pypy_compat.py +315 -0
- quantum/runtime/python_bridge.py +698 -0
- quantum/runtime/query_validators.py +304 -0
- quantum/runtime/renderer.py +733 -0
- quantum/runtime/service_container.py +444 -0
- quantum/runtime/terminal_builder.py +76 -0
- quantum/runtime/terminal_code_generator.py +607 -0
- quantum/runtime/terminal_templates.py +243 -0
- quantum/runtime/testing_builder.py +77 -0
- quantum/runtime/testing_code_generator.py +833 -0
- quantum/runtime/testing_templates.py +85 -0
- quantum/runtime/ui_builder.py +188 -0
- quantum/runtime/ui_desktop_adapter.py +1730 -0
- quantum/runtime/ui_desktop_templates.py +307 -0
- quantum/runtime/ui_html_adapter.py +2691 -0
- quantum/runtime/ui_html_templates.py +2297 -0
- quantum/runtime/ui_mobile_adapter.py +1832 -0
- quantum/runtime/ui_mobile_templates.py +1003 -0
- quantum/runtime/ui_textual_adapter.py +1866 -0
- quantum/runtime/ui_textual_templates.py +45 -0
- quantum/runtime/ui_tokens.py +465 -0
- quantum/runtime/ui_validator.py +365 -0
- quantum/runtime/validators.py +256 -0
- quantum/runtime/web_server.py +1766 -0
- quantum/runtime/websocket_adapter.py +501 -0
- quantum/runtime/websocket_service.py +585 -0
- quantum/runtime/websocket_transport.py +289 -0
- quantum/runtime/wsgi.py +101 -0
- quantum/utils/__init__.py +1 -0
- quantum_framework-0.9.0.dist-info/METADATA +244 -0
- quantum_framework-0.9.0.dist-info/RECORD +262 -0
- quantum_framework-0.9.0.dist-info/WHEEL +5 -0
- quantum_framework-0.9.0.dist-info/entry_points.txt +2 -0
- quantum_framework-0.9.0.dist-info/licenses/LICENSE +21 -0
- quantum_framework-0.9.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
"""
|
|
2
|
+
UI Engine - Desktop Templates
|
|
3
|
+
|
|
4
|
+
Provides templates for Python pywebview desktop apps with JS bridge:
|
|
5
|
+
- QUANTUM_STATE_CLASS: Reactive state container with JS notification
|
|
6
|
+
- QUANTUM_API_CLASS: API class template exposed to JavaScript
|
|
7
|
+
- JS_BRIDGE_CODE: JavaScript bridge for Python-JS communication
|
|
8
|
+
- DESKTOP_TEMPLATE: Complete Python pywebview app template
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from typing import Any, Dict
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# ==========================================================================
|
|
15
|
+
# QuantumState Class - Reactive state container
|
|
16
|
+
# ==========================================================================
|
|
17
|
+
|
|
18
|
+
QUANTUM_STATE_CLASS = '''\
|
|
19
|
+
class QuantumState:
|
|
20
|
+
"""Reactive state container with JS notification and persistence support."""
|
|
21
|
+
|
|
22
|
+
def __init__(self, window_ref, persist_config: Dict[str, Dict] = None):
|
|
23
|
+
self._window = window_ref
|
|
24
|
+
self._state: Dict[str, Any] = {}
|
|
25
|
+
self._persist_config = persist_config or {} # name -> {scope, key, ttl, encrypt}
|
|
26
|
+
self._storage_path = None
|
|
27
|
+
|
|
28
|
+
def set(self, name: str, value: Any):
|
|
29
|
+
"""Set a state value and notify JS."""
|
|
30
|
+
self._state[name] = value
|
|
31
|
+
self._notify_js(name, value)
|
|
32
|
+
# Auto-persist if configured
|
|
33
|
+
if name in self._persist_config:
|
|
34
|
+
self._persist_value(name, value)
|
|
35
|
+
|
|
36
|
+
def get(self, name: str, default: Any = None) -> Any:
|
|
37
|
+
"""Get a state value."""
|
|
38
|
+
return self._state.get(name, default)
|
|
39
|
+
|
|
40
|
+
def _notify_js(self, name: str, value: Any):
|
|
41
|
+
"""Push state update to JS."""
|
|
42
|
+
if self._window:
|
|
43
|
+
import json
|
|
44
|
+
js_value = json.dumps(value)
|
|
45
|
+
self._window.evaluate_js(
|
|
46
|
+
f"window.__quantumStateUpdate(\\'{name}\\', {js_value})"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
def _get_storage_path(self) -> str:
|
|
50
|
+
"""Get the storage path for file-based persistence."""
|
|
51
|
+
if self._storage_path:
|
|
52
|
+
return self._storage_path
|
|
53
|
+
import os
|
|
54
|
+
import sys
|
|
55
|
+
# Use user data directory based on platform
|
|
56
|
+
if sys.platform == 'win32':
|
|
57
|
+
base = os.environ.get('LOCALAPPDATA', os.path.expanduser('~'))
|
|
58
|
+
elif sys.platform == 'darwin':
|
|
59
|
+
base = os.path.expanduser('~/Library/Application Support')
|
|
60
|
+
else:
|
|
61
|
+
base = os.environ.get('XDG_DATA_HOME', os.path.expanduser('~/.local/share'))
|
|
62
|
+
self._storage_path = os.path.join(base, 'quantum_app', 'persist')
|
|
63
|
+
os.makedirs(self._storage_path, exist_ok=True)
|
|
64
|
+
return self._storage_path
|
|
65
|
+
|
|
66
|
+
def _persist_value(self, name: str, value: Any):
|
|
67
|
+
"""Persist a value to storage based on configuration."""
|
|
68
|
+
import json
|
|
69
|
+
import os
|
|
70
|
+
config = self._persist_config.get(name, {})
|
|
71
|
+
scope = config.get('scope', 'local')
|
|
72
|
+
key = config.get('key', name)
|
|
73
|
+
ttl = config.get('ttl')
|
|
74
|
+
|
|
75
|
+
storage_path = self._get_storage_path()
|
|
76
|
+
file_path = os.path.join(storage_path, f'{key}.json')
|
|
77
|
+
|
|
78
|
+
data = {'value': value}
|
|
79
|
+
if ttl:
|
|
80
|
+
import time
|
|
81
|
+
data['_ttl'] = int(time.time()) + ttl
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
with open(file_path, 'w', encoding='utf-8') as f:
|
|
85
|
+
json.dump(data, f)
|
|
86
|
+
except Exception as e:
|
|
87
|
+
print(f'Persist error for {name}: {e}')
|
|
88
|
+
|
|
89
|
+
def _restore_persisted(self, name: str) -> Any:
|
|
90
|
+
"""Restore a persisted value from storage."""
|
|
91
|
+
import json
|
|
92
|
+
import os
|
|
93
|
+
config = self._persist_config.get(name, {})
|
|
94
|
+
key = config.get('key', name)
|
|
95
|
+
|
|
96
|
+
storage_path = self._get_storage_path()
|
|
97
|
+
file_path = os.path.join(storage_path, f'{key}.json')
|
|
98
|
+
|
|
99
|
+
if not os.path.exists(file_path):
|
|
100
|
+
return None
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
104
|
+
data = json.load(f)
|
|
105
|
+
|
|
106
|
+
# Check TTL expiration
|
|
107
|
+
if '_ttl' in data:
|
|
108
|
+
import time
|
|
109
|
+
if time.time() > data['_ttl']:
|
|
110
|
+
os.remove(file_path)
|
|
111
|
+
return None
|
|
112
|
+
|
|
113
|
+
return data.get('value')
|
|
114
|
+
except Exception as e:
|
|
115
|
+
print(f'Restore error for {name}: {e}')
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
def restore_all_persisted(self):
|
|
119
|
+
"""Restore all persisted values on startup."""
|
|
120
|
+
for name in self._persist_config:
|
|
121
|
+
value = self._restore_persisted(name)
|
|
122
|
+
if value is not None:
|
|
123
|
+
self._state[name] = value
|
|
124
|
+
self._notify_js(name, value)
|
|
125
|
+
|
|
126
|
+
def remove_persisted(self, name: str):
|
|
127
|
+
"""Remove a persisted value from storage."""
|
|
128
|
+
import os
|
|
129
|
+
config = self._persist_config.get(name, {})
|
|
130
|
+
key = config.get('key', name)
|
|
131
|
+
|
|
132
|
+
storage_path = self._get_storage_path()
|
|
133
|
+
file_path = os.path.join(storage_path, f'{key}.json')
|
|
134
|
+
|
|
135
|
+
if os.path.exists(file_path):
|
|
136
|
+
try:
|
|
137
|
+
os.remove(file_path)
|
|
138
|
+
except Exception as e:
|
|
139
|
+
print(f'Remove persist error for {name}: {e}')
|
|
140
|
+
'''
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# ==========================================================================
|
|
144
|
+
# QuantumAPI Class Template - API exposed to JavaScript
|
|
145
|
+
# ==========================================================================
|
|
146
|
+
|
|
147
|
+
QUANTUM_API_CLASS = '''\
|
|
148
|
+
class QuantumAPI:
|
|
149
|
+
"""API exposed to JavaScript via pywebview."""
|
|
150
|
+
|
|
151
|
+
def __init__(self):
|
|
152
|
+
self._window = None
|
|
153
|
+
self.state = None
|
|
154
|
+
self._persist_config = {persist_config}
|
|
155
|
+
|
|
156
|
+
def _set_window(self, window):
|
|
157
|
+
"""Initialize window reference and state with persistence."""
|
|
158
|
+
self._window = window
|
|
159
|
+
self.state = QuantumState(window, self._persist_config)
|
|
160
|
+
# Restore persisted values first
|
|
161
|
+
self.state.restore_all_persisted()
|
|
162
|
+
# State initialization
|
|
163
|
+
{state_init}
|
|
164
|
+
|
|
165
|
+
def set_state(self, args):
|
|
166
|
+
"""Two-way binding from JS inputs.
|
|
167
|
+
|
|
168
|
+
Chamava-se `__set_state`. Dois underscores dentro de uma classe
|
|
169
|
+
acionam o name mangling do Python: o metodo passa a existir como
|
|
170
|
+
`_QuantumAPI__set_state`, e o pywebview so expoe nomes publicos. O JS
|
|
171
|
+
gerado chamava `__quantumCall('__set_state', ...)`, que caia no
|
|
172
|
+
`console.warn('function not found')` — em silencio, do lado do
|
|
173
|
+
usuario. Ou seja: TODO input com `bind=` no alvo desktop nunca
|
|
174
|
+
escreveu de volta no Python.
|
|
175
|
+
"""
|
|
176
|
+
name = args.get('name') if isinstance(args, dict) else None
|
|
177
|
+
value = args.get('value') if isinstance(args, dict) else None
|
|
178
|
+
if name:
|
|
179
|
+
self.state.set(name, value)
|
|
180
|
+
|
|
181
|
+
{function_methods}
|
|
182
|
+
'''
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# ==========================================================================
|
|
186
|
+
# JavaScript Bridge Code
|
|
187
|
+
# ==========================================================================
|
|
188
|
+
|
|
189
|
+
JS_BRIDGE_CODE = '''\
|
|
190
|
+
<script>
|
|
191
|
+
// Quantum Desktop Bridge
|
|
192
|
+
window.__quantumState = {};
|
|
193
|
+
window.__quantumBindings = {};
|
|
194
|
+
|
|
195
|
+
// Called by Python when state changes
|
|
196
|
+
window.__quantumStateUpdate = function(name, value) {
|
|
197
|
+
window.__quantumState[name] = value;
|
|
198
|
+
var bindings = window.__quantumBindings[name] || [];
|
|
199
|
+
bindings.forEach(function(b) {
|
|
200
|
+
if (b.type === 'text') b.el.textContent = value;
|
|
201
|
+
else if (b.type === 'value') b.el.value = value;
|
|
202
|
+
else if (b.type === 'html') b.el.innerHTML = value;
|
|
203
|
+
});
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// Register element to receive state updates
|
|
207
|
+
window.__quantumBind = function(elId, stateName, type) {
|
|
208
|
+
var el = document.getElementById(elId);
|
|
209
|
+
if (!el) return;
|
|
210
|
+
if (!window.__quantumBindings[stateName]) {
|
|
211
|
+
window.__quantumBindings[stateName] = [];
|
|
212
|
+
}
|
|
213
|
+
window.__quantumBindings[stateName].push({el: el, type: type || 'text'});
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
// Wrapper to call Python functions
|
|
217
|
+
window.__quantumCall = async function(fn, args) {
|
|
218
|
+
if (window.pywebview && window.pywebview.api && window.pywebview.api[fn]) {
|
|
219
|
+
return await window.pywebview.api[fn](args || {});
|
|
220
|
+
} else {
|
|
221
|
+
console.warn('Quantum: API not ready or function not found:', fn);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
// Form data collector
|
|
226
|
+
window.__quantumFormData = function(form) {
|
|
227
|
+
var data = {};
|
|
228
|
+
var formData = new FormData(form);
|
|
229
|
+
formData.forEach(function(value, key) {
|
|
230
|
+
data[key] = value;
|
|
231
|
+
});
|
|
232
|
+
return data;
|
|
233
|
+
};
|
|
234
|
+
</script>
|
|
235
|
+
'''
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
# ==========================================================================
|
|
239
|
+
# Desktop App Template
|
|
240
|
+
# ==========================================================================
|
|
241
|
+
|
|
242
|
+
DESKTOP_TEMPLATE = '''\
|
|
243
|
+
"""Quantum UI Desktop App - Generated pywebview Application
|
|
244
|
+
|
|
245
|
+
This file was generated by the Quantum UI Engine.
|
|
246
|
+
It creates a native desktop window using pywebview with
|
|
247
|
+
bidirectional Python-JS communication.
|
|
248
|
+
"""
|
|
249
|
+
|
|
250
|
+
import webview
|
|
251
|
+
from typing import Dict, Any
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
{quantum_state_class}
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
{quantum_api_class}
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def main():
|
|
261
|
+
"""Main entry point for the desktop application."""
|
|
262
|
+
html_content = {html_content}
|
|
263
|
+
|
|
264
|
+
# Create API instance
|
|
265
|
+
api = QuantumAPI()
|
|
266
|
+
|
|
267
|
+
# Create window with API
|
|
268
|
+
window = webview.create_window(
|
|
269
|
+
title={title},
|
|
270
|
+
html=html_content,
|
|
271
|
+
width={width},
|
|
272
|
+
height={height},
|
|
273
|
+
js_api=api,
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
# Set window reference after creation
|
|
277
|
+
def on_loaded():
|
|
278
|
+
api._set_window(window)
|
|
279
|
+
|
|
280
|
+
window.events.loaded += on_loaded
|
|
281
|
+
|
|
282
|
+
# Start the application
|
|
283
|
+
webview.start()
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
if __name__ == "__main__":
|
|
287
|
+
main()
|
|
288
|
+
'''
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
# ==========================================================================
|
|
292
|
+
# Helper functions for code generation
|
|
293
|
+
# ==========================================================================
|
|
294
|
+
|
|
295
|
+
def escape_for_python_string(s: str) -> str:
|
|
296
|
+
"""Escape a string for use in a Python triple-quoted string."""
|
|
297
|
+
# Replace backslashes first, then other special chars
|
|
298
|
+
s = s.replace('\\', '\\\\')
|
|
299
|
+
s = s.replace("'''", "\\'\\'\\'")
|
|
300
|
+
return s
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def indent_code(code: str, spaces: int = 8) -> str:
|
|
304
|
+
"""Indent each line of code by the specified number of spaces."""
|
|
305
|
+
indent = ' ' * spaces
|
|
306
|
+
lines = code.split('\n')
|
|
307
|
+
return '\n'.join(indent + line if line.strip() else line for line in lines)
|