@quillmark/wasm 0.105.0 → 0.106.0
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.
- package/CHANGELOG.md +138 -0
- package/backends/pdfform/wasm.d.ts +5 -0
- package/backends/pdfform/wasm_bg.wasm +0 -0
- package/backends/typst/wasm.d.ts +5 -0
- package/backends/typst/wasm_bg.wasm +0 -0
- package/core/wasm.d.ts +5 -0
- package/core/wasm_bg.wasm +0 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,143 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.106.0 - 2026-08-16
|
|
4
|
+
|
|
5
|
+
- feat(typst,pdfform): a schema address may step one property into a declared
|
|
6
|
+
container, so `form-field(field: "classification.poc")` and
|
|
7
|
+
`field-region("address.city")` name a cell rather than the container holding
|
|
8
|
+
it. Two generated address tables gate the step the way `array_fields` gates
|
|
9
|
+
the index step, and a typed dictionary and a variant container reach both
|
|
10
|
+
alike: `classification.value` addresses the discriminant, `classification.poc`
|
|
11
|
+
a variant cell in any world. The pdfform binder descends a variant container
|
|
12
|
+
to match, so one address binds on either backend where `address.city` bound
|
|
13
|
+
only on pdfform and asserted on Typst. **Region addresses shift** for a plate
|
|
14
|
+
that reads a container property directly: `#data.classification.poc` regions
|
|
15
|
+
as `classification.poc` where it regioned as `classification`, and `fieldAt`
|
|
16
|
+
answers the same. A container read whole is unchanged, as is a read of a key
|
|
17
|
+
the container does not declare.
|
|
18
|
+
- feat(core,wasm)!: an `enum` may declare `variants:`, a per-member field set
|
|
19
|
+
that exists only in the world where the discriminant holds that member. This
|
|
20
|
+
is the DSL's first cross-field shape, and it replaces the `cui_`-prefix
|
|
21
|
+
convention with one the engine checks: `must_fill` inside a variant keeps its
|
|
22
|
+
ordinary `default:`-presence derivation, so it reads *required in this world* —
|
|
23
|
+
a `poc` obliged on a CUI memo and silent on every other one, the thing
|
|
24
|
+
`must_fill` alone could not say. **Breaking**: declaring `variants:` changes
|
|
25
|
+
the field's resting shape at every projection, from a bare string to a
|
|
26
|
+
container, `{value: <member>, …that member's fields}`; the bare scalar
|
|
27
|
+
(`classification: CUI`) is still accepted as the spelling of a world carrying
|
|
28
|
+
no answers, and coercion normalizes both. The wire carries exactly the live
|
|
29
|
+
world, so a plate reads a variant field inside the `values ∪ blank` branch it
|
|
30
|
+
already owes the enum, and inside that branch every declared field is present
|
|
31
|
+
and needs no guard. A value stranded by a discriminant flip is kept and warned
|
|
32
|
+
(`validation::out_of_variant`), never dropped at coercion or gated at render.
|
|
33
|
+
The ceiling is enforced at load, not discovered at render: a variant carries
|
|
34
|
+
plain data only, sits at card level only, and cannot declare `value`. The
|
|
35
|
+
transform schema projects the container with every world's fields flattened
|
|
36
|
+
under `properties`, since a binding built once against a schema must address a
|
|
37
|
+
field today's document has not selected; member scoping stays on the
|
|
38
|
+
declaration view, where `schema()` emits `variants:` keyed by member.
|
|
39
|
+
`FieldSchema` gains `variants` and `variant_field` (the cell a name declares
|
|
40
|
+
under any world); `VariantFields` and `VARIANT_DISCRIMINANT_KEY` are new.
|
|
41
|
+
- feat(fixtures)!: `usaf_memo`'s four `cui_*` fields move under
|
|
42
|
+
`classification`'s `CUI` variant as `controlled_by`, `poc`, `category`, and
|
|
43
|
+
`limited_dissemination`. `controlled_by` and `poc` drop their `default: ""`
|
|
44
|
+
and are therefore obliged — on a CUI memo only, which is what DoDM 5200.48
|
|
45
|
+
actually requires and what the flat spelling could state only in
|
|
46
|
+
`description:` prose. A document writes `classification: {value: CUI, …}` and
|
|
47
|
+
a plate reads `data.classification.value`.
|
|
48
|
+
- feat(typst): `field-region(field, body)` claims the ink `body` draws for a
|
|
49
|
+
schema field, so a plate can tie content it *composes* — a banner keyed on a
|
|
50
|
+
field, a package-built block, a computed table — to `session.regions()` and
|
|
51
|
+
`session.fieldAt(..)`. Layout-neutral: `body` is returned untouched between two
|
|
52
|
+
invisible `metadata` markers. It is a **fallback** claim, never an override:
|
|
53
|
+
ink already tracked to a field keeps that field, so wrapping is purely
|
|
54
|
+
additive and cannot retarget. Each *call* claims independently, so a wrapper
|
|
55
|
+
invoked once per card yields one region per card — the way a card's scalar
|
|
56
|
+
fields get regions at all, reading as they do from a loop variable that carries
|
|
57
|
+
no per-instance identity. The marker stack persists across pages so a claim can
|
|
58
|
+
span a page break, which leaves a claim whose closing marker never reaches a
|
|
59
|
+
frame bounded by nothing: it would take every unattributed piece of ink to the
|
|
60
|
+
end of the document. Those are found before the scan and suppressed in both the
|
|
61
|
+
region and point queries — an unbounded claim yields nothing rather than
|
|
62
|
+
everything — and reported as a `typst::unclosed_field_region` warning naming
|
|
63
|
+
the field, since only the plate author can act on it. Typst does not separate
|
|
64
|
+
the two markers on its own — they are siblings in content flow — but a plate
|
|
65
|
+
emitting the call's return value in parts can.
|
|
66
|
+
- feat(typst,pdf): `form-field` takes `font`, `size`, and `align`, so an
|
|
67
|
+
injected widget's value can be set to match the type around it. A widget was
|
|
68
|
+
fixed at Helvetica, auto-size, left: auto-size makes the rendered size a
|
|
69
|
+
function of both box height and how much the user has typed, and left
|
|
70
|
+
justification cannot be overcome by geometry, because a fillable box is sized
|
|
71
|
+
for the longest plausible value rather than the value in it. A right-aligned
|
|
72
|
+
fill-in — a USAF memo's date, say — was unreachable. `font` is one of
|
|
73
|
+
`"helvetica"`/`"times"`/`"courier"`, a widget being unable to carry a font
|
|
74
|
+
program; `size` is an absolute length or `auto` for the old behavior; `align`
|
|
75
|
+
is `"left"`/`"center"`/`"right"` and lands in `/Q`. All three are rejected on
|
|
76
|
+
`"checkbox"` and `"signature"`, which carry no variable text. `FieldSpec`
|
|
77
|
+
gains `font`, `font_size`, and `align` (`FormFont` and `TextAlign` are new).
|
|
78
|
+
A field that sets none of them stamps byte-identically to before, and
|
|
79
|
+
`pdfform` is untouched: `form.json` still carries no styling, so the flatten
|
|
80
|
+
path and canvas preview are unchanged.
|
|
81
|
+
- fix(fixtures): the `usaf_memo` indorsement date widget is set in the memo's
|
|
82
|
+
own 12pt Times and ends on the right margin, where the date it stands in for
|
|
83
|
+
would have ended. It was auto-sized Helvetica starting at the fill-in rule's
|
|
84
|
+
left end. Sizing it exposed that the rule-width box clips a real date — "28
|
|
85
|
+
September 2026" sets 93pt at 12pt Times against a 72pt box, and a fixed size
|
|
86
|
+
clips where auto-size had silently shrunk — so the widget is now 10em wide
|
|
87
|
+
and hangs off the rule's right edge, overrunning leftwards into the
|
|
88
|
+
whitespace a printed date grows into. Sized in ems of its own face rather
|
|
89
|
+
than inches because `font_size` is a document field with no ceiling: an inch
|
|
90
|
+
width would stay put while the text inside it grew. 10em clears both
|
|
91
|
+
orderings at any body size (DAF's "September 28, 2026" is the widest at
|
|
92
|
+
8.03em; USAF's "28 September 2026" is 7.78em). `date-placeholder-line` seats
|
|
93
|
+
it with a measured `dx` rather than `place(bottom + right)`, Typst clamping
|
|
94
|
+
an overflowing alignment back to zero, which leaves `right` indistinguishable
|
|
95
|
+
from `left`. That helper draws no rule now and is named `date-placeholder`
|
|
96
|
+
rather than `date-placeholder-line`: the widget carries the date, and a rule
|
|
97
|
+
under a widget wider than it underlines only the fraction of the value narrow
|
|
98
|
+
enough to sit over it. It is package-internal, not exported from `lib.typ`.
|
|
99
|
+
- fix(core): a name two variants declare *differently* is a load error,
|
|
100
|
+
`quill::variant_field_collision`. The name is one cell of the container
|
|
101
|
+
whichever world brings it into play — neither the coercion lookup nor the
|
|
102
|
+
transform schema consults the discriminant to fill it — so two readings of it
|
|
103
|
+
coerced a live value under the other world's type: a document selecting a
|
|
104
|
+
world whose `note` is `integer` had its `42` coerced to `"42"` by a sibling
|
|
105
|
+
world's `string` and then failed `validation::type_mismatch`, undraftable and
|
|
106
|
+
blamed for a string it never wrote. Identical declarations, which is what
|
|
107
|
+
repeating a shared field set or sharing a YAML anchor produces, collapse to
|
|
108
|
+
that one cell without loss and stay legal.
|
|
109
|
+
- fix(core,wasm,python)!: `EditError::UnknownField` carries the in-field path
|
|
110
|
+
`FieldDecode` and `FieldNotContent` carry. A property an `object` field does
|
|
111
|
+
not declare — `get_content_at("address", [Key("zip")])` against an `address`
|
|
112
|
+
with no `zip` — reported `field 'zip' is not declared in the schema`, which
|
|
113
|
+
reads as a claim about a top-level field and collides outright when a real
|
|
114
|
+
top-level field shares the name. It now reports
|
|
115
|
+
`field 'address.zip' is not declared in the schema` and anchors the
|
|
116
|
+
diagnostic at `main.address.zip`, so the caller can tell an undeclared
|
|
117
|
+
property from an undeclared field. **Breaking**: the variant is a struct
|
|
118
|
+
variant, `UnknownField { field, at }`, matching the two siblings; `field`
|
|
119
|
+
stays a bare field name, and the `edit::unknown_field` code, its `field` arg
|
|
120
|
+
and the whole-field message are unchanged.
|
|
121
|
+
- fix(python): declaring `license-files` ships the `LICENSE` the sdist metadata
|
|
122
|
+
names, which PyPI rejected the sdist for lacking. v0.104.0 and v0.105.0 are
|
|
123
|
+
wheels only.
|
|
124
|
+
|
|
125
|
+
<!-- seed: commits since v0.105.0, confirm the entries above cover them, then delete this comment
|
|
126
|
+
- chore(repo): union-merge CHANGELOG.md
|
|
127
|
+
- feat: migrate usaf_memo to enum variants, document the axis
|
|
128
|
+
- feat(core): enum variants — fields that exist only for one enum value
|
|
129
|
+
- fix(fixtures): drop the rule under the indorsement date
|
|
130
|
+
- fix(fixtures): size the indorsement date widget in ems, not inches
|
|
131
|
+
- fix(fixtures): set the memo's indorsement date widget like a date
|
|
132
|
+
- feat(typst,pdf): font, size, and align on injected form fields
|
|
133
|
+
- Make the usaf_memo indorsement's blank date a bound fill-in widget
|
|
134
|
+
- Compress the field-region prose
|
|
135
|
+
- Add `field-region` so plates can tie composed content to a field
|
|
136
|
+
- fix(python): declare license-files so the sdist ships its LICENSE
|
|
137
|
+
- Anchor an undeclared property at the property, not at a bare name
|
|
138
|
+
-->
|
|
139
|
+
|
|
140
|
+
|
|
3
141
|
## v0.105.0 - 2026-08-14
|
|
4
142
|
|
|
5
143
|
- feat(core,wasm,python)!: a `Content` nested inside a composite field is
|
|
@@ -462,6 +462,11 @@ export interface QuillFieldSchema {
|
|
|
462
462
|
/** The closed set of allowed values. Required on `type: "enum"`, and valid
|
|
463
463
|
* nowhere else. */
|
|
464
464
|
values?: string[];
|
|
465
|
+
/** Per-member field sets on a card-level `type: "enum"` field, keyed by
|
|
466
|
+
* member: the fields that exist only where the discriminant holds that
|
|
467
|
+
* member. Declaring it makes the field rest as a container,
|
|
468
|
+
* `{value: <member>, …that member's fields}`, rather than a bare string. */
|
|
469
|
+
variants?: Record<string, Record<string, QuillFieldSchema>>;
|
|
465
470
|
/** Whether a human must author the field. Absent, it derives from
|
|
466
471
|
* `default`: a defaulted field is unobliged, a defaultless one obliged. */
|
|
467
472
|
must_fill?: boolean;
|
|
Binary file
|
package/backends/typst/wasm.d.ts
CHANGED
|
@@ -462,6 +462,11 @@ export interface QuillFieldSchema {
|
|
|
462
462
|
/** The closed set of allowed values. Required on `type: "enum"`, and valid
|
|
463
463
|
* nowhere else. */
|
|
464
464
|
values?: string[];
|
|
465
|
+
/** Per-member field sets on a card-level `type: "enum"` field, keyed by
|
|
466
|
+
* member: the fields that exist only where the discriminant holds that
|
|
467
|
+
* member. Declaring it makes the field rest as a container,
|
|
468
|
+
* `{value: <member>, …that member's fields}`, rather than a bare string. */
|
|
469
|
+
variants?: Record<string, Record<string, QuillFieldSchema>>;
|
|
465
470
|
/** Whether a human must author the field. Absent, it derives from
|
|
466
471
|
* `default`: a defaulted field is unobliged, a defaultless one obliged. */
|
|
467
472
|
must_fill?: boolean;
|
|
Binary file
|
package/core/wasm.d.ts
CHANGED
|
@@ -407,6 +407,11 @@ export interface QuillFieldSchema {
|
|
|
407
407
|
/** The closed set of allowed values. Required on `type: "enum"`, and valid
|
|
408
408
|
* nowhere else. */
|
|
409
409
|
values?: string[];
|
|
410
|
+
/** Per-member field sets on a card-level `type: "enum"` field, keyed by
|
|
411
|
+
* member: the fields that exist only where the discriminant holds that
|
|
412
|
+
* member. Declaring it makes the field rest as a container,
|
|
413
|
+
* `{value: <member>, …that member's fields}`, rather than a bare string. */
|
|
414
|
+
variants?: Record<string, Record<string, QuillFieldSchema>>;
|
|
410
415
|
/** Whether a human must author the field. Absent, it derives from
|
|
411
416
|
* `default`: a defaulted field is unobliged, a defaultless one obliged. */
|
|
412
417
|
must_fill?: boolean;
|
package/core/wasm_bg.wasm
CHANGED
|
Binary file
|