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"andtype="microservices"were removed (APP-1). They never ran their routes.q:applicationwithout atypemeanthtmland is refused too; the parse error explains how to move to pages incomponents/served byquantum 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 useoperation="increment". - Only a missing name makes a
conditionfalse (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:returnends the component (RET-1), and avaluethat mixes text and expressions is always text:"007"stays"007"(RET-2). - A POST whose
actionfield is missing or names no action is refused with 400 on pages with more than oneq:action(ACT-5). It used to run the first action. q:settypes are checked (ERR-1).type="number"keeps fractions —{5 / 2}used to store2;type="integer"refuses3.5instead 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:queryrefusescache,ttl,reactive,interval,timeout,maxrowsandbatch(DB-5): they never did anything.quantum migrateapplies migrations to the datasource inquantum.config.yaml(DB-6) — the one the pages use — chosen with--datasourcewhen there are several. It used to read a separatedatabase:section and, without one, try a local PostgreSQL namedquantumbefore falling back to./data/quantum.db: the migrations landed in a different database than the app queried.- The
q:fetchdata-fetching feature was removed. Its parser was never registered, soq:fetchnever ran in a.qfile; its guide page, example and module are gone. q:functionparameters are always converted and checked against theirq:paramrules, like actions (FN-1).validate="true"was needed before, and even thentype="email"andmin/maxwere not checked.q:functionrefuses attributes that never did anything (FN-2):cache,memoize,pure,async,retry,timeout,access,scope,validate,endpointand the REST attributes.- Arithmetic operators other than
+need numbers (EXPR-7):'-' * 40and'%s' % xare errors instead of Python's repetition and formatting. An attribute that is only{3}is the number 3, no longer the text{3}. defaultonq:setapplies whenvalueresolves to nothing (SET-1):value="{session.clicks}" default="0"stores0on the first visit instead of''.q:param type="number"keeps whole numbers whole:"30"is30, not30.0(decimalis still a float).- A failed
q:dataorq:invokestops the component with an error naming the source and the reason, likeq:queryalready did (DATA-4, INV-2). They used to leave the variable empty and carry on. Addonerror="continue"to handle the failure through<name>_result, whoseerroris 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:elseifwritten after</q:if>was dropped insideq: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 explicittimeout, and itsq:params were sent empty (INV-1).form.<field>was empty insideq:action(ACT-6).- Conversion errors in
q:setsay 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 runprinted a Python traceback for a failedq:invoke, and created./logs/and./quantum_jobs.dbin the current directory for any program (RUN-1, RUN-2).q:jobandq:scheduleran on two different job executors; every service now has one instance per runtime.- A component's
q:functioncould not be called from its HTML:<p>{f(2)}</p>rendered the literal text (FN-3). - A
q:queryinsideq:transaction datasource="…"had to repeat the datasource or the file did not parse (DB-4). ${NAME:default}(with:only) is accepted inquantum.config.yamlas well as${NAME:-default}.
Added
${VAR}and${VAR:-default}inquantum.config.yamlread environment variables; a missing one stops startup naming the variable (CFG-1).SPEC.md, with conformance tests intests/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.