@lokascript/compilation-service 3.1.1 → 3.3.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 +186 -1
- package/dist/{chunk-SUUECC42.js → chunk-AMTQUPKJ.js} +58 -7
- package/dist/chunk-AMTQUPKJ.js.map +1 -0
- package/dist/{chunk-T2AN3WRD.js → chunk-PEL4Z7TK.js} +3 -3
- package/dist/{core-parser-adapter-W5UPZR4X-B6CKOVA3.js → core-parser-adapter-W5UPZR4X-QSTMJ42V.js} +2 -2
- package/dist/{dist-WWPF6XTQ.js → dist-6EMM5HXE.js} +414 -230
- package/dist/dist-6EMM5HXE.js.map +1 -0
- package/dist/{dist-HOHQFWDA.js → dist-OK2I5ODH.js} +1090 -484
- package/dist/dist-OK2I5ODH.js.map +1 -0
- package/dist/http.cjs +1558 -717
- package/dist/http.cjs.map +1 -1
- package/dist/http.d.cts +1 -1
- package/dist/http.d.ts +1 -1
- package/dist/http.js +1 -1
- package/dist/index.cjs +1558 -717
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/{multilingual-VYI3FTN7.js → multilingual-TCFUREGW.js} +1 -1
- package/dist/multilingual-TCFUREGW.js.map +1 -0
- package/dist/{service-IyB2DZOm.d.cts → service-Da54XrEI.d.cts} +14 -0
- package/dist/{service-IyB2DZOm.d.ts → service-Da54XrEI.d.ts} +14 -0
- package/package.json +9 -9
- package/dist/chunk-SUUECC42.js.map +0 -1
- package/dist/dist-HOHQFWDA.js.map +0 -1
- package/dist/dist-WWPF6XTQ.js.map +0 -1
- package/dist/multilingual-VYI3FTN7.js.map +0 -1
- /package/dist/{chunk-T2AN3WRD.js.map → chunk-PEL4Z7TK.js.map} +0 -0
- /package/dist/{core-parser-adapter-W5UPZR4X-B6CKOVA3.js.map → core-parser-adapter-W5UPZR4X-QSTMJ42V.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,189 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.3.0] - 2026-10-02
|
|
11
|
+
|
|
12
|
+
The first publication of `@hyperfixi/engine`, the hyperscript engine meant to replace the one
|
|
13
|
+
in `@hyperfixi/core`, and the example gallery moved onto it.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **`@hyperfixi/engine` is published.** A hyperscript engine written against upstream
|
|
18
|
+
`_hyperscript`'s source, with upstream's own test suite as the acceptance oracle (1,401 of
|
|
19
|
+
1,467 tests; the 66 known failures are upstream's internal API, sockets and workers). It
|
|
20
|
+
ships `dist/hyperfixi-hs.js`, a script-tag bundle of hyperscript and nothing else, 34.1 KB
|
|
21
|
+
gzipped, which 36 of the repository's example pages now load instead of `hyperfixi.js`. It
|
|
22
|
+
keeps two forms upstream lacks, `new X(...)` and `toggle <element>`; the other hyperfixi-only
|
|
23
|
+
forms are not in it. It is typed (`tsc --strict`, no `any`), built from modules, and exposes
|
|
24
|
+
upstream's public API shape plus one hook, `addSourceTransform`, which
|
|
25
|
+
`@lokascript/hyperscript-adapter` uses to run the 24 languages on it.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- **Examples and docs are written in upstream `_hyperscript`'s spelling** wherever upstream has
|
|
30
|
+
one: `put Y into X` for the `swap` strategies, `debounced at 300ms`, `matches`, `set X's @a`,
|
|
31
|
+
`increment #count's textContent` (core counted in a bare `#count`; upstream does not),
|
|
32
|
+
`on mutation of childList from #x`, `my offsetLeft` in place of `measure x`. The multilingual
|
|
33
|
+
reader still accepts the old forms; the renderer writes upstream's. Corpus rows follow.
|
|
34
|
+
- **`@lokascript/semantic` renders `repeat for x in xs index i`** (was `with index`) and
|
|
35
|
+
`tell X show` (was `tell X to show`), upstream's spellings.
|
|
36
|
+
- **The examples' bundle loader** takes a per-page default (`data-default="hs"`), and `?bundle=hs`
|
|
37
|
+
switches any page to the engine bundle.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- **`@hyperfixi/core`**: `toggle *display of X` parsed and then threw.
|
|
42
|
+
- **Hybrid bundles (`hyperfixi-hx.js`)**: `increment` / `decrement` of a possessive wrote only
|
|
43
|
+
style properties; `increment #count's textContent` evaluated to the text and threw on
|
|
44
|
+
`querySelectorAll('0')`. They now write the property.
|
|
45
|
+
- **`@lokascript/semantic`**: a template-literal URL in a Korean handler was read as a custom
|
|
46
|
+
event name.
|
|
47
|
+
|
|
48
|
+
## [3.2.0] - 2026-09-30
|
|
49
|
+
|
|
50
|
+
A correctness release for multilingual hyperscript. The semantic parser behind
|
|
51
|
+
`translate()`, `@lokascript/hyperscript-adapter`, MCP `translate_code` and hyperfixi's
|
|
52
|
+
non-English path now keeps whole programs that it used to shorten or drop: values,
|
|
53
|
+
conditions, loops and handler heads. Every value shape in a generated matrix of 4,205
|
|
54
|
+
(executed in 24 languages, directly and through the adapter, against upstream
|
|
55
|
+
\_hyperscript) now matches upstream, apart from two documented differences. Core
|
|
56
|
+
matches upstream \_hyperscript on more forms.
|
|
57
|
+
|
|
58
|
+
### Added
|
|
59
|
+
|
|
60
|
+
- **Counted loops are written in each language's own words**: es `repetir 3 veces`,
|
|
61
|
+
fr `répéter 3 fois`, ja `3 回 を 繰り返し`, hi `3 बार को दोहराएं`, where translations
|
|
62
|
+
wrote English `times` in 18 languages and English `repeat` in the SOV six. English
|
|
63
|
+
`times`/`repeat` and each language's other count words (es `vez`, ru `раза`, …) still
|
|
64
|
+
read. 18 i18n dictionaries gain a `temporal.times` word.
|
|
65
|
+
- **Variable names that are words of the target language.** A variable spelled like a
|
|
66
|
+
structure word (es `si`, pl `w`, tr `al`) is written in parentheses, `(si)`, where the
|
|
67
|
+
plain translation would be misread, and read back as the variable. The language server
|
|
68
|
+
warns (`name-collision`, with a rename quick fix), MCP `validate_hyperscript` reports
|
|
69
|
+
`NAME_COLLISION`, and `translate_code` warns when a variable reads as a value word in
|
|
70
|
+
the target (tl `ako` is `me`). `@lokascript/semantic` exports `nameCollision`,
|
|
71
|
+
`findNameCollisions` and `findTranslationCollisions`.
|
|
72
|
+
- Event-handler modifiers (`once`, `debounced at`, `throttled at`, `from`) render in every
|
|
73
|
+
language and are scored by the fidelity signals.
|
|
74
|
+
- `of`-paths and pseudo-commands (`reset() the closest <form/>`) survive translation.
|
|
75
|
+
- `@lokascript/hyperscript-adapter`'s host gate also rejects a translation that reads a
|
|
76
|
+
reference as a handler's event (`on click on me toggle .active`, an empty click handler
|
|
77
|
+
plus a handler for an event named `me`), falling back to the author's text with a
|
|
78
|
+
warning; such a translation used to parse cleanly and do nothing.
|
|
79
|
+
- **Localized htmx attributes: all 23 non-English languages now cover
|
|
80
|
+
every attribute the _Hypermedia Systems_ book's code listings use** —
|
|
81
|
+
`hx-vals`, `hx-select`, `hx-swap-oob` and `hx-sync` join the Contact.app
|
|
82
|
+
twelve (`hx-値`, `hx-valores`, `hx-값`, `hx-werte`, `hx-選択`, `hx-selección`,
|
|
83
|
+
`hx-seçim`, `hx-auswahl`, `hx-sélection`, `hx-选择`, …). tr/de/fr/zh are new
|
|
84
|
+
in the table: the Contact.app seven they lacked (`hx-sil`, `hx-löschen`,
|
|
85
|
+
`hx-supprimer`, `hx-删除`, …) plus audited trigger/swap primaries following
|
|
86
|
+
loka-js (`hx-tetikleyici`, `hx-auslöser`, `hx-déclencheur`, `hx-替换`; the
|
|
87
|
+
profile words `hx-tetikle`, `hx-auslösen`, `hx-déclencher`, `hx-交换` still
|
|
88
|
+
resolve). de gains a lowercase `hx-ziel`: the profile's `hx-Ziel` could never
|
|
89
|
+
match a parsed attribute, since HTML lowercases attribute names. The other
|
|
90
|
+
15 languages (ar, bn, he, hi, id, it, ms, pl, qu, ru, sw, th, tl, uk, vi)
|
|
91
|
+
are unreviewed drafts, every entry flagged `lowConfidence`; they also gain
|
|
92
|
+
the trigger heads their dictionaries left in English (ms and tl all six,
|
|
93
|
+
vi/he/ar some). id gains `hx-sasaran` for a target that was the English
|
|
94
|
+
identity; tl keeps `hx-target` on purpose. `hx-ext` is left in English on
|
|
95
|
+
purpose: htmx 4 removed it. The vocab table gains an `events` block for
|
|
96
|
+
trigger heads the i18n dictionaries do not name; ja, es, pt and ko author
|
|
97
|
+
the DOM `search` event (`検索`, `buscar`, `검색`), which the book's and
|
|
98
|
+
Contact.app's search box fires. htmx's own trigger words (`revealed`,
|
|
99
|
+
`every`) stay English, like the `delay:` / `from:` modifiers.
|
|
100
|
+
- Adapter-only vocab keys now resolve from the authored table alone, never
|
|
101
|
+
from a semantic profile: 22 profiles carry a `select` keyword that means
|
|
102
|
+
mark/highlight text (de `markieren`, tr `vurgula`), and it would otherwise
|
|
103
|
+
have shipped as `hx-select` in 22 unreviewed languages.
|
|
104
|
+
|
|
105
|
+
- **Localized htmx attributes: ja, es, pt and ko now cover every attribute the
|
|
106
|
+
_Hypermedia Systems_ Contact.app uses** — `hx-post`, `hx-delete`,
|
|
107
|
+
`hx-confirm`, `hx-push-url`, `hx-boost`, `hx-indicator` and `hx-include` join
|
|
108
|
+
the existing five (e.g. `hx-削除`, `hx-eliminar`, `hx-excluir`, `hx-삭제`).
|
|
109
|
+
`hx-indicator` / `hx-include` localize under `@hyperfixi/htmx-adapter` (stock
|
|
110
|
+
htmx implements them; the embedded layer does not).
|
|
111
|
+
- **Vocab aliases.** Several localized names may map to one attribute or event;
|
|
112
|
+
the first is the form to teach, later ones keep already-authored pages
|
|
113
|
+
working. Core's embedded orchestrator now reads whichever form an element
|
|
114
|
+
carries (it previously kept a single name per attribute).
|
|
115
|
+
|
|
116
|
+
### Changed
|
|
117
|
+
|
|
118
|
+
- **Rendered vocabulary** (owner decisions): `null` is written `null` in ar, hi, id, qu,
|
|
119
|
+
sw, th and tr, where it shared the word for `empty`; hi writes `no` as `कोई नहीं`; qu
|
|
120
|
+
writes `and` as `hinallataq`; tl and tr write `includes` with `contains`' word (both
|
|
121
|
+
engines read the two as one operator).
|
|
122
|
+
- `@lokascript/semantic` exports its real `VERSION` (it was `0.1.0` since the first
|
|
123
|
+
release); browser bundles report `<version>-<bundle>`.
|
|
124
|
+
- MCP `translate_hyperscript` is described accurately: it uses the same semantic engine as
|
|
125
|
+
`translate_code`, without the verification.
|
|
126
|
+
- **Audited primaries for `hx-trigger` / `hx-swap`** in ja (`hx-トリガー`,
|
|
127
|
+
`hx-置換`), es (`hx-disparador`, `hx-intercambio`), pt (`hx-gatilho`,
|
|
128
|
+
`hx-troca`) and ko (`hx-교체`), following loka-js's terminology reviews. The
|
|
129
|
+
names that shipped before (`hx-引き金`, `hx-disparar`, …) still resolve.
|
|
130
|
+
- The vocab modules are regenerated against the current i18n dictionaries.
|
|
131
|
+
**No working name was removed** — 141 retired event names and three attribute
|
|
132
|
+
names are kept as aliases. One name changed meaning with its dictionary: sw
|
|
133
|
+
`panya_juu` is now `mouseup` (was `mouseover`).
|
|
134
|
+
|
|
135
|
+
### Fixed
|
|
136
|
+
|
|
137
|
+
- **Translations that lost code** (semantic parse and render, in every language):
|
|
138
|
+
- `get` of a literal (`get "hello"`, `get 3`, `get true`) dropped the whole command; an
|
|
139
|
+
object literal after `get` was cut to `get {`.
|
|
140
|
+
- Loops keep their extent and body; `repeat until` stops; a loop keeps its index
|
|
141
|
+
variable, the tail after an `if` inside it, and the command after an empty loop its own
|
|
142
|
+
`end` closes; a count may be any value (a variable, `$n`, `it`, a possessive), where
|
|
143
|
+
some translations read `forever`, a silent infinite loop.
|
|
144
|
+
- Handler heads keep `or` events, filters and event parameters; a translated
|
|
145
|
+
`wait for <event>` waits instead of throwing; behaviors keep their handlers and init
|
|
146
|
+
blocks; an else-if chain shares one `end`.
|
|
147
|
+
- Values keep their comparison phrases (`is equal to`, `includes`, `is an Element`, …),
|
|
148
|
+
`and`/`or`/`not`, `mod`, possessive and `of` chains, object and array literals, every
|
|
149
|
+
conversion core supports (`as Int`, `as Fixed:2`, piped conversions), unary minus and
|
|
150
|
+
property paths; `true`/`false`/`null` keep their meaning.
|
|
151
|
+
- Commands keep `put … into <variable>`, `tell … to show`, fetch's `do not throw` and
|
|
152
|
+
response type, event-source/socket URLs, show/hide `with` strategies, `go`/`scroll`
|
|
153
|
+
positions, `${…}` URLs, core's `has`, and a class query's `in` scope.
|
|
154
|
+
- **`@hyperfixi/core` follows upstream \_hyperscript**:
|
|
155
|
+
- `X of Y` binds as property access, and the X of a null target is null.
|
|
156
|
+
- `increment` reads its amount and counter as upstream does, and writing an object's
|
|
157
|
+
property through `'s`/`of` works.
|
|
158
|
+
- A loop's count reads as upstream's `index < times` does: `"6.5"` loops 7 times and
|
|
159
|
+
`"6abc"` none, in the full runtime and in the hybrid bundles (`hyperfixi-hx.js`,
|
|
160
|
+
plugin bundles), which read `parseInt`.
|
|
161
|
+
- Blocks close at the end of input; `morph … to`; `render … with name: value`; `beep!`
|
|
162
|
+
as an expression; `transition`'s owners, several properties, `from` and `using`; three
|
|
163
|
+
handler forms from _Hypermedia Systems_; four upstream-valid forms that compiled and
|
|
164
|
+
then failed at run time; `.item in #list` keeps its scope; `on click once` fires on
|
|
165
|
+
the first click.
|
|
166
|
+
- htmx: camelCase event names survive an attribute name.
|
|
167
|
+
- MCP: the validators report what the parsers actually did.
|
|
168
|
+
- The AOT compiler (experimental): loops were compiled to `while (true)`; targets,
|
|
169
|
+
property access, scoped queries, `empty` and variable scope now compile to what they
|
|
170
|
+
mean.
|
|
171
|
+
- `@lokascript/hyperscript-adapter` and `@hyperscript-tools/multilingual` READMEs: the
|
|
172
|
+
Japanese quickstart example was a dead button, and the multi-language example loaded
|
|
173
|
+
only the Spanish bundle; the examples are now native and run in a test. Bundle sizes are
|
|
174
|
+
measured.
|
|
175
|
+
- Bare CDN URLs now serve a browser bundle: `unpkg.com/@lokascript/hyperscript-adapter@3` (and
|
|
176
|
+
jsDelivr) served `dist/index.cjs`, which throws in a `<script>` tag. The adapter,
|
|
177
|
+
`@hyperscript-tools/multilingual`, `@lokascript/semantic`, `@hyperfixi/core` and
|
|
178
|
+
`@lokascript/htmx-adapter` declare `unpkg`/`jsdelivr` entries.
|
|
179
|
+
- `hyperfixi-multilingual.js`'s error names the semantic bundle that exists (the full
|
|
180
|
+
`browser.global.js`, the only one that defines `LokaScriptSemantic`).
|
|
181
|
+
- READMEs: `@lokascript/i18n` no longer claims to translate (and its `/lsp` export and CLI,
|
|
182
|
+
which do not exist, are gone); `@lokascript/semantic`, `@hyperfixi/vite-plugin` and
|
|
183
|
+
`@hyperfixi/core` have correct package names, API calls, language lists (24) and measured
|
|
184
|
+
bundle sizes.
|
|
185
|
+
- Dependencies: the js-yaml and smol-toml advisories; Vite 8, vitest 5 and happy-dom 20.14.
|
|
186
|
+
- **Vietnamese `hx-get` / `hx-target` / `hx-swap` / `hx-trigger` / `sse-swap`
|
|
187
|
+
never worked**: the names were emitted with spaces (`hx-lấy giá trị`), which
|
|
188
|
+
HTML reads as three attributes. They are now hyphen-joined
|
|
189
|
+
(`hx-lấy-giá-trị`), like vi's existing `hx-trực-tiếp`.
|
|
190
|
+
- 29 multi-word event names (ar, vi) were removed from the vocab modules: an
|
|
191
|
+
event is a single token of an `hx-trigger` value, so they could never match.
|
|
192
|
+
|
|
10
193
|
## [3.1.1] - 2026-09-04
|
|
11
194
|
|
|
12
195
|
### Fixed
|
|
@@ -716,7 +899,9 @@ _Synchronized version release. See git history for details._
|
|
|
716
899
|
- npm access token stored in GitHub Secrets
|
|
717
900
|
- 2FA recommended for npm organization
|
|
718
901
|
|
|
719
|
-
[Unreleased]: https://github.com/codetalcott/hyperfixi/compare/v3.
|
|
902
|
+
[Unreleased]: https://github.com/codetalcott/hyperfixi/compare/v3.3.0...HEAD
|
|
903
|
+
[3.3.0]: https://github.com/codetalcott/hyperfixi/compare/v3.2.0...v3.3.0
|
|
904
|
+
[3.2.0]: https://github.com/codetalcott/hyperfixi/compare/v3.1.0...v3.2.0
|
|
720
905
|
[3.1.0]: https://github.com/codetalcott/hyperfixi/compare/v3.0.0...v3.1.0
|
|
721
906
|
[2.10.0]: https://github.com/codetalcott/hyperfixi/compare/v2.9.0...v2.10.0
|
|
722
907
|
[2.9.0]: https://github.com/codetalcott/hyperfixi/compare/v2.8.0...v2.9.0
|
|
@@ -371,7 +371,8 @@ function extractOperations(node) {
|
|
|
371
371
|
}
|
|
372
372
|
function extractEventHandler(n) {
|
|
373
373
|
const eventRole = n.roles?.get("event");
|
|
374
|
-
const
|
|
374
|
+
const named = eventRole?.value ?? eventRole?.raw;
|
|
375
|
+
const eventName = typeof named === "string" && named.length > 0 ? named : "click";
|
|
375
376
|
const operations = [];
|
|
376
377
|
if (n.body && Array.isArray(n.body)) {
|
|
377
378
|
for (const child of n.body) {
|
|
@@ -2604,6 +2605,7 @@ function normalizeJSON(input) {
|
|
|
2604
2605
|
|
|
2605
2606
|
// src/validation/inert-shapes.ts
|
|
2606
2607
|
var QUANTIFIER = /^(all|every|each)\.(\S+)$/;
|
|
2608
|
+
var BARE_QUANTIFIER = /^(all|every|each)$/;
|
|
2607
2609
|
var PREDICATE_AS_CLASS = /(^|\s)\.(has|is|contains|matches|includes)(\s|$)/;
|
|
2608
2610
|
function valueString(v) {
|
|
2609
2611
|
return String(v.value ?? v.raw ?? "");
|
|
@@ -2630,6 +2632,15 @@ function walk(node, out) {
|
|
|
2630
2632
|
});
|
|
2631
2633
|
continue;
|
|
2632
2634
|
}
|
|
2635
|
+
if (v.type === "expression" && BARE_QUANTIFIER.test(s) && (role === "destination" || role === "source")) {
|
|
2636
|
+
out.push({
|
|
2637
|
+
severity: "warning",
|
|
2638
|
+
code: "INERT_QUANTIFIER_TARGET",
|
|
2639
|
+
message: `${role} parsed as the identifier "${s}", which is undefined at runtime, so this ${role} will not resolve; the selector after it is not read.`,
|
|
2640
|
+
suggestion: `Selectors already address every match: write the selector alone, without "${s}".`
|
|
2641
|
+
});
|
|
2642
|
+
continue;
|
|
2643
|
+
}
|
|
2633
2644
|
if (role === "condition" && v.type === "expression" && PREDICATE_AS_CLASS.test(s)) {
|
|
2634
2645
|
const word = PREDICATE_AS_CLASS.exec(s)?.[2];
|
|
2635
2646
|
out.push({
|
|
@@ -2806,6 +2817,7 @@ function compileSemanticNode(node, options = {}) {
|
|
|
2806
2817
|
var CompilationService = class _CompilationService {
|
|
2807
2818
|
constructor(options = {}) {
|
|
2808
2819
|
this.translateFn = null;
|
|
2820
|
+
this.translationCollisionsFn = null;
|
|
2809
2821
|
this.confidenceThreshold = options.confidenceThreshold ?? 0.7;
|
|
2810
2822
|
this.cache = new SemanticCache(options.cacheSize ?? 500);
|
|
2811
2823
|
this.testRenderers = new Map(
|
|
@@ -2850,7 +2862,7 @@ var CompilationService = class _CompilationService {
|
|
|
2850
2862
|
initValidation({
|
|
2851
2863
|
validateSemanticResult: semantic.validateSemanticResult
|
|
2852
2864
|
});
|
|
2853
|
-
const aot = await import("./dist-
|
|
2865
|
+
const aot = await import("./dist-6EMM5HXE.js");
|
|
2854
2866
|
const compiler = aot.createCompiler();
|
|
2855
2867
|
initBridge(
|
|
2856
2868
|
{
|
|
@@ -2860,6 +2872,7 @@ var CompilationService = class _CompilationService {
|
|
|
2860
2872
|
compiler
|
|
2861
2873
|
);
|
|
2862
2874
|
service.translateFn = semantic.translate;
|
|
2875
|
+
service.translationCollisionsFn = semantic.findTranslationCollisions;
|
|
2863
2876
|
return service;
|
|
2864
2877
|
}
|
|
2865
2878
|
// ===========================================================================
|
|
@@ -2984,7 +2997,7 @@ var CompilationService = class _CompilationService {
|
|
|
2984
2997
|
ok: true,
|
|
2985
2998
|
code: result,
|
|
2986
2999
|
...verification !== void 0 ? { verification } : {},
|
|
2987
|
-
diagnostics:
|
|
3000
|
+
diagnostics: this.translationCollisions(request)
|
|
2988
3001
|
};
|
|
2989
3002
|
} catch (error) {
|
|
2990
3003
|
return {
|
|
@@ -2999,6 +3012,20 @@ var CompilationService = class _CompilationService {
|
|
|
2999
3012
|
};
|
|
3000
3013
|
}
|
|
3001
3014
|
}
|
|
3015
|
+
/**
|
|
3016
|
+
* A variable of the source that the target language reads as a value word
|
|
3017
|
+
* (tl `ako` is `me`): the translation reads the value, and no spelling of
|
|
3018
|
+
* the name tells them apart, so the fix is a rename before translating.
|
|
3019
|
+
*/
|
|
3020
|
+
translationCollisions(request) {
|
|
3021
|
+
const findings = this.translationCollisionsFn?.(request.code, request.from, request.to) ?? [];
|
|
3022
|
+
return findings.map((finding) => ({
|
|
3023
|
+
severity: "warning",
|
|
3024
|
+
code: "NAME_COLLISION",
|
|
3025
|
+
message: finding.message,
|
|
3026
|
+
suggestion: finding.rename ? `Rename \`${finding.name}\` to \`${finding.rename}\` in the source (${finding.occurrences.length} place(s)), then translate.` : `Rename \`${finding.name}\` in the source, then translate.`
|
|
3027
|
+
}));
|
|
3028
|
+
}
|
|
3002
3029
|
/**
|
|
3003
3030
|
* Generate behavior-level tests from hyperscript.
|
|
3004
3031
|
*
|
|
@@ -3240,7 +3267,27 @@ var CompilationService = class _CompilationService {
|
|
|
3240
3267
|
if (!gateRef.pass || !gateCand.pass) {
|
|
3241
3268
|
return { ok: false, diagnostics };
|
|
3242
3269
|
}
|
|
3243
|
-
|
|
3270
|
+
const truncated = (...lists) => lists.some((ds) => ds.some((d) => d.code === "UNCONSUMED_INPUT"));
|
|
3271
|
+
const referenceComplete = !truncated(normRef.diagnostics, gateRef.diagnostics);
|
|
3272
|
+
const candidateComplete = !truncated(normCand.diagnostics, gateCand.diagnostics);
|
|
3273
|
+
if (!referenceComplete || !candidateComplete) {
|
|
3274
|
+
const sides = [!referenceComplete && "reference", !candidateComplete && "candidate"].filter(Boolean).join(" and ");
|
|
3275
|
+
diagnostics.push({
|
|
3276
|
+
severity: "warning",
|
|
3277
|
+
code: "INCOMPLETE_PARSE",
|
|
3278
|
+
message: `The ${sides} parse left tokens unconsumed, so the scores compare only what parsed; not faithful.`,
|
|
3279
|
+
suggestion: "The unconsumed tokens are named in the UNCONSUMED_INPUT diagnostics above. If the reference is truncated, a translation of it drops the same clause."
|
|
3280
|
+
});
|
|
3281
|
+
}
|
|
3282
|
+
const report = scoreNodes(normRef.node, normCand.node);
|
|
3283
|
+
return {
|
|
3284
|
+
ok: true,
|
|
3285
|
+
diagnostics,
|
|
3286
|
+
...report,
|
|
3287
|
+
faithful: report.faithful && referenceComplete && candidateComplete,
|
|
3288
|
+
referenceComplete,
|
|
3289
|
+
candidateComplete
|
|
3290
|
+
};
|
|
3244
3291
|
}
|
|
3245
3292
|
/**
|
|
3246
3293
|
* Generate a target-specific output from LSE (bracket syntax or protocol JSON).
|
|
@@ -3420,7 +3467,7 @@ function nodeToSemanticJSON(node) {
|
|
|
3420
3467
|
const bodyJSON = nodeToSemanticJSON(n.body[0]);
|
|
3421
3468
|
if (bodyJSON) {
|
|
3422
3469
|
bodyJSON.trigger = {
|
|
3423
|
-
event: eventRole
|
|
3470
|
+
event: eventNameOf(eventRole),
|
|
3424
3471
|
modifiers: n.eventModifiers
|
|
3425
3472
|
};
|
|
3426
3473
|
return bodyJSON;
|
|
@@ -3430,13 +3477,17 @@ function nodeToSemanticJSON(node) {
|
|
|
3430
3477
|
action: n.action,
|
|
3431
3478
|
roles,
|
|
3432
3479
|
trigger: {
|
|
3433
|
-
event: eventRole
|
|
3480
|
+
event: eventNameOf(eventRole),
|
|
3434
3481
|
modifiers: n.eventModifiers
|
|
3435
3482
|
}
|
|
3436
3483
|
};
|
|
3437
3484
|
}
|
|
3438
3485
|
return { action: n.action, roles };
|
|
3439
3486
|
}
|
|
3487
|
+
function eventNameOf(eventRole) {
|
|
3488
|
+
const name = eventRole?.value ?? eventRole?.raw;
|
|
3489
|
+
return typeof name === "string" && name.length > 0 ? name : "click";
|
|
3490
|
+
}
|
|
3440
3491
|
|
|
3441
3492
|
export {
|
|
3442
3493
|
diffBehaviors,
|
|
@@ -3452,4 +3503,4 @@ export {
|
|
|
3452
3503
|
SvelteRenderer,
|
|
3453
3504
|
CompilationService
|
|
3454
3505
|
};
|
|
3455
|
-
//# sourceMappingURL=chunk-
|
|
3506
|
+
//# sourceMappingURL=chunk-AMTQUPKJ.js.map
|