Skip to content

Quantum 0.11.0 ​

The release that writes the language down: SPEC.md states what a program means, rule by rule, and every rule is pinned by a test that cites it.

Breaking ​

  • q:application type="html", type="api" and type="microservices" were removed (APP-1). They never ran their routes. q:application without a type meant html and is refused too; the parse error explains how to move to pages in components/ served by quantum start.
  • An expression that fails in a q: attribute is an error that names it, with a suggestion when a similar name exists (EXPR-1, EXPR-2). It used to be left as literal text — value="x{nada}y" produced "x{nada}y", and {10 / zero} produced its own braces. HTML content is still forgiving: an unresolved expression there is rendered as written and logged once (EXPR-4).
  • Arithmetic on a session/application value that is not set is an error (EXPR-3). {session.visitas + 1} used to become '' and fail later with "could not convert string to float". Reading the value alone still gives ''; for counters use operation="increment".
  • Only a missing name makes a condition false (EXPR-5). A syntax error or an unknown function in a condition is now an error instead of a silent false.
  • The first top-level q:return ends the component (RET-1), and a value that mixes text and expressions is always text: "007" stays "007" (RET-2).
  • A POST whose action field is missing or names no action is refused with 400 on pages with more than one q:action (ACT-5). It used to run the first action.
  • q:set types are checked (ERR-1). type="number" keeps fractions — {5 / 2} used to store 2; type="integer" refuses 3.5 instead of truncating it; type="boolean" refuses anything but true/false/1/0/yes/no.
  • An unknown q: tag is a parse error, with a suggestion (PARSE-1). <q:sett>, <q:retrun> or a tag the docs promised but never existed (q:try, q:storedproc, q:fetch, q:include, q:throw) used to be dropped silently, and the program ran without it.
  • q:query refuses cache, ttl, reactive, interval, timeout, maxrows and batch (DB-5): they never did anything.
  • quantum migrate applies migrations to the datasource in quantum.config.yaml (DB-6) — the one the pages use — chosen with --datasource when there are several. It used to read a separate database: section and, without one, try a local PostgreSQL named quantum before falling back to ./data/quantum.db: the migrations landed in a different database than the app queried.
  • The q:fetch data-fetching feature was removed. Its parser was never registered, so q:fetch never ran in a .q file; its guide page, example and module are gone.
  • q:function parameters are always converted and checked against their q:param rules, like actions (FN-1). validate="true" was needed before, and even then type="email" and min/max were not checked.
  • q:function refuses attributes that never did anything (FN-2): cache, memoize, pure, async, retry, timeout, access, scope, validate, endpoint and the REST attributes.
  • Arithmetic operators other than + need numbers (EXPR-7): '-' * 40 and '%s' % x are errors instead of Python's repetition and formatting. An attribute that is only {3} is the number 3, no longer the text {3}.
  • default on q:set applies when value resolves to nothing (SET-1): value="{session.clicks}" default="0" stores 0 on the first visit instead of ''.
  • q:param type="number" keeps whole numbers whole: "30" is 30, not 30.0 (decimal is still a float).
  • A failed q:data or q:invoke stops the component with an error naming the source and the reason, like q:query already did (DATA-4, INV-2). They used to leave the variable empty and carry on. Add onerror="continue" to handle the failure through <name>_result, whose error is now always {message}.

Fixed ​

  • && and || did not parse, so any condition using them was false for every input — including the examples in the conditionals guide (EXPR-6).
  • A q:else/q:elseif written after </q:if> was dropped inside q:loop, q:function, HTML elements and most other bodies; it only worked at the top of a component (IF-1).
  • q:invoke url= never worked without an explicit timeout, and its q:params were sent empty (INV-1).
  • form.<field> was empty inside q:action (ACT-6).
  • Conversion errors in q:set say what to write: value="{a} + {b}" points to {a + b}, and JSON with single quotes asks for double quotes, instead of Python's "could not convert string to float" (ERR-1).
  • quantum run printed a Python traceback for a failed q:invoke, and created ./logs/ and ./quantum_jobs.db in the current directory for any program (RUN-1, RUN-2).
  • q:job and q:schedule ran on two different job executors; every service now has one instance per runtime.
  • A component's q:function could not be called from its HTML: <p>{f(2)}</p> rendered the literal text (FN-3).
  • A q:query inside q:transaction datasource="…" had to repeat the datasource or the file did not parse (DB-4).
  • ${NAME:default} (with : only) is accepted in quantum.config.yaml as well as ${NAME:-default}.

Added ​

  • ${VAR} and ${VAR:-default} in quantum.config.yaml read environment variables; a missing one stops startup naming the variable (CFG-1).
  • SPEC.md, with conformance tests in tests/conformance/, and known gaps kept as strict expected failures until decided.
  • The guide examples that show an Output are executed by the test suite; the expressions and conditionals pages were rewritten from what runs.

← 0.10.0 · All versions · 0.12.0 →

MIT Licensed · Built with VitePress