quantum-framework 0.15.0__tar.gz → 0.16.0__tar.gz
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_framework-0.15.0/quantum_framework.egg-info → quantum_framework-0.16.0}/PKG-INFO +3 -1
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/pyproject.toml +5 -1
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/commands/build.py +4 -7
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/runner.py +12 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/ast_nodes.py +1 -1
- quantum_framework-0.16.0/quantum/core/docs_links.py +8 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/state_management/src/ast_node.py +0 -107
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/ui_engine/src/ast_nodes.py +24 -1
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/ui_engine/src/parser.py +19 -2
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parser.py +16 -7
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/control_flow/set_parser.py +10 -11
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/tiers.py +20 -1
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/action_handler.py +2 -1
- quantum_framework-0.16.0/quantum/runtime/local_server.py +28 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/ui_builder.py +50 -21
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/ui_console.py +167 -36
- quantum_framework-0.16.0/quantum/runtime/ui_desktop.py +56 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/ui_html_adapter.py +43 -191
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/ui_html_templates.py +2 -247
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/ui_page_renderer.py +106 -3
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/ui_view.py +37 -2
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/web_server.py +6 -5
- {quantum_framework-0.15.0 → quantum_framework-0.16.0/quantum_framework.egg-info}/PKG-INFO +3 -1
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_framework.egg-info/SOURCES.txt +3 -6
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_framework.egg-info/requires.txt +3 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_cli_commands.py +4 -5
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_ui_html_adapter.py +0 -25
- quantum_framework-0.15.0/quantum/core/parsers/persistence/__init__.py +0 -9
- quantum_framework-0.15.0/quantum/core/parsers/persistence/persist_parser.py +0 -64
- quantum_framework-0.15.0/quantum/runtime/ui_desktop_adapter.py +0 -1730
- quantum_framework-0.15.0/quantum/runtime/ui_desktop_templates.py +0 -307
- quantum_framework-0.15.0/tests/test_desktop_bridge.py +0 -442
- quantum_framework-0.15.0/tests/test_state_persistence.py +0 -458
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/LICENSE +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/README.md +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/admin.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/commands/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/commands/dev.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/commands/docs.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/commands/lint.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/commands/migrate.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/commands/new.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/commands/serve.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/commands/test.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/deploy.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/hot_reload.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/jobs.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/mq.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/pkg.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/server_process.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/cli/utils.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/compiler/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/compiler/base_generator.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/compiler/cli.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/compiler/expression_transformer.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/compiler/javascript/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/compiler/javascript/generator.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/compiler/optimizer.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/compiler/python/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/compiler/python/generator.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/compiler/python/runtime.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/compiler/transpiler.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/config_env.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/expression_diagnostics.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/expression_stdlib.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/expressions.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/agents/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/agents/src/ast_node.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/conditionals/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/conditionals/src/ast_node.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/data_import/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/data_import/src/ast_node.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/data_import/src/runtime.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/dump/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/dump/src/ast_node.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/dump/src/parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/dump/src/runtime.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/functions/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/functions/src/ast_node.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/game_engine_2d/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/game_engine_2d/src/ast_nodes.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/game_engine_2d/src/parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/invocation/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/invocation/src/ast_node.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/invocation/src/runtime.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/knowledge_base/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/knowledge_base/src/ast_node.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/knowledge_base/src/parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/logging/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/logging/src/ast_node.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/logging/src/parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/logging/src/runtime.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/loops/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/loops/src/ast_node.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/query/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/query/src/query_validators.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/state_management/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/terminal_engine/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/terminal_engine/src/ast_nodes.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/terminal_engine/src/parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/testing_engine/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/testing_engine/src/ast_nodes.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/testing_engine/src/parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/theming/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/theming/src/ast_node.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/theming/src/presets.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/ui_engine/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/websocket/src/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/websocket/src/ast_node.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/guards.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/html_compat.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parser_registry.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/ai/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/ai/agent_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/ai/knowledge_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/ai/llm_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/ai/team_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/base.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/composition/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/composition/import_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/composition/slot_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/control_flow/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/control_flow/if_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/control_flow/loop_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/data/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/data/data_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/data/invoke_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/data/query_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/data/transaction_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/events/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/events/dispatch_event_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/forms/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/forms/action_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/forms/flash_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/forms/redirect_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/functions/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/functions/function_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/functions/param_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/functions/return_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/html/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/html/component_call_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/html/html_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/jobs/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/jobs/job_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/jobs/schedule_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/jobs/thread_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/messaging/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/messaging/message_ack_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/messaging/message_nack_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/messaging/message_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/messaging/queue_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/messaging/websocket_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/routing/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/routing/route_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/scripting/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/scripting/pyclass_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/scripting/pydecorator_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/scripting/pyimport_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/scripting/python_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/services/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/services/dump_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/services/file_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/services/log_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/parsers/services/mail_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/packages/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/packages/manager.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/packages/manifest.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/packages/registry.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/packages/resolver.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/plugins/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/plugins/hooks.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/plugins/loader.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/plugins/manifest.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/plugins/registry.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/adapters/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/adapters/memory_adapter.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/adapters/rabbitmq_adapter.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/adapters/redis_adapter.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/adapters/sqlite_adapter.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/agent_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/ast_cache.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/auth_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/component.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/component_composer.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/component_resolver.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/conditions.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/database_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/email_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/error_handler.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/execution_context.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executor_registry.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/ai/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/ai/agent_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/ai/knowledge_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/ai/llm_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/ai/team_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/base.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/control_flow/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/control_flow/if_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/control_flow/loop_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/control_flow/redirect_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/control_flow/set_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/data/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/data/data_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/data/invoke_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/data/query_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/data/transaction_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/jobs/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/jobs/job_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/jobs/schedule_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/jobs/thread_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/messaging/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/messaging/message_ack_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/messaging/message_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/messaging/queue_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/messaging/websocket_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/scripting/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/scripting/pyclass_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/scripting/pyimport_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/scripting/python_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/services/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/services/dump_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/services/file_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/services/log_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/executors/services/mail_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/expression_cache.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/file_upload_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/function_registry.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/game_builder.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/game_code_generator.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/game_templates.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/godot_code_generator.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/godot_templates.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/job_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/knowledge_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/llm_cache.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/llm_providers.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/llm_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/logging_setup.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/message_broker.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/message_queue_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/param_validation.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/pypy_compat.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/python_bridge.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/query_validators.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/renderer.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/service_container.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/terminal_builder.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/terminal_code_generator.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/terminal_templates.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/testing_builder.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/testing_code_generator.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/testing_templates.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/ui_mobile_adapter.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/ui_mobile_templates.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/ui_textual_adapter.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/ui_textual_templates.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/ui_tokens.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/ui_validator.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/validators.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/websocket_adapter.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/websocket_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/websocket_transport.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/runtime/wsgi.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/services.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/utils/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/assets/quantum-admin-connectors.js +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/assets/quantum-admin.css +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/assets/quantum-source-highlight.js +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/audit_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/auth_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/component_discovery.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/config_generator.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/connector_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/crud.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/database.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/db_setup_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/deploy_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/docker_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/environment_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/git_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/health_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/job_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/log_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/main.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/models.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/pipeline_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/resource_manager.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/schemas.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/secret_manager.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/settings_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/template_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/test_execution_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/test_generator.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/webhook_service.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/backend/websocket_manager.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/_layout/AdminShell.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/agents.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/app/[name].q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/applications.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/component/[...path].q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/components.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/connectors.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/dashboard.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/database.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/features.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/index.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/jobs.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/login.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/logout.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/settings.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/source.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/components/admin/tests.q +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/run.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/services/__init__.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/services/_base.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/services/_component_test_generator.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/services/_yaml_editor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/services/apps.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/services/auth.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/services/components.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/services/connectors.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/services/projects.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/services/repository.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/services/settings.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_admin/services/yaml_import.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_framework.egg-info/dependency_links.txt +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_framework.egg-info/entry_points.txt +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum_framework.egg-info/top_level.txt +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/setup.cfg +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_agent.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_animations.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_ast_cache.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_component_library.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_expression_cache.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_form_validation.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_game_codegen.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_game_e2e.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_game_engine.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_game_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_godot_codegen.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_job_executor.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_llm_providers.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_message_broker.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_message_queue.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_mobile_target.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_multi_agent.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_packages.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_plugins.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_pypy_compat.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_python_scripting.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_terminal_codegen.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_terminal_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_testing_codegen.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_testing_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_theming.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_ui_parity.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_ui_parser.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_ui_textual_adapter.py +0 -0
- {quantum_framework-0.15.0 → quantum_framework-0.16.0}/tests/test_websocket.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quantum-framework
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.0
|
|
4
4
|
Summary: Full-stack declarative framework for building web, desktop, and mobile applications
|
|
5
5
|
Author-email: Daniel Gregorio <danielgregorio2611@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -42,6 +42,8 @@ Provides-Extra: admin
|
|
|
42
42
|
Requires-Dist: sqlalchemy>=2.0; extra == "admin"
|
|
43
43
|
Requires-Dist: PyJWT>=2.8; extra == "admin"
|
|
44
44
|
Requires-Dist: cryptography>=42.0; extra == "admin"
|
|
45
|
+
Provides-Extra: desktop
|
|
46
|
+
Requires-Dist: pywebview>=5.0; extra == "desktop"
|
|
45
47
|
Provides-Extra: websocket
|
|
46
48
|
Requires-Dist: websockets>=12.0; extra == "websocket"
|
|
47
49
|
Dynamic: license-file
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "quantum-framework"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.16.0"
|
|
8
8
|
description = "Full-stack declarative framework for building web, desktop, and mobile applications"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -58,6 +58,10 @@ admin = [
|
|
|
58
58
|
"PyJWT>=2.8",
|
|
59
59
|
"cryptography>=42.0",
|
|
60
60
|
]
|
|
61
|
+
desktop = [
|
|
62
|
+
# `quantum desktop`: the native window around the application's server.
|
|
63
|
+
"pywebview>=5.0",
|
|
64
|
+
]
|
|
61
65
|
websocket = [
|
|
62
66
|
# The transport behind q:websocket. Without it the tag registers a
|
|
63
67
|
# connection and opens nothing — and says so, rather than pretending.
|
|
@@ -16,12 +16,12 @@ from quantum.cli.utils import get_console, find_project_root, find_q_files
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
# Available build targets
|
|
19
|
-
TARGETS = ['html', '
|
|
19
|
+
TARGETS = ['html', 'mobile', 'textual', 'all']
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
@click.command('build')
|
|
23
23
|
@click.option('--target', '-t', type=click.Choice(TARGETS), default='html',
|
|
24
|
-
help='Build target (html,
|
|
24
|
+
help='Build target (html, mobile, textual, all)')
|
|
25
25
|
@click.option('--output', '-o', type=click.Path(), default='./dist',
|
|
26
26
|
help='Output directory')
|
|
27
27
|
@click.option('--minify', is_flag=True, default=True, help='Minify output')
|
|
@@ -53,8 +53,6 @@ def build(
|
|
|
53
53
|
|
|
54
54
|
quantum build
|
|
55
55
|
|
|
56
|
-
quantum build --target desktop
|
|
57
|
-
|
|
58
56
|
quantum build --target all --output ./build
|
|
59
57
|
|
|
60
58
|
quantum build --target mobile --no-minify
|
|
@@ -98,7 +96,7 @@ def build(
|
|
|
98
96
|
|
|
99
97
|
# Determine targets to build
|
|
100
98
|
if target == 'all':
|
|
101
|
-
targets_to_build = ['html', '
|
|
99
|
+
targets_to_build = ['html', 'mobile', 'textual']
|
|
102
100
|
else:
|
|
103
101
|
targets_to_build = [target]
|
|
104
102
|
|
|
@@ -247,12 +245,11 @@ def _build_application(
|
|
|
247
245
|
from quantum.runtime.testing_builder import TestingBuilder
|
|
248
246
|
builder = TestingBuilder()
|
|
249
247
|
ext = '.py'
|
|
250
|
-
elif app_type == 'ui' or target in ('html', '
|
|
248
|
+
elif app_type == 'ui' or target in ('html', 'mobile', 'textual'):
|
|
251
249
|
builder = UIBuilder()
|
|
252
250
|
# Map target to extension
|
|
253
251
|
ext_map = {
|
|
254
252
|
'html': '.html',
|
|
255
|
-
'desktop': '.py',
|
|
256
253
|
'mobile': '.js',
|
|
257
254
|
'textual': '.py',
|
|
258
255
|
}
|
|
@@ -286,6 +286,7 @@ Examples:
|
|
|
286
286
|
quantum run hello.q # Execute component
|
|
287
287
|
quantum admin # Start the Quantum Admin
|
|
288
288
|
quantum console # The application's pages in the terminal
|
|
289
|
+
quantum desktop # The application's pages in a desktop window
|
|
289
290
|
quantum run game.q --engine godot # Build Godot 4 project
|
|
290
291
|
quantum run backup-job.q # Execute job
|
|
291
292
|
quantum deploy ./my-app # Deploy application
|
|
@@ -341,6 +342,13 @@ Examples:
|
|
|
341
342
|
console_parser.add_argument('path', nargs='?', default='/', help='Page to open (default: /)')
|
|
342
343
|
console_parser.add_argument('--config', default='quantum.config.yaml', help='Config file')
|
|
343
344
|
|
|
345
|
+
# Desktop: the application's pages in a native window (UI-4)
|
|
346
|
+
desktop_parser = subparsers.add_parser('desktop', help="Open the application's pages in a desktop window")
|
|
347
|
+
desktop_parser.add_argument('path', nargs='?', default='/', help='Page to open (default: /)')
|
|
348
|
+
desktop_parser.add_argument('--config', default='quantum.config.yaml', help='Config file')
|
|
349
|
+
desktop_parser.add_argument('--width', type=int, default=1024, help='Window width (default: 1024)')
|
|
350
|
+
desktop_parser.add_argument('--height', type=int, default=720, help='Window height (default: 720)')
|
|
351
|
+
|
|
344
352
|
# Admin command (the screens need the [admin] extra; checked when run)
|
|
345
353
|
from quantum.cli.admin import create_admin_parser
|
|
346
354
|
create_admin_parser(subparsers)
|
|
@@ -411,6 +419,10 @@ Examples:
|
|
|
411
419
|
from quantum.runtime.ui_console import run_console
|
|
412
420
|
sys.exit(run_console(args.config, args.path))
|
|
413
421
|
|
|
422
|
+
elif args.command == 'desktop':
|
|
423
|
+
from quantum.runtime.ui_desktop import run_desktop
|
|
424
|
+
sys.exit(run_desktop(args.config, args.path, width=args.width, height=args.height))
|
|
425
|
+
|
|
414
426
|
elif args.command == 'admin':
|
|
415
427
|
from quantum.cli.admin import handle_admin
|
|
416
428
|
sys.exit(handle_admin(args))
|
|
@@ -676,7 +676,7 @@ class OnEventNode(QuantumNode):
|
|
|
676
676
|
|
|
677
677
|
# MIGRATED: SetNode and PersistNode moved to feature-based structure
|
|
678
678
|
# Import from new location (Option C migration)
|
|
679
|
-
from .features.state_management.src.ast_node import SetNode
|
|
679
|
+
from .features.state_management.src.ast_node import SetNode
|
|
680
680
|
|
|
681
681
|
|
|
682
682
|
class QueryNode(QuantumNode):
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Documentation pages that error messages point to (one place, one spelling)."""
|
|
2
|
+
|
|
3
|
+
DOCS = 'https://danielgregorio.github.io/quantum'
|
|
4
|
+
|
|
5
|
+
# EXEC-*: the order in which a page's parts run. The traps — a statement in
|
|
6
|
+
# the markup, a variable the action cannot see, a guard reading the page —
|
|
7
|
+
# all come from that order, so their messages send the reader here.
|
|
8
|
+
HOW_A_PAGE_RUNS = f'{DOCS}/guide/how-a-page-runs'
|
|
@@ -3,11 +3,6 @@ AST Node for State Management (q:set)
|
|
|
3
3
|
|
|
4
4
|
This module contains the SetNode class, which represents the <q:set> tag
|
|
5
5
|
for state management in Quantum Language.
|
|
6
|
-
|
|
7
|
-
State Persistence Support:
|
|
8
|
-
- persist="local" - localStorage (browser) or file (desktop)
|
|
9
|
-
- persist="session" - sessionStorage (browser) or memory (desktop)
|
|
10
|
-
- persist="sync" - synchronized across tabs/windows (browser) or network (desktop)
|
|
11
6
|
"""
|
|
12
7
|
|
|
13
8
|
from typing import Dict, Any, List, Optional
|
|
@@ -54,12 +49,6 @@ class SetNode(QuantumNode):
|
|
|
54
49
|
self.key = None
|
|
55
50
|
self.source = None
|
|
56
51
|
|
|
57
|
-
# State Persistence
|
|
58
|
-
self.persist: Optional[str] = None # None, "local", "session", "sync"
|
|
59
|
-
self.persist_key: Optional[str] = None # Custom storage key (defaults to name)
|
|
60
|
-
self.persist_encrypt: bool = False # Encrypt persisted data
|
|
61
|
-
self.persist_ttl: Optional[int] = None # TTL in seconds for cached persistence
|
|
62
|
-
|
|
63
52
|
def to_dict(self) -> Dict[str, Any]:
|
|
64
53
|
result = {
|
|
65
54
|
"type": "set",
|
|
@@ -84,14 +73,6 @@ class SetNode(QuantumNode):
|
|
|
84
73
|
"maxlength": self.maxlength
|
|
85
74
|
}
|
|
86
75
|
}
|
|
87
|
-
# Add persistence info if enabled
|
|
88
|
-
if self.persist:
|
|
89
|
-
result["persistence"] = {
|
|
90
|
-
"scope": self.persist,
|
|
91
|
-
"key": self.persist_key or self.name,
|
|
92
|
-
"encrypt": self.persist_encrypt,
|
|
93
|
-
"ttl": self.persist_ttl
|
|
94
|
-
}
|
|
95
76
|
return result
|
|
96
77
|
|
|
97
78
|
def validate(self) -> List[str]:
|
|
@@ -136,93 +117,5 @@ class SetNode(QuantumNode):
|
|
|
136
117
|
if self.maxlength and len(str(self.value)) > int(self.maxlength):
|
|
137
118
|
errors.append(f"Value length {len(str(self.value))} exceeds maxlength {self.maxlength}")
|
|
138
119
|
|
|
139
|
-
# Validar persist scope
|
|
140
|
-
if self.persist:
|
|
141
|
-
valid_persist_scopes = ['local', 'session', 'sync']
|
|
142
|
-
if self.persist not in valid_persist_scopes:
|
|
143
|
-
errors.append(f"Invalid persist scope: {self.persist}. Must be one of {valid_persist_scopes}")
|
|
144
|
-
|
|
145
|
-
return errors
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
class PersistNode(QuantumNode):
|
|
149
|
-
"""
|
|
150
|
-
Represents a <q:persist> - Explicit persistence configuration.
|
|
151
|
-
|
|
152
|
-
Allows fine-grained control over state persistence beyond the persist attribute on q:set.
|
|
153
|
-
|
|
154
|
-
Examples:
|
|
155
|
-
<q:persist scope="local" prefix="myapp_">
|
|
156
|
-
<q:var name="theme" />
|
|
157
|
-
<q:var name="locale" />
|
|
158
|
-
</q:persist>
|
|
159
|
-
|
|
160
|
-
<q:persist scope="sync" key="user_preferences" encrypt="true">
|
|
161
|
-
<q:var name="darkMode" />
|
|
162
|
-
<q:var name="fontSize" />
|
|
163
|
-
</q:persist>
|
|
164
|
-
|
|
165
|
-
Attributes:
|
|
166
|
-
scope: "local" (localStorage), "session" (sessionStorage), "sync" (cross-tab/network)
|
|
167
|
-
prefix: Optional prefix for all storage keys
|
|
168
|
-
key: If set, all vars are stored under this single key as an object
|
|
169
|
-
encrypt: Whether to encrypt persisted data
|
|
170
|
-
ttl: Time-to-live in seconds (for cache invalidation)
|
|
171
|
-
storage: Override storage backend ("localStorage", "indexedDB", "file", "db")
|
|
172
|
-
"""
|
|
173
|
-
|
|
174
|
-
def __init__(
|
|
175
|
-
self,
|
|
176
|
-
scope: str = "local",
|
|
177
|
-
prefix: Optional[str] = None,
|
|
178
|
-
key: Optional[str] = None,
|
|
179
|
-
encrypt: bool = False,
|
|
180
|
-
ttl: Optional[int] = None,
|
|
181
|
-
storage: Optional[str] = None
|
|
182
|
-
):
|
|
183
|
-
self.scope = scope
|
|
184
|
-
self.prefix = prefix
|
|
185
|
-
self.key = key
|
|
186
|
-
self.encrypt = encrypt
|
|
187
|
-
self.ttl = ttl
|
|
188
|
-
self.storage = storage
|
|
189
|
-
self.variables: List[str] = [] # List of variable names to persist
|
|
190
|
-
|
|
191
|
-
def add_variable(self, name: str):
|
|
192
|
-
"""Add a variable name to persist."""
|
|
193
|
-
self.variables.append(name)
|
|
194
|
-
|
|
195
|
-
def to_dict(self) -> Dict[str, Any]:
|
|
196
|
-
return {
|
|
197
|
-
"type": "persist",
|
|
198
|
-
"scope": self.scope,
|
|
199
|
-
"prefix": self.prefix,
|
|
200
|
-
"key": self.key,
|
|
201
|
-
"encrypt": self.encrypt,
|
|
202
|
-
"ttl": self.ttl,
|
|
203
|
-
"storage": self.storage,
|
|
204
|
-
"variables": self.variables
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
def validate(self) -> List[str]:
|
|
208
|
-
errors = []
|
|
209
|
-
|
|
210
|
-
# Validate scope
|
|
211
|
-
valid_scopes = ['local', 'session', 'sync']
|
|
212
|
-
if self.scope not in valid_scopes:
|
|
213
|
-
errors.append(f"Invalid persist scope: {self.scope}. Must be one of {valid_scopes}")
|
|
214
|
-
|
|
215
|
-
# Validate storage backend if specified
|
|
216
|
-
if self.storage:
|
|
217
|
-
valid_storage = ['localStorage', 'sessionStorage', 'indexedDB', 'file', 'db']
|
|
218
|
-
if self.storage not in valid_storage:
|
|
219
|
-
errors.append(f"Invalid storage backend: {self.storage}. Must be one of {valid_storage}")
|
|
220
|
-
|
|
221
|
-
# Validate variables
|
|
222
|
-
if not self.variables:
|
|
223
|
-
errors.append("q:persist must contain at least one q:var element")
|
|
224
|
-
|
|
225
120
|
return errors
|
|
226
121
|
|
|
227
|
-
def __repr__(self):
|
|
228
|
-
return f'<PersistNode scope={self.scope} vars={len(self.variables)}>'
|
|
@@ -374,7 +374,7 @@ class UIValidatorNode(QuantumNode):
|
|
|
374
374
|
Can be defined at form level (reusable) or inline in an input.
|
|
375
375
|
|
|
376
376
|
Examples:
|
|
377
|
-
<ui:validator name="phone" pattern="
|
|
377
|
+
<ui:validator name="phone" pattern="^\\d{10,11}$" message="Invalid phone number" />
|
|
378
378
|
<ui:validator name="passwordMatch" field="password" match="confirm_password"
|
|
379
379
|
message="Passwords must match" />
|
|
380
380
|
<ui:validator name="customEmail" type="email" message="Please enter a valid email" />
|
|
@@ -549,6 +549,7 @@ class UIInputNode(QuantumNode, UILayoutMixin):
|
|
|
549
549
|
|
|
550
550
|
def __init__(self):
|
|
551
551
|
self.bind: Optional[str] = None
|
|
552
|
+
self.value: Optional[str] = None # initial value (UI-6)
|
|
552
553
|
self.placeholder: Optional[str] = None
|
|
553
554
|
self.input_type: str = "text" # text, password, email, number
|
|
554
555
|
self.on_change: Optional[str] = None
|
|
@@ -592,6 +593,7 @@ class UICheckboxNode(QuantumNode, UILayoutMixin):
|
|
|
592
593
|
|
|
593
594
|
def __init__(self):
|
|
594
595
|
self.bind: Optional[str] = None
|
|
596
|
+
self.checked: Optional[str] = None # "true"/"false" or {expr} (UI-6)
|
|
595
597
|
self.label: Optional[str] = None
|
|
596
598
|
self._init_layout_attrs()
|
|
597
599
|
|
|
@@ -609,6 +611,7 @@ class UIRadioNode(QuantumNode, UILayoutMixin):
|
|
|
609
611
|
|
|
610
612
|
def __init__(self):
|
|
611
613
|
self.bind: Optional[str] = None
|
|
614
|
+
self.value: Optional[str] = None # selected option (UI-6)
|
|
612
615
|
self.options: Optional[str] = None # comma-separated or source ref
|
|
613
616
|
self._init_layout_attrs()
|
|
614
617
|
|
|
@@ -626,6 +629,7 @@ class UISwitchNode(QuantumNode, UILayoutMixin):
|
|
|
626
629
|
|
|
627
630
|
def __init__(self):
|
|
628
631
|
self.bind: Optional[str] = None
|
|
632
|
+
self.checked: Optional[str] = None # "true"/"false" or {expr} (UI-6)
|
|
629
633
|
self.label: Optional[str] = None
|
|
630
634
|
self._init_layout_attrs()
|
|
631
635
|
|
|
@@ -643,6 +647,7 @@ class UISelectNode(QuantumNode, UILayoutMixin):
|
|
|
643
647
|
|
|
644
648
|
def __init__(self):
|
|
645
649
|
self.bind: Optional[str] = None
|
|
650
|
+
self.value: Optional[str] = None # selected option (UI-6)
|
|
646
651
|
self.options: Optional[str] = None
|
|
647
652
|
self.source: Optional[str] = None
|
|
648
653
|
self.children: List[QuantumNode] = [] # UIOptionNode children
|
|
@@ -667,6 +672,7 @@ class UITableNode(QuantumNode, UILayoutMixin):
|
|
|
667
672
|
|
|
668
673
|
def __init__(self):
|
|
669
674
|
self.source: Optional[str] = None
|
|
675
|
+
self.as_var: Optional[str] = None # row variable for column content (UI-5)
|
|
670
676
|
self.children: List[QuantumNode] = [] # UIColumnNode children
|
|
671
677
|
self._init_layout_attrs()
|
|
672
678
|
|
|
@@ -691,6 +697,11 @@ class UIColumnNode(QuantumNode):
|
|
|
691
697
|
self.label: Optional[str] = None
|
|
692
698
|
self.column_width: Optional[str] = None
|
|
693
699
|
self.align: Optional[str] = None # left, center, right
|
|
700
|
+
# UI-5: a column with content draws it once per row (buttons, links).
|
|
701
|
+
self.children: List[QuantumNode] = []
|
|
702
|
+
|
|
703
|
+
def add_child(self, child: QuantumNode):
|
|
704
|
+
self.children.append(child)
|
|
694
705
|
|
|
695
706
|
def to_dict(self) -> Dict[str, Any]:
|
|
696
707
|
return {"type": "ui_column", "key": self.key,
|
|
@@ -1862,3 +1873,15 @@ class UIDatePickerNode(QuantumNode, UILayoutMixin):
|
|
|
1862
1873
|
def is_ui_node(node) -> bool:
|
|
1863
1874
|
"""A ui:* element (UI-1): markup, drawn by a renderer, never executed."""
|
|
1864
1875
|
return type(node).__module__ == __name__
|
|
1876
|
+
|
|
1877
|
+
|
|
1878
|
+
# UI-7: the elements every renderer draws — browser, console and desktop — with
|
|
1879
|
+
# the same meaning, checked by tests/apps/test_ui_paridade.py. The other ui:*
|
|
1880
|
+
# tags work in the browser only; the console says it cannot draw them.
|
|
1881
|
+
CORE_TAGS = frozenset({
|
|
1882
|
+
'window', 'hbox', 'vbox', 'grid', 'panel', 'section', 'scrollbox', 'spacer', 'rule',
|
|
1883
|
+
'header', 'footer', 'card', 'card-header', 'card-body', 'card-footer', 'tabpanel', 'tab',
|
|
1884
|
+
'text', 'badge', 'alert', 'link', 'image', 'progress',
|
|
1885
|
+
'table', 'column', 'list', 'item',
|
|
1886
|
+
'form', 'formitem', 'input', 'checkbox', 'switch', 'radio', 'select', 'option', 'button',
|
|
1887
|
+
})
|
{quantum_framework-0.15.0 → quantum_framework-0.16.0}/quantum/core/features/ui_engine/src/parser.py
RENAMED
|
@@ -31,6 +31,7 @@ from .ast_nodes import (
|
|
|
31
31
|
UICalendarNode, UIDatePickerNode,
|
|
32
32
|
)
|
|
33
33
|
from quantum.core.features.theming.src import UIThemeNode, UIColorNode
|
|
34
|
+
from quantum.core.ast_nodes import TextNode
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
class UIParseError(Exception):
|
|
@@ -252,11 +253,20 @@ class UIParser:
|
|
|
252
253
|
return None
|
|
253
254
|
|
|
254
255
|
def _parse_children(self, element: ET.Element, node):
|
|
255
|
-
"""Parse all children of an element, adding them to node.
|
|
256
|
+
"""Parse all children of an element, adding them to node.
|
|
257
|
+
|
|
258
|
+
UI-1: inside a page, a container's own text is content too
|
|
259
|
+
(`<ui:card-header>Resumo</ui:card-header>`); it used to vanish. Nodes
|
|
260
|
+
that keep their text in `content` read it themselves."""
|
|
261
|
+
texto_e_conteudo = self.page_mode and not hasattr(node, 'content')
|
|
262
|
+
if texto_e_conteudo and (element.text or '').strip():
|
|
263
|
+
node.add_child(TextNode(element.text.strip()))
|
|
256
264
|
for child in element:
|
|
257
265
|
parsed = self._parse_child(child)
|
|
258
266
|
if parsed:
|
|
259
267
|
node.add_child(parsed)
|
|
268
|
+
if texto_e_conteudo and (child.tail or '').strip():
|
|
269
|
+
node.add_child(TextNode(child.tail.strip()))
|
|
260
270
|
|
|
261
271
|
# ------------------------------------------------------------------
|
|
262
272
|
# Containers
|
|
@@ -404,6 +414,7 @@ class UIParser:
|
|
|
404
414
|
def _parse_ui_input(self, element: ET.Element) -> UIInputNode:
|
|
405
415
|
node = UIInputNode()
|
|
406
416
|
node.bind = element.get('bind')
|
|
417
|
+
node.value = element.get('value')
|
|
407
418
|
node.placeholder = element.get('placeholder')
|
|
408
419
|
node.input_type = element.get('type', 'text')
|
|
409
420
|
node.on_change = element.get('on-change')
|
|
@@ -436,6 +447,7 @@ class UIParser:
|
|
|
436
447
|
def _parse_ui_checkbox(self, element: ET.Element) -> UICheckboxNode:
|
|
437
448
|
node = UICheckboxNode()
|
|
438
449
|
node.bind = element.get('bind')
|
|
450
|
+
node.checked = element.get('checked')
|
|
439
451
|
node.label = element.get('label')
|
|
440
452
|
self._apply_layout_attrs(node, element)
|
|
441
453
|
return node
|
|
@@ -443,6 +455,7 @@ class UIParser:
|
|
|
443
455
|
def _parse_ui_radio(self, element: ET.Element) -> UIRadioNode:
|
|
444
456
|
node = UIRadioNode()
|
|
445
457
|
node.bind = element.get('bind')
|
|
458
|
+
node.value = element.get('value')
|
|
446
459
|
node.options = element.get('options')
|
|
447
460
|
self._apply_layout_attrs(node, element)
|
|
448
461
|
return node
|
|
@@ -450,6 +463,7 @@ class UIParser:
|
|
|
450
463
|
def _parse_ui_switch(self, element: ET.Element) -> UISwitchNode:
|
|
451
464
|
node = UISwitchNode()
|
|
452
465
|
node.bind = element.get('bind')
|
|
466
|
+
node.checked = element.get('checked')
|
|
453
467
|
node.label = element.get('label')
|
|
454
468
|
self._apply_layout_attrs(node, element)
|
|
455
469
|
return node
|
|
@@ -457,6 +471,7 @@ class UIParser:
|
|
|
457
471
|
def _parse_ui_select(self, element: ET.Element) -> UISelectNode:
|
|
458
472
|
node = UISelectNode()
|
|
459
473
|
node.bind = element.get('bind')
|
|
474
|
+
node.value = element.get('value')
|
|
460
475
|
node.options = element.get('options')
|
|
461
476
|
node.source = element.get('source')
|
|
462
477
|
self._apply_layout_attrs(node, element)
|
|
@@ -467,6 +482,7 @@ class UIParser:
|
|
|
467
482
|
def _parse_ui_table(self, element: ET.Element) -> UITableNode:
|
|
468
483
|
node = UITableNode()
|
|
469
484
|
node.source = element.get('source')
|
|
485
|
+
node.as_var = element.get('as')
|
|
470
486
|
self._apply_layout_attrs(node, element)
|
|
471
487
|
# Parse child <ui:column> elements
|
|
472
488
|
self._parse_children(element, node)
|
|
@@ -478,6 +494,7 @@ class UIParser:
|
|
|
478
494
|
node.label = element.get('label')
|
|
479
495
|
node.column_width = element.get('width')
|
|
480
496
|
node.align = element.get('align')
|
|
497
|
+
self._parse_children(element, node)
|
|
481
498
|
return node
|
|
482
499
|
|
|
483
500
|
def _parse_ui_list(self, element: ET.Element) -> UIListNode:
|
|
@@ -586,7 +603,7 @@ class UIParser:
|
|
|
586
603
|
Parse <ui:validator> custom validation rule.
|
|
587
604
|
|
|
588
605
|
Examples:
|
|
589
|
-
<ui:validator name="phone" pattern="
|
|
606
|
+
<ui:validator name="phone" pattern="^\\d{10}$" message="Invalid phone" />
|
|
590
607
|
<ui:validator name="confirmPassword" match="password"
|
|
591
608
|
message="Passwords must match" />
|
|
592
609
|
<ui:validator name="custom" expression="value.length > 5"
|
|
@@ -31,7 +31,8 @@ from quantum.core.ast_nodes import (
|
|
|
31
31
|
# Import feature AST nodes from their respective modules
|
|
32
32
|
from quantum.core.features.conditionals.src.ast_node import IfNode
|
|
33
33
|
from quantum.core.features.loops.src.ast_node import LoopNode
|
|
34
|
-
from quantum.core.features.state_management.src.ast_node import SetNode
|
|
34
|
+
from quantum.core.features.state_management.src.ast_node import SetNode
|
|
35
|
+
from quantum.core.docs_links import HOW_A_PAGE_RUNS
|
|
35
36
|
from quantum.core.features.functions.src.ast_node import FunctionNode, RestConfig
|
|
36
37
|
from quantum.core.features.invocation.src.ast_node import InvokeNode
|
|
37
38
|
from quantum.core.features.logging.src import LogNode, parse_log
|
|
@@ -109,7 +110,6 @@ def _create_parser_registry(parser: 'QuantumParser') -> ParserRegistry:
|
|
|
109
110
|
from quantum.core.parsers.composition import ImportParser, SlotParser
|
|
110
111
|
from quantum.core.parsers.functions import FunctionParser, ReturnParser, ParamParser
|
|
111
112
|
from quantum.core.parsers.events import DispatchEventParser
|
|
112
|
-
from quantum.core.parsers.persistence import PersistParser
|
|
113
113
|
from quantum.core.parsers.routing import RouteParser
|
|
114
114
|
from quantum.core.parsers.messaging import MessageAckParser, MessageNackParser
|
|
115
115
|
from quantum.core.parsers.scripting import PyDecoratorParser
|
|
@@ -170,8 +170,6 @@ def _create_parser_registry(parser: 'QuantumParser') -> ParserRegistry:
|
|
|
170
170
|
# They are internal parsers used by FunctionParser and other parsers
|
|
171
171
|
# Events
|
|
172
172
|
DispatchEventParser(parser),
|
|
173
|
-
# Persistence
|
|
174
|
-
PersistParser(parser),
|
|
175
173
|
]
|
|
176
174
|
|
|
177
175
|
registry.register_all(parsers)
|
|
@@ -482,7 +480,16 @@ class QuantumParser:
|
|
|
482
480
|
continue
|
|
483
481
|
anterior = child if nome == 'if' and self._is_quantum_tag(child) else None
|
|
484
482
|
|
|
483
|
+
# Tags that existed and were removed, with what to use instead.
|
|
484
|
+
REMOVED_TAGS = {
|
|
485
|
+
'persist': ('was removed in Quantum 0.16 (SET-2): it kept variables in the browser, '
|
|
486
|
+
'and a page\'s variables live on the server, for one request. Keep what must '
|
|
487
|
+
'last in session.x (per user) or in the database.'),
|
|
488
|
+
}
|
|
489
|
+
|
|
485
490
|
def _unknown_tag_message(self, name: str) -> str:
|
|
491
|
+
if name in self.REMOVED_TAGS:
|
|
492
|
+
return f"<q:{name}> {self.REMOVED_TAGS[name]}"
|
|
486
493
|
import difflib
|
|
487
494
|
# Only Quantum tags: the registry also holds the HTML tag names, which
|
|
488
495
|
# made <q:try> suggest <q:tr>.
|
|
@@ -681,7 +688,7 @@ class QuantumParser:
|
|
|
681
688
|
f'redirects, so it also runs before the page\'s q:action — where the page '
|
|
682
689
|
f'has not run and {{{nome}}} does not exist, and the guard would let the '
|
|
683
690
|
f'action through. Read the scope directly (e.g. session.x), or protect the '
|
|
684
|
-
f'page with require_auth / require_role.')
|
|
691
|
+
f'page with require_auth / require_role. See {HOW_A_PAGE_RUNS}')
|
|
685
692
|
|
|
686
693
|
# Nodes the HTML renderer draws. Anything else inside markup is a statement,
|
|
687
694
|
# and statements run in the execution pass, before the render pass sees
|
|
@@ -758,7 +765,8 @@ class QuantumParser:
|
|
|
758
765
|
raise QuantumParseError(
|
|
759
766
|
f'{tag(node)} inside {onde[1]} in <q:component name="{component.name}"> '
|
|
760
767
|
f'never runs: statements run before the page is rendered, and markup '
|
|
761
|
-
f'is only rendered. Move it above the markup (or into a q:action).'
|
|
768
|
+
f'is only rendered. Move it above the markup (or into a q:action). '
|
|
769
|
+
f'See {HOW_A_PAGE_RUNS}')
|
|
762
770
|
nome = getattr(node, 'name', None)
|
|
763
771
|
# A running total read AFTER the loop is fine; a value the
|
|
764
772
|
# loop's own rows read is not.
|
|
@@ -767,7 +775,8 @@ class QuantumParser:
|
|
|
767
775
|
f'{tag(node)} inside a q:loop whose rows use {{{nome}}} in '
|
|
768
776
|
f'<q:component name="{component.name}">: the loop runs for every item '
|
|
769
777
|
f'before any row is rendered, so every row would show the last value. '
|
|
770
|
-
f'Compute it in the expression instead, e.g. {{item.price * item.qty}}.'
|
|
778
|
+
f'Compute it in the expression instead, e.g. {{item.price * item.qty}}. '
|
|
779
|
+
f'See {HOW_A_PAGE_RUNS}')
|
|
771
780
|
continue
|
|
772
781
|
if isinstance(node, HTMLNode):
|
|
773
782
|
andar(filhos(node), onde if onde and onde[0] == 'markup' else ('markup', f'<{node.tag}>'))
|
|
@@ -79,16 +79,15 @@ class SetParser(BaseTagParser):
|
|
|
79
79
|
set_node.key = self.get_attr(element, 'key')
|
|
80
80
|
set_node.source = self.get_attr(element, 'source')
|
|
81
81
|
|
|
82
|
-
#
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
set_node.
|
|
91
|
-
|
|
92
|
-
pass
|
|
82
|
+
# SET-2: browser persistence never ran in a page.
|
|
83
|
+
persist = [a for a in ('persist', 'persistKey', 'persistTtl', 'persistEncrypt')
|
|
84
|
+
if element.get(a) is not None]
|
|
85
|
+
if persist:
|
|
86
|
+
from quantum.core.parser import QuantumParseError
|
|
87
|
+
raise QuantumParseError(
|
|
88
|
+
f'<q:set name="{set_node.name}"> {persist[0]}= was removed in Quantum 0.16: it '
|
|
89
|
+
f'kept the variable in the browser, and a page\'s variables live on the server, '
|
|
90
|
+
f'for one request. Keep what must last in session.{set_node.name} (per user) '
|
|
91
|
+
f'or in the database.')
|
|
93
92
|
|
|
94
93
|
return set_node
|
|
@@ -31,7 +31,7 @@ EXPERIMENTAL = frozenset({
|
|
|
31
31
|
"job", "schedule", "thread",
|
|
32
32
|
"message", "queue", "subscribe", "messageAck", "messageNack",
|
|
33
33
|
"websocket", "websocket-send", "websocket-close",
|
|
34
|
-
"mail", "file", "log", "dump",
|
|
34
|
+
"mail", "file", "log", "dump",
|
|
35
35
|
"python", "pyclass", "pyimport", "class", "decorator", "pydecorator",
|
|
36
36
|
"dispatchEvent", "transaction",
|
|
37
37
|
})
|
|
@@ -140,6 +140,25 @@ def warn_app_type(app_type: str) -> None:
|
|
|
140
140
|
)
|
|
141
141
|
|
|
142
142
|
|
|
143
|
+
# UI-8: React Native translates the logic to JavaScript on its own — the
|
|
144
|
+
# opposite of "one runtime, many renderers" — and phones are out of 1.0. It
|
|
145
|
+
# stays to press on the language, like the games.
|
|
146
|
+
LAB_UI_TARGETS = frozenset({"mobile", "react-native"})
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def warn_ui_target(target: str) -> None:
|
|
150
|
+
"""One-time warning when a LABORATÓRIO UI target is built."""
|
|
151
|
+
key = f"ui-target:{target}"
|
|
152
|
+
if target not in LAB_UI_TARGETS or key in _warned:
|
|
153
|
+
return
|
|
154
|
+
_warned.add(key)
|
|
155
|
+
logger.warning(
|
|
156
|
+
"quantum run --target %s is LABORATÓRIO — it translates q:set and "
|
|
157
|
+
"q:function to JavaScript with no stability promise (SUPPORT_TIERS.md). "
|
|
158
|
+
"It may change or break without notice.", target
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
|
|
143
162
|
def reset_warnings() -> None:
|
|
144
163
|
"""For tests, and for a reloading server."""
|
|
145
164
|
_warned.clear()
|
|
@@ -143,8 +143,9 @@ class ActionHandler:
|
|
|
143
143
|
# page's statements, so a variable the page sets is not here.
|
|
144
144
|
mensagem = str(e)
|
|
145
145
|
if 'is not defined' in mensagem:
|
|
146
|
+
from quantum.core.docs_links import HOW_A_PAGE_RUNS
|
|
146
147
|
mensagem += (". A q:action does not run the page's statements: "
|
|
147
|
-
"query or compute what it needs inside the action")
|
|
148
|
+
f"query or compute what it needs inside the action. See {HOW_A_PAGE_RUNS}")
|
|
148
149
|
logger.exception(
|
|
149
150
|
"q:action %r failed: %s", getattr(action, 'name', '?'), mensagem
|
|
150
151
|
)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""The application's server on a free local port, for renderers that are not a browser.
|
|
2
|
+
|
|
3
|
+
`quantum console` (UI-3) and `quantum desktop` (UI-4) open the whole
|
|
4
|
+
application — pages, actions, sessions — through the same server that
|
|
5
|
+
`quantum start` runs. Only the drawing differs; nothing of a page's logic runs
|
|
6
|
+
anywhere else.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
import threading
|
|
11
|
+
from contextlib import contextmanager
|
|
12
|
+
from typing import Iterator
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@contextmanager
|
|
16
|
+
def local_server(config_path: str = 'quantum.config.yaml') -> Iterator[str]:
|
|
17
|
+
"""Serve the application on 127.0.0.1 (a free port) in a thread; yield its base URL."""
|
|
18
|
+
from werkzeug.serving import make_server
|
|
19
|
+
from quantum.runtime.web_server import QuantumWebServer
|
|
20
|
+
|
|
21
|
+
logging.getLogger('werkzeug').setLevel(logging.ERROR)
|
|
22
|
+
app = QuantumWebServer(config_path).app
|
|
23
|
+
servidor = make_server('127.0.0.1', 0, app, threaded=True)
|
|
24
|
+
threading.Thread(target=servidor.serve_forever, daemon=True).start()
|
|
25
|
+
try:
|
|
26
|
+
yield f'http://127.0.0.1:{servidor.server_port}/'
|
|
27
|
+
finally:
|
|
28
|
+
servidor.shutdown()
|