@optionfactory/fml 9.0.0-rc3 → 9.0.0-rc31

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.
Files changed (44) hide show
  1. package/README.md +16 -88
  2. package/dist/client-errors.iife.js +40 -49
  3. package/dist/client-errors.iife.js.map +1 -1
  4. package/dist/client-errors.iife.min.js +1 -1
  5. package/dist/client-errors.iife.min.js.map +1 -1
  6. package/dist/custom-elements.json +491 -51
  7. package/dist/fml.css +25 -20
  8. package/dist/fml.css.map +1 -1
  9. package/dist/fml.iife.js +5866 -2563
  10. package/dist/fml.iife.js.map +1 -1
  11. package/dist/fml.iife.min.js +1 -1
  12. package/dist/fml.iife.min.js.map +1 -1
  13. package/dist/ftl.d.mts +425 -231
  14. package/dist/ftl.iife.js +774 -1044
  15. package/dist/ftl.iife.js.map +1 -1
  16. package/dist/ftl.iife.min.js +1 -1
  17. package/dist/ftl.iife.min.js.map +1 -1
  18. package/dist/ftl.min.mjs +1 -1
  19. package/dist/ftl.min.mjs.map +1 -1
  20. package/dist/ftl.mjs +774 -1044
  21. package/dist/ftl.mjs.map +1 -1
  22. package/dist/ful.css +25 -20
  23. package/dist/ful.css.map +1 -1
  24. package/dist/ful.d.mts +3048 -556
  25. package/dist/ful.iife.js +4977 -1395
  26. package/dist/ful.iife.js.map +1 -1
  27. package/dist/ful.iife.min.js +1 -1
  28. package/dist/ful.iife.min.js.map +1 -1
  29. package/dist/ful.min.mjs +1 -1
  30. package/dist/ful.min.mjs.map +1 -1
  31. package/dist/ful.mjs +4975 -1396
  32. package/dist/ful.mjs.map +1 -1
  33. package/dist/httpc.d.mts +143 -123
  34. package/dist/httpc.iife.js +163 -175
  35. package/dist/httpc.iife.js.map +1 -1
  36. package/dist/httpc.iife.min.js +1 -1
  37. package/dist/httpc.iife.min.js.map +1 -1
  38. package/dist/httpc.min.mjs +1 -1
  39. package/dist/httpc.min.mjs.map +1 -1
  40. package/dist/httpc.mjs +163 -175
  41. package/dist/httpc.mjs.map +1 -1
  42. package/dist/vscode.html-custom-data.json +239 -39
  43. package/dist/web-types.json +498 -51
  44. package/package.json +2 -2
package/dist/ftl.d.mts CHANGED
@@ -1,10 +1,6 @@
1
1
  /**
2
- * A Map bounded by entry count, evicting in insertion order: not an LRU (a hit
3
- * does not refresh an entry), just a cap keeping unbounded key spaces (parsed
4
- * expressions, compiled masks, formatter instances) from growing forever. The
5
- * capacity is sized so eviction never happens on a sane page: hitting it means
6
- * dynamically generated keys, where FIFO's worst case (evicting a hot entry)
7
- * costs one recomputation.
2
+ * A Map bounded by entry count, evicting the oldest entry when full. A hit does
3
+ * not refresh an entry: eviction follows insertion order, not use.
8
4
  */
9
5
  declare class BoundedCache {
10
6
  #private;
@@ -20,6 +16,7 @@ declare class BoundedCache {
20
16
  * @returns {V}
21
17
  */
22
18
  getOrCompute<K, V>(key: K, compute: (key: K) => V): V;
19
+ /** @returns {number} the number of entries held */
23
20
  get size(): number;
24
21
  }
25
22
  /**
@@ -31,121 +28,180 @@ declare class BoundedCache {
31
28
  */
32
29
  declare class Expressions {
33
30
  #private;
31
+ /** Parses the whole text as one expression: `user.name`. */
34
32
  static MODE_EXPRESSION: symbol;
33
+ /**
34
+ * Parses text with interpolations, `Hello {{ user.name }}`, evaluating to
35
+ * its parts: `{ type, value }` for each literal run and each `{{ }}` (text),
36
+ * `{{{ }}}` (html) or `{{{{ }}}}` (node) interpolation, in order.
37
+ */
35
38
  static MODE_TEMPLATED: symbol;
36
39
  /**
37
- * Parses an expression.
40
+ * The key under which the receiver of a module function answers a lookup
41
+ * against the bound data alone: `this[Expressions.BOUND](name)` resolves
42
+ * the name in the layers the scope was created with (a registry's data,
43
+ * the data handed to a Template factory) and never in an overlay pushed
44
+ * afterwards, by `data-tpl-each`, `data-tpl-with` or `withOverlay`. It is
45
+ * how a module reads what the page configured without the rendered data
46
+ * being able to supply or replace it. No name on the data stack reaches it.
47
+ */
48
+ static BOUND: symbol;
49
+ /**
50
+ * Parses an expression, caching the ast by mode and text.
38
51
  * @param {string} expression
39
- * @param {(typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED)?} [mode]
40
- * @returns the ast
52
+ * @param {(typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED)?} [mode] MODE_EXPRESSION when omitted
53
+ * @returns {any} the ast
54
+ * @throws a peggy syntax error when the text does not parse
41
55
  */
42
56
  static parse(expression: string, mode?: (typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED) | null): any;
43
57
  /**
44
- * Evaluates an expression.
58
+ * Evaluates a parsed ast against the modules and the data stack.
45
59
  * @param {{[k: string]: any } | null | undefined } modules
46
- * @param {any[]} dataStack
47
- * @param {any} ast
48
- * @param {(typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED)?} [mode]
49
- * @returns the result
60
+ * @param {any[]} dataStack innermost overlay last
61
+ * @param {any} ast what `parse` answered
62
+ * @param {(typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED)?} [mode] the mode it was parsed in
63
+ * @param {number} [bound] how many layers, from the outermost, are the bound data; all of them when omitted
64
+ * @returns {any} the value, or the list of parts in MODE_TEMPLATED
50
65
  */
51
66
  static evaluate(modules: {
52
67
  [k: string]: any;
53
- } | null | undefined, dataStack: any[], ast: any, mode?: (typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED) | null): any;
68
+ } | null | undefined, dataStack: any[], ast: any, mode?: (typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED) | null, bound?: number): any;
54
69
  /**
55
70
  * Parses and evaluates an expression.
56
71
  * @param {{ [x: string]: any; } | null | undefined} modules
57
- * @param {any[]} dataStack
72
+ * @param {any[]} dataStack innermost overlay last
58
73
  * @param {string} expression
59
- * @param {(typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED)?} [mode]
60
- * @returns the result
74
+ * @param {(typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED)?} [mode] MODE_EXPRESSION when omitted
75
+ * @param {number} [bound] how many layers, from the outermost, are the bound data; all of them when omitted
76
+ * @returns {any} the value, or the list of parts in MODE_TEMPLATED
61
77
  */
62
78
  static interpret(modules: {
63
79
  [x: string]: any;
64
- } | null | undefined, dataStack: any[], expression: string, mode?: (typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED) | null): any;
80
+ } | null | undefined, dataStack: any[], expression: string, mode?: (typeof Expressions.MODE_EXPRESSION | typeof Expressions.MODE_TEMPLATED) | null, bound?: number): any;
65
81
  }
66
82
  /**
67
83
  * A scope: the modules that `#name:fn()` resolves against and the data stack
68
84
  * that a bare identifier resolves against, as a single value. Adding an overlay
69
85
  * returns a new evaluator instead of modifying this one, so a template can add
70
86
  * data for one subtree without affecting the rest of the render.
87
+ *
88
+ * The layers an evaluator is created with are its bound data; the overlays
89
+ * pushed afterwards are not. A bare identifier resolves against both, while a
90
+ * module function can ask for the bound data alone through `Expressions.BOUND`.
71
91
  */
72
92
  declare class ExpressionEvaluator {
73
93
  #private;
74
- constructor(modules: any, dataStack: any);
75
- withModule(name: any, value: any): ExpressionEvaluator;
94
+ /**
95
+ * @param {{ [k: string]: any } | null | undefined} modules
96
+ * @param {any[]} dataStack innermost overlay last
97
+ * @param {number} [bound] how many layers, from the outermost, are the bound data; all of them when omitted
98
+ */
99
+ constructor(modules: {
100
+ [k: string]: any;
101
+ } | null | undefined, dataStack: any[], bound?: number);
102
+ /**
103
+ * A new evaluator with one more module: `#name:fn()` resolves into it, and an
104
+ * empty name merges a whole map whose functions resolve bare, as `#fn()`.
105
+ * @param {string} name
106
+ * @param {object} value
107
+ * @returns {ExpressionEvaluator}
108
+ */
109
+ withModule(name: string, value: object): ExpressionEvaluator;
110
+ /**
111
+ * A new evaluator with the data pushed as the innermost overlays, the last
112
+ * one winning a shared name. The bound data stays what it was.
113
+ * @param {...any} data
114
+ * @returns {ExpressionEvaluator}
115
+ */
76
116
  withOverlay(...data: any[]): ExpressionEvaluator;
77
117
  /**
78
118
  * Resolves a name against the data stack, with no parse round trip: the
79
119
  * lookup a template's bare identifier makes, for an imperative caller.
80
120
  * @param {string} name
121
+ * @returns {any} undefined when no overlay carries the name
81
122
  */
82
123
  resolve(name: string): any;
83
- /** Evaluates an expression against this scope. */
84
- evaluateExpression(expression: any): any;
85
- /** Evaluates a templated text, the `{{ }}` form, against this scope. */
86
- evaluateTemplated(text: any): any;
124
+ /**
125
+ * Evaluates an expression against this scope.
126
+ * @param {string} expression
127
+ * @returns {any}
128
+ */
129
+ evaluateExpression(expression: string): any;
130
+ /**
131
+ * Evaluates a templated text, the `{{ }}` form, against this scope.
132
+ * @param {string} text
133
+ * @returns {{ type: symbol, value: any }[]} its parts, as MODE_TEMPLATED describes
134
+ */
135
+ evaluateTemplated(text: string): {
136
+ type: symbol;
137
+ value: any;
138
+ }[];
87
139
  }
88
- /** Creates and inspects the DocumentFragments a Template renders into. */
140
+ /** Creates, serializes and inspects DocumentFragments. */
89
141
  declare class Fragments {
90
142
  /**
91
- * Creates a DocumentFragment from an string.
92
- * @param {...string} html
93
- * @returns {DocumentFragment} the fragment
143
+ * Parses html into a DocumentFragment adopted by the document, each piece
144
+ * trimmed and the pieces joined.
145
+ * @param {...string} html
146
+ * @returns {DocumentFragment}
94
147
  */
95
148
  static fromHtml(...html: string[]): DocumentFragment;
96
149
  /**
97
- * Creates a string representation (HTML) of a DocumentFragment, consuming it:
98
- * the nodes are moved out, not copied, and the fragment is left empty. Pass
150
+ * Serializes a fragment, or a single node, to html, consuming it: the nodes
151
+ * are moved out, not copied, and a fragment is left empty. Pass
99
152
  * `fragment.cloneNode(true)` to keep the original usable.
100
- * @param {DocumentFragment} fragment
101
- * @returns {string} the html
153
+ * @param {DocumentFragment|Node} fragment
154
+ * @returns {string}
102
155
  */
103
- static toHtml(fragment: DocumentFragment): string;
156
+ static toHtml(fragment: DocumentFragment | Node): string;
104
157
  /**
105
- * Checks if a fragment contains only blank text nodes
158
+ * Whether a fragment holds no element and no text but whitespace.
106
159
  * @param {DocumentFragment} fragment
107
- * @returns {boolean} true if the fragment is blank
160
+ * @returns {boolean}
108
161
  */
109
162
  static isBlank(fragment: DocumentFragment): boolean;
110
163
  /**
111
- * Creates a DocumentFragment from nodes.
112
- * @param {...Node} nodes
113
- * @returns {DocumentFragment} the fragment
164
+ * Moves the nodes, in order, into a new DocumentFragment.
165
+ * @param {...Node} nodes
166
+ * @returns {DocumentFragment}
114
167
  */
115
168
  static from(...nodes: Node[]): DocumentFragment;
116
169
  /**
117
- * Creates a DocumentFragment from childNodes of an element.
170
+ * Moves the children of a node into a new DocumentFragment, leaving the
171
+ * node empty.
118
172
  * @param {Node} el
119
- * @returns {DocumentFragment} the fragment
173
+ * @returns {DocumentFragment}
120
174
  */
121
175
  static fromChildNodes(el: Node): DocumentFragment;
122
176
  }
123
- /** Attribute reads and writes where a nullish value removes the attribute instead of setting it to the string 'null'. */
177
+ /** Attribute helpers: unique ids, defaults, prefixed forwarding, and writes where a nullish value removes the attribute. */
124
178
  declare class Attributes {
125
179
  static id: number;
126
180
  /**
127
- * Creates a unique id with the given prefix.
181
+ * A page-unique id under the prefix, as `prefix-n`.
128
182
  * @param {string} prefix
129
- * @returns
183
+ * @returns {string}
130
184
  */
131
185
  static uid(prefix: string): string;
132
186
  /**
133
- * Sets an attribute if not present.
187
+ * Sets an attribute when the element does not carry it.
134
188
  * @param {Element} el
135
189
  * @param {string} k
136
190
  * @param {string} v
137
- * @returns
191
+ * @returns {string|null} the attribute's value afterwards
138
192
  */
139
193
  static defaultValue(el: Element, k: string, v: string): string | null;
140
194
  /**
141
- * Forwards prefixed attributes from an element to another (removing the prefix).
195
+ * Copies every attribute whose name starts with the prefix onto another
196
+ * element, under the name without the prefix. `<prefix>class` adds its
197
+ * classes to the target's instead of replacing them.
142
198
  * @param {string} prefix
143
199
  * @param {Element} from
144
200
  * @param {Element} to
145
201
  */
146
202
  static forward(prefix: string, from: Element, to: Element): void;
147
203
  /**
148
- * Sets the value of an attribute. nullish values remove the attribute.
204
+ * Sets an attribute, or removes it when the value is nullish.
149
205
  * @param {Element} el
150
206
  * @param {string} attr
151
207
  * @param {string | null | undefined} value
@@ -160,67 +216,64 @@ declare class Attributes {
160
216
  */
161
217
  declare class LightSlots {
162
218
  /**
163
- * Extracts light slots from an element. For non default slots in a template tag, the content is extracted.
219
+ * Takes an element's children apart into slots, leaving the element empty.
220
+ * A named child is removed and contributes what `slotFromNode` answers;
221
+ * children sharing a name are gathered in order. A child with an empty
222
+ * `slot` belongs to the default slot, in document order among the rest.
164
223
  * @param {Element} el
165
- * @returns the slots
224
+ * @returns {Record<string, DocumentFragment>} the slots by name, `default` always present
166
225
  */
167
- static from(el: Element): {
168
- default: DocumentFragment;
169
- };
170
- static slotFromNode(el: any): any;
226
+ static from(el: Element): Record<string, DocumentFragment>;
227
+ /**
228
+ * What a slotted node contributes: a template's content, the parsed markup
229
+ * of a `<script type="text/html">`, or the node itself.
230
+ * @param {Element} el
231
+ * @returns {Element|DocumentFragment}
232
+ */
233
+ static slotFromNode(el: Element): Element | DocumentFragment;
171
234
  }
172
- /** Waits for the parser and for the document, for elements that upgrade before their own markup is complete. */
235
+ /** Waits on the parser and the document, and queries an element's own children. */
173
236
  declare class Nodes {
174
237
  /**
175
- * Checks if an element is already parsed.
238
+ * Whether the parser has moved past the element: the element, or one of
239
+ * its ancestors, has a next sibling.
176
240
  * @param {Element} el
177
- * @returns
241
+ * @returns {boolean}
178
242
  */
179
243
  static isParsed(el: Element): boolean;
180
244
  /**
181
- * Waits for the document's DOMContentLoaded, resolving immediately when
182
- * that moment already passed. 'interactive' alone cannot tell a document
183
- * still waiting for deferred scripts (the event comes, however late) from
184
- * a module imported past it (the event is gone): the two events order
185
- * themselves, DOMContentLoaded always precedes load, so racing the two
186
- * resolves with DCL whenever it is still coming and with load otherwise,
187
- * never early.
245
+ * Waits for the document's DOMContentLoaded. Resolves at once when that
246
+ * moment already passed, and for a document with no view, which receives
247
+ * no events. Never resolves early for a document still running its
248
+ * deferred scripts.
249
+ * @param {Document} doc
250
+ * @returns {Promise<void>}
188
251
  */
189
- static waitDomContentLoaded(doc: any): Promise<any>;
252
+ static waitDomContentLoaded(doc: Document): Promise<void>;
190
253
  /**
191
254
  * Waits for the element's closing tag to be parsed: one MutationObserver
192
255
  * resolves once the element, or any of its ancestors, gains a next sibling,
193
256
  * which is the parser having moved past this subtree. The document's
194
257
  * DOMContentLoaded is the deadline. Resolves immediately for an element
195
- * that is already parsed.
196
- *
197
- * Every ancestor is watched, not only the parent, because that is what the
198
- * predicate reads: an element last among its siblings becomes parsed when
199
- * an ancestor gains one, and a childList observer on the parent never sees
200
- * that. Formatted markup usually hides the difference, the whitespace
201
- * before a closing tag being a text node the parent does gain, so the gap
202
- * shows on whitespace-free markup, where the wait fell back to the
203
- * deadline. One observer takes many targets, so the cost is one observe()
204
- * per level, and it is disconnected at the first checkpoint past the
205
- * element either way.
206
- * @param {any} el
207
- * @returns {Promise<any>}
208
- */
209
- static waitParsed(el: any): Promise<any>;
210
- /**
211
- * Returns the first child of the element element (if exists) matching the selector.
258
+ * that is already parsed, or once the parser has finished the document.
212
259
  * @param {Element} el
260
+ * @returns {Promise<Element>} the element
261
+ */
262
+ static waitParsed(el: Element): Promise<Element>;
263
+ /**
264
+ * The first child element matching the selector, descendants excluded.
265
+ * @param {Element|DocumentFragment} el
213
266
  * @param {string} selector
214
- * @returns
267
+ * @returns {Element|null}
215
268
  */
216
- static queryChildren(el: Element, selector: string): Element | null;
269
+ static queryChildren(el: Element | DocumentFragment, selector: string): Element | null;
217
270
  /**
218
- * Returns all children of the element matching the selector.
219
- * @param {Element} el
271
+ * Every child element matching the selector, descendants excluded.
272
+ * @param {Element|DocumentFragment} el
220
273
  * @param {string} selector
221
- * @returns
274
+ * @returns {Element[]}
222
275
  */
223
- static queryChildrenAll(el: Element, selector: string): Element[];
276
+ static queryChildrenAll(el: Element | DocumentFragment, selector: string): Element[];
224
277
  }
225
278
  /**
226
279
  * A compiled fragment together with the scope it renders in. Both are
@@ -231,41 +284,45 @@ declare class Nodes {
231
284
  declare class Template {
232
285
  #private;
233
286
  /**
234
- * Creates a template from a string.
287
+ * Creates a template from html.
235
288
  * @param {string} html
236
289
  * @param {{ [k: string] : any }?} [modules]
237
- * @param {...*} data
238
- * @returns the template
290
+ * @param {...*} data the data stack, innermost last
291
+ * @returns {Template}
239
292
  */
240
293
  static fromHtml(html: string, modules?: {
241
294
  [k: string]: any;
242
295
  } | null, ...data: any[]): Template;
243
296
  /**
244
- * Creates a template from the content of the first template element matching the selector.
297
+ * Creates a template from the content of the first element matching the
298
+ * selector, which is adopted: the template element is left empty.
245
299
  * @param {string} selector for an HTMLTemplateElement
246
300
  * @param {{ [k: string] : any }?} [modules]
247
- * @param {...*} data
248
- * @returns the template
301
+ * @param {...*} data the data stack, innermost last
302
+ * @returns {Template}
303
+ * @throws when the selector matches no template element
249
304
  */
250
305
  static fromSelector(selector: string, modules?: {
251
306
  [k: string]: any;
252
307
  } | null, ...data: any[]): Template;
253
308
  /**
254
- * Creates a template from the content of an HTMLTemplateElement.
309
+ * Creates a template from the content of a template element, which is
310
+ * adopted: the template element is left empty.
255
311
  * @param {HTMLTemplateElement} templateEl
256
312
  * @param {{ [k: string] : any }?} [modules]
257
- * @param {...*} data
258
- * @returns the template
313
+ * @param {...*} data the data stack, innermost last
314
+ * @returns {Template}
259
315
  */
260
316
  static fromTemplate(templateEl: HTMLTemplateElement, modules?: {
261
317
  [k: string]: any;
262
318
  } | null, ...data: any[]): Template;
263
319
  /**
264
- * Creates a template from a DocumentFragment.
320
+ * Creates a template over a fragment, which is imported afresh on every
321
+ * render and never modified.
265
322
  * @param {DocumentFragment} fragment
266
323
  * @param { { [k: string] : any }? } [modules]
267
- * @param {...*} data
268
- * @returns the template
324
+ * @param {...*} data the data stack, innermost last
325
+ * @returns {Template}
269
326
  */
270
327
  static fromFragment(fragment: DocumentFragment, modules?: {
271
328
  [k: string]: any;
@@ -280,117 +337,151 @@ declare class Template {
280
337
  * Creates a new Template rendering in another scope: the one way to rebind
281
338
  * a compiled template to a registry's modules and data.
282
339
  * @param {ExpressionEvaluator} evaluator
340
+ * @returns {Template}
283
341
  */
284
342
  withEvaluator(evaluator: ExpressionEvaluator): Template;
285
343
  /**
286
- * Creates a new Template replacing the fragment.
344
+ * Creates a new Template over another fragment, in the same scope.
287
345
  * @param {DocumentFragment} fragment
346
+ * @returns {Template}
288
347
  */
289
348
  withFragment(fragment: DocumentFragment): Template;
290
349
  /**
291
- * Creates a new Template with a new module added.
350
+ * Creates a new Template with a module added, as `ExpressionEvaluator.withModule` does.
292
351
  * @param {string?} name
293
352
  * @param {{[k: string]: any}} value
353
+ * @returns {Template}
294
354
  */
295
355
  withModule(name: string | null, value: {
296
356
  [k: string]: any;
297
357
  }): Template;
298
358
  /**
299
- * Creates a new Template with new a data overlay added to the stack.
359
+ * Creates a new Template with the data pushed as the innermost overlays.
300
360
  * @param {...*} data
361
+ * @returns {Template}
301
362
  */
302
363
  withOverlay(...data: any[]): Template;
303
364
  /**
304
365
  * Evaluates an expression in this template's scope, widened by the overlays.
305
366
  * @param {string} expression
306
367
  * @param {...*} data
307
- * @returns the evaluated expression result
368
+ * @returns {any}
308
369
  */
309
370
  evaluateExpression(expression: string, ...data: any[]): any;
310
371
  /**
311
372
  * Evaluates a templated text, the `{{ }}` form, in this template's scope.
312
373
  * @param {string} text
313
374
  * @param {...*} data
314
- * @returns the parts the text evaluates to
375
+ * @returns {{ type: symbol, value: any }[]} the parts, as `Expressions.MODE_TEMPLATED` describes
315
376
  */
316
- evaluateTemplated(text: string, ...data: any[]): any;
377
+ evaluateTemplated(text: string, ...data: any[]): {
378
+ type: symbol;
379
+ value: any;
380
+ }[];
317
381
  /**
318
- * Returns an expression evaluator with bound modules and dataStack.
382
+ * The scope this template renders in.
383
+ * @returns {ExpressionEvaluator}
319
384
  */
320
385
  evaluator(): ExpressionEvaluator;
321
386
  /**
322
- * Renders the template.
323
- * @returns a DocumentFragment
387
+ * Renders the template into a new fragment, applying the `data-tpl-*`
388
+ * commands and bindings and the `{{ }}` interpolations.
389
+ * @returns {DocumentFragment}
390
+ * @throws {RenderError} naming the node and the directive that failed
324
391
  */
325
392
  render(): DocumentFragment;
326
393
  /**
327
- * Renders this template on the Element (replacing children).
394
+ * Renders this template into the element, replacing its children.
328
395
  * @param {Element} el
396
+ * @throws {RenderError}
329
397
  */
330
398
  renderTo(el: Element): void;
331
399
  /**
332
- * Renders this template appending the resulting fragment to the Element.
400
+ * Renders this template and appends the result to the element.
333
401
  * @param {Element} el
402
+ * @throws {RenderError}
334
403
  */
335
404
  appendTo(el: Element): void;
336
405
  /**
337
- * Renders this template on the first Element matching the selector (replacing children), if exists.
406
+ * Renders this template into the first element matching the selector,
407
+ * replacing its children; does nothing when none matches.
338
408
  * @param {string} selector
409
+ * @throws {RenderError}
339
410
  */
340
411
  renderToSelector(selector: string): void;
341
412
  /**
342
- * Renders this template appending the resulting fragment to the Element matching the selector, if exists.
413
+ * Renders this template and appends the result to the first element
414
+ * matching the selector; does nothing when none matches.
343
415
  * @param {string} selector
416
+ * @throws {RenderError}
344
417
  */
345
418
  appendToSelector(selector: string): void;
346
419
  }
347
420
  /**
348
- * A render failure, one frame per nesting level. Each frame names the node it
349
- * failed on and what was being evaluated there, so the chain reads as the path
350
- * from the template's root down to the offending expression. The frame carries
351
- * the node's identification only, an open tag rather than its whole subtree:
352
- * the markup is serialized on demand through `html`, and the live node stays on
353
- * `node`, so a failure costs no clone and a nested failure does not embed the
354
- * page in its own message.
421
+ * A render failure, one frame per nesting level, chained through `cause` from
422
+ * the outermost frame down to the error that failed the expression. A frame's
423
+ * message names what was being evaluated and the node's open tag, with the
424
+ * attributes it still carries: the directive being evaluated is already off
425
+ * the tag. The subtree is not in the message; `html` serializes it on demand.
355
426
  */
356
427
  declare class RenderError extends Error {
357
428
  #private;
358
- /**
359
- * How many frames a chain keeps. The innermost are the specific ones, so a
360
- * deeper nesting drops the outer context rather than the failure site: three
361
- * frames name the offending node and the two levels that hold it, which is
362
- * the path a reader follows without the page arriving with it.
363
- */
429
+ /** How many frames a chain keeps: a deeper nesting drops the outermost ones and marks the chain `truncated`. */
364
430
  static FRAMES: number;
365
- /** true when the budget dropped the outer frames of this chain */
431
+ /** Whether the chain dropped outer frames to stay within FRAMES. */
366
432
  truncated: boolean;
367
433
  /**
368
- * Frames a failure, unless the chain already spent its budget: then the
369
- * cause travels on, marked so a report can say the outer context was
370
- * dropped.
371
- */
372
- static wrap(message: any, nodeOrFragment: any, cause: any): RenderError;
373
- constructor(message: any, nodeOrFragment: any, cause: any);
374
- /** How many frames this chain carries, this one included. */
375
- get depth(): any;
376
- /** The node the render failed on, live: it keeps its place in the fragment being built. */
377
- get node(): any;
378
- /** The node's markup, serialized when asked for rather than on every failure. */
434
+ * Frames a failure, unless the chain already holds FRAMES frames: then the
435
+ * cause is returned as it is, marked `truncated`.
436
+ * @param {string} message
437
+ * @param {Node} nodeOrFragment the node that failed
438
+ * @param {any} cause
439
+ * @returns {RenderError}
440
+ */
441
+ static wrap(message: string, nodeOrFragment: Node, cause: any): RenderError;
442
+ /**
443
+ * @param {string} message
444
+ * @param {Node} nodeOrFragment the node that failed
445
+ * @param {any} cause
446
+ */
447
+ constructor(message: string, nodeOrFragment: Node, cause: any);
448
+ /**
449
+ * How many frames this chain carries, this one included.
450
+ * @returns {number}
451
+ */
452
+ get depth(): number;
453
+ /**
454
+ * The node the render failed on, live in the fragment being built.
455
+ * @returns {Node}
456
+ */
457
+ get node(): Node;
458
+ /**
459
+ * The failed node's markup, whitespace trimmed, serialized on each read.
460
+ * @returns {string}
461
+ */
379
462
  get html(): string;
380
463
  /**
381
464
  * What identifies a node in a frame: an element by its open tag, a text node
382
- * by its source, a fragment by the open tags of the elements it holds.
465
+ * by its source, a fragment by the open tags of the elements it holds, cut
466
+ * at 120 characters.
467
+ * @param {Node} nodeOrFragment
468
+ * @returns {string}
469
+ */
470
+ static describe(nodeOrFragment: Node): string;
471
+ /**
472
+ * A node's markup with its whitespace-only text dropped and the rest trimmed.
473
+ * @param {Node} nodeOrFragment left untouched: a clone is serialized
474
+ * @returns {string}
383
475
  */
384
- static describe(nodeOrFragment: any): any;
385
- static stringify(nodeOrFragment: any): string;
476
+ static stringify(nodeOrFragment: Node): string;
386
477
  }
387
478
  /**
388
479
  * The page's single source of truth for elements, modules, data, components
389
480
  * and attribute mappers. Elements defined before configure() are deferred and
390
481
  * defined by it; from then on every defineElement takes effect immediately.
391
482
  * The exported `registry` singleton is the page's own; a `new Registry()` is a
392
- * separate instance, and Rendering and the ftl:ready machinery wait on the
393
- * singleton alone.
483
+ * separate instance with its own upgrade queue, which dispatches its own
484
+ * ftl:ready on the document, while Rendering waits on the singleton alone.
394
485
  */
395
486
  declare class Registry {
396
487
  #private;
@@ -398,11 +489,14 @@ declare class Registry {
398
489
  * Registers a custom element under its tag: the class is augmented with its
399
490
  * BITS (observed attributes, mappers, templates) and handed to the platform.
400
491
  * Before configure() the definition is deferred, so import order never
401
- * matters.
492
+ * matters. The element resolves its templates and components through this
493
+ * registry, whichever one a module imports, and its `static config` is read
494
+ * here, so a page replacing it does so before the definition.
402
495
  * @param {string} tag
403
496
  * @param {*} klass a ParsedElement subclass
497
+ * @returns {Registry} this registry
404
498
  */
405
- defineElement(tag: string, klass: any): this;
499
+ defineElement(tag: string, klass: any): Registry;
406
500
  /**
407
501
  * The attribute declarations a class composes along its inheritance chain,
408
502
  * base first: `observed` stay live after the upgrade and drive the property
@@ -411,13 +505,8 @@ declare class Registry {
411
505
  * ancestors', so a base class declares what every subclass keeps observing
412
506
  * (a protocol attribute such as Field's disabled claim) and a leaf refines a
413
507
  * mapping, or moves a name's position, without repeating the whole list.
414
- *
415
- * The walk stops where the platform's own class hierarchy begins: no earlier
416
- * stop can work, since a registered ancestor carries an own BITS of its own,
417
- * and nothing above the elements declares anything.
418
- *
419
- * Everything deriving a component's attribute vocabulary reads it here, so
420
- * the runtime and whatever documents it cannot walk the chain differently.
508
+ * The observed attributes are applied in the composed order, a re-declared
509
+ * name taking the position of its last declaration.
421
510
  * @param {*} klass a ParsedElement subclass
422
511
  * @returns {{ observed: string[], attributes: string[] }}
423
512
  */
@@ -429,14 +518,7 @@ declare class Registry {
429
518
  * The property an observed attribute drives, by the platform's own
430
519
  * dash-to-camel rule: the one `dataset` applies, so `clear-invalid-on-change`
431
520
  * would reach `clearInvalidOnChange` the way `data-clear-invalid-on-change`
432
- * reaches `dataset.clearInvalidOnChange`. A single-word name is returned
433
- * unchanged, which is what every observed attribute in the library is.
434
- *
435
- * It exists because the observed tier is the one that becomes properties:
436
- * without it an attribute could only be observed if its name happened to be
437
- * a usable identifier, which is why every multiword observed attribute here
438
- * used to be squashed into one word while the configuration tier, which
439
- * never becomes a property, spelled the same idea with a dash.
521
+ * reaches `dataset.clearInvalidOnChange`.
440
522
  *
441
523
  * Only this direction is mapped. A property never derives its attribute: a
442
524
  * setter reflects through `reflectTo`, naming the attribute it writes.
@@ -450,65 +532,90 @@ declare class Registry {
450
532
  * as `#fn`.
451
533
  * @param {string} name
452
534
  * @param {object} value
535
+ * @returns {Registry} this registry
453
536
  */
454
- defineModule(name: string, value: object): this;
537
+ defineModule(name: string, value: object): Registry;
455
538
  /**
456
539
  * Replaces the whole module map.
457
540
  * @param {object} ms
541
+ * @returns {Registry} this registry
458
542
  */
459
- defineModules(ms: object): this;
543
+ defineModules(ms: object): Registry;
460
544
  /**
461
545
  * Registers a named component (a loader, a response mapper), fetched back
462
546
  * through component().
463
547
  * @param {string} name
464
548
  * @param {*} value
549
+ * @returns {Registry} this registry
465
550
  */
466
- defineComponent(name: string, value: any): this;
551
+ defineComponent(name: string, value: any): Registry;
467
552
  /**
468
553
  * Replaces the data stack the templates evaluate over.
469
554
  * @param {...any} data
555
+ * @returns {Registry} this registry
470
556
  */
471
- defineData(...data: any[]): this;
557
+ defineData(...data: any[]): Registry;
472
558
  /**
473
559
  * Appends to the data stack, the later entry winning a shared name.
474
560
  * @param {...any} data
561
+ * @returns {Registry} this registry
475
562
  */
476
- defineOverlay(...data: any[]): this;
563
+ defineOverlay(...data: any[]): Registry;
477
564
  /**
478
565
  * Registers a custom attribute mapper type, available to every later
479
566
  * `name:type` declaration.
480
567
  * @param {string} k
481
568
  * @param {{ unmarshal(str: string|null, name: string, el: Element): any, marshal(value: any, name: string, el: Element): string|null }} v
569
+ * @returns {Registry} this registry
482
570
  */
483
571
  defineMapper(k: string, v: {
484
572
  unmarshal(str: string | null, name: string, el: Element): any;
485
573
  marshal(value: any, name: string, el: Element): string | null;
486
- }): this;
574
+ }): Registry;
487
575
  /**
488
576
  * Hands the registry over to the plugin's configure.
489
577
  * @param {{ configure(registry: Registry): void }} p
578
+ * @returns {Registry} this registry
490
579
  */
491
580
  plugin(p: {
492
581
  configure(registry: Registry): void;
493
- }): this;
582
+ }): Registry;
494
583
  /**
495
584
  * Defines every element deferred so far; from then on, defineElement takes
496
- * effect immediately.
585
+ * effect immediately. Readiness waits for the first call: a page that
586
+ * configures late (translations fetched first) gets its ftl:ready once the
587
+ * elements this defines have upgraded, not at DOMContentLoaded.
588
+ * @returns {Registry} this registry
497
589
  */
498
- configure(): this;
590
+ configure(): Registry;
499
591
  /**
500
592
  * Waits for the queued upgrades the filter accepts, rejecting with the first
501
- * that failed: the rejecting barrier Rendering is a facade over.
593
+ * that failed, the upgrades enqueued meanwhile included: the rejecting
594
+ * barrier Rendering is a facade over.
502
595
  * @param {(el: Element) => boolean} accept
596
+ * @returns {Promise<void>}
503
597
  */
504
598
  settle(accept: (el: Element) => boolean): Promise<void>;
505
- /** The pending upgrade of one element, undefined when it is not queued. */
506
- whenUpgraded(el: any): any;
507
- /** The elements whose upgrade is still pending, in queue order. */
508
- pending(): any[];
509
599
  /**
510
- * Waits for the page's readiness: the same moment the ftl:ready event is
511
- * dispatched at, resolving immediately when that moment already passed.
600
+ * The pending upgrade of one element: resolving when it has rendered,
601
+ * rejecting with what its upgrade threw.
602
+ * @param {Element} el
603
+ * @returns {Promise<void>|undefined} undefined when the element is not queued
604
+ */
605
+ whenUpgraded(el: Element): Promise<void> | undefined;
606
+ /**
607
+ * The elements whose upgrade is still pending, in queue order.
608
+ * @returns {Element[]}
609
+ */
610
+ pending(): Element[];
611
+ /**
612
+ * Waits for this registry's readiness: resolves right after its ftl:ready
613
+ * event is dispatched on the document, and immediately when that already
614
+ * happened. The event is dispatched once DOMContentLoaded has passed,
615
+ * configure() has been called and the queue has drained, so a registry
616
+ * that is never configured is never ready. Never rejects: a failed
617
+ * upgrade counts as settled, and its rejection is left unhandled so it
618
+ * still reaches the console and the page's error reporting.
512
619
  * @returns {Promise<void>}
513
620
  */
514
621
  ready(): Promise<void>;
@@ -516,29 +623,60 @@ declare class Registry {
516
623
  * The scope every template on this registry renders in: the modules and the
517
624
  * data stack, as one value. Replaced whenever either is defined, so a holder
518
625
  * of an older one keeps rendering against what it was handed.
626
+ * @returns {ExpressionEvaluator}
519
627
  */
520
628
  evaluator(): ExpressionEvaluator;
521
- /** The component registered under the name, undefined when none is. */
522
- component(name: any): any;
629
+ /**
630
+ * The component registered under the name.
631
+ * @param {string} name
632
+ * @returns {any} undefined when none is
633
+ */
634
+ component(name: string): any;
523
635
  }
524
636
  declare const registry: Registry;
525
- /** The Template factories, each bound to the page registry's scope. */
526
637
  /** The Template factories bound to the page's own registry: the same four sources, with its modules and data already applied. */
527
638
  declare class Templates {
528
- static fromHtml(html: any): Template;
529
- static fromSelector(selector: any): Template;
530
- static fromTemplate(templateEl: any): Template;
531
- static fromFragment(fragment: any): Template;
639
+ /**
640
+ * @param {string} html
641
+ * @returns {Template}
642
+ */
643
+ static fromHtml(html: string): Template;
644
+ /**
645
+ * @param {string} selector for an HTMLTemplateElement
646
+ * @returns {Template}
647
+ */
648
+ static fromSelector(selector: string): Template;
649
+ /**
650
+ * @param {HTMLTemplateElement} templateEl consumed: its content is adopted
651
+ * @returns {Template}
652
+ */
653
+ static fromTemplate(templateEl: HTMLTemplateElement): Template;
654
+ /**
655
+ * @param {DocumentFragment} fragment
656
+ * @returns {Template}
657
+ */
658
+ static fromFragment(fragment: DocumentFragment): Template;
532
659
  }
533
660
  /**
534
- * Awaitable rendering barriers over the registry's upgrade queue. These are
535
- * the rejecting waits: a failed upgrade among the awaited components rejects
536
- * the wait, where registry.ready() only ever means the queue drained and
537
- * leaves a failed component to its own unhandled-rejection report.
661
+ * Waits for elements queued on the page's `registry` to render. Unlike
662
+ * `registry.ready()`, these reject when an awaited upgrade fails. An element
663
+ * defined by another Registry is awaited through that registry instead.
538
664
  */
539
665
  declare class Rendering {
540
- static waitFor(el: any): Promise<void>;
541
- static waitForChildren(el: any): Promise<void>;
666
+ /**
667
+ * Waits for the element and its descendants, the ones their own renders
668
+ * enqueue included.
669
+ * @param {Element} el
670
+ * @returns {Promise<void>} rejecting with the first upgrade that failed
671
+ */
672
+ static waitFor(el: Element): Promise<void>;
673
+ /**
674
+ * Waits for the element's descendants, the element itself excluded: what a
675
+ * component awaits from inside its own render.
676
+ * @param {Element} el
677
+ * @returns {Promise<void>} rejecting with the first upgrade that failed
678
+ */
679
+ static waitForChildren(el: Element): Promise<void>;
542
680
  }
543
681
  export type Mapper = {
544
682
  unmarshal: (val: string | null | undefined, name: string, el: Element) => any;
@@ -551,6 +689,13 @@ export type Mapper = {
551
689
  * @property {(val: string|null|undefined, name: string, el: Element) => any} unmarshal
552
690
  * @property {(val: any, name: string, el: Element) => string|null} marshal
553
691
  */
692
+ /**
693
+ * The base of every fml element. A subclass declares its attributes, slots and
694
+ * templates in statics and builds its dom in `render`; the base reads the light
695
+ * slots, reads the declared attributes through their mappers, renders once, and
696
+ * then forwards observed attribute writes to the matching properties. An element
697
+ * resolves templates and components through the registry that defined it.
698
+ */
554
699
  declare class ParsedElement extends HTMLElement {
555
700
  #private;
556
701
  static BITS: {
@@ -572,41 +717,65 @@ declare class ParsedElement extends HTMLElement {
572
717
  static get observedAttributes(): string[];
573
718
  constructor();
574
719
  /**
575
- * The platform's window into the element's own state. The base attaches it
576
- * for every element, so a subclass never calls attachInternals itself: the
577
- * platform allows it once, and a second call throws. Form association is a
578
- * property of the definition rather than of who attached, so a subclass
579
- * declaring `static formAssociated` still gets the form apis here.
580
- *
581
- * A subclass must not redeclare it: a class field with no initializer
582
- * assigns undefined after super() returns, which would wipe it.
720
+ * The element's ElementInternals, attached by the base for every element: a
721
+ * subclass never calls attachInternals itself, since a second call throws.
722
+ * A subclass declaring `static formAssociated` gets the form apis here.
723
+ * A subclass must not redeclare the field: a class field without an
724
+ * initializer assigns undefined after super() returns, wiping it.
725
+ * @type {ElementInternals}
583
726
  */
584
727
  internals: ElementInternals;
585
- unmarshal(attr: any, str: any): any;
586
- marshal(attr: any, value: any): string | null;
587
728
  /**
588
- * @param {string} [name] - The name of the template target, defaults to 'default'
729
+ * Reads an attribute value through the mapper it was declared with.
730
+ * @param {string} attr
731
+ * @param {string|null} str
732
+ * @returns {any}
733
+ * @throws when the class declares no such attribute; read undeclared ones with getAttribute
589
734
  */
590
- /** The registry that defined this element, the page's own for an undefined one. */
591
- get _registry(): Registry;
735
+ unmarshal(attr: string, str: string | null): any;
736
+ /**
737
+ * Writes a value as the attribute string its declared mapper produces.
738
+ * @param {string} attr
739
+ * @param {any} value
740
+ * @returns {string|null} null for a value that removes the attribute
741
+ * @throws when the class declares no such attribute
742
+ */
743
+ marshal(attr: string, value: any): string | null;
744
+ /**
745
+ * The registry that defined this element, the page's own for an undefined one.
746
+ * @returns {typeof registry}
747
+ */
748
+ get _registry(): typeof registry;
592
749
  /**
593
750
  * The component registered under the name on this element's registry, the
594
751
  * one every ful loader and mapper resolves through.
595
752
  * @param {string} name
753
+ * @returns {any} undefined when none is registered
596
754
  */
597
755
  component(name: string): any;
598
- template(name: any): any;
756
+ /**
757
+ * One of the class's templates, bound to its registry's scope with the
758
+ * class's `static config` overlaid as `config`.
759
+ * @param {string} [name] 'default', the `static template`, when omitted
760
+ * @returns {Template}
761
+ * @throws when the class declares no template of that name
762
+ */
763
+ template(name?: string): Template;
599
764
  connectedCallback(): void;
600
765
  attributeChangedCallback(attr: any, oldValue: any, newValue: any): void;
601
766
  /**
602
- * Upgrades once: reads the declared attributes, keeps the observed half open
603
- * to writes made while the render is pending, applies them to the properties
604
- * when the render returns, and only then lets an attribute write forward.
767
+ * Upgrades once, however often the element is connected: reads the declared
768
+ * attributes, keeps the observed ones open to writes made while the render is
769
+ * pending, renders, then applies the observed values to their properties in
770
+ * the order the registry composed them, a base class's before a subclass's.
771
+ * Only then do attribute writes forward to properties, and the element gains
772
+ * the `rendered` custom state. A render that throws leaves the forwarding
773
+ * shut and the state unset.
605
774
  *
606
775
  * An observed attribute drives the property the registry's `propertyOf`
607
776
  * names, so a hyphenated attribute is authored with its dashes and read as
608
- * a camelCase property. A single-word attribute is its own property name,
609
- * which is what every observed attribute in the library is.
777
+ * a camelCase property.
778
+ * @returns {Promise<void>} rejecting with what the render threw
610
779
  */
611
780
  upgrade(): Promise<void>;
612
781
  /**
@@ -614,12 +783,13 @@ declare class ParsedElement extends HTMLElement {
614
783
  * drive, and the base applies the declared state onto the properties as
615
784
  * soon as it returns. A render needing a declared value while it builds
616
785
  * reads it through `declared(name)`. The slots are undefined for an element
617
- * declaring no slots.
618
- * @param {{ slots: any }} c
786
+ * declaring no slots. It may be async; the upgrade awaits it.
787
+ * @param {{ slots: Record<string, DocumentFragment> | undefined }} c
788
+ * @returns {void | Promise<void>}
619
789
  */
620
790
  render(c: {
621
- slots: any;
622
- }): void;
791
+ slots: Record<string, DocumentFragment> | undefined;
792
+ }): void | Promise<void>;
623
793
  /**
624
794
  * The declared value of an attribute, unmarshalled through its mapper.
625
795
  *
@@ -629,21 +799,21 @@ declare class ParsedElement extends HTMLElement {
629
799
  * observed name answers the snapshot while the render is pending, kept
630
800
  * open to attribute writes landing in that window, and the live attribute
631
801
  * afterwards, the property being live by then.
632
- *
633
- * The snapshot exists rather than a read of the dom because an element may
634
- * write its own observed attributes while it renders, whether a reflection
635
- * or a value the platform normalizes on the way in, and what the author
636
- * declared is what the base applies, not what the render left behind.
637
802
  * @param {string} name
803
+ * @returns {any}
804
+ * @throws when the class declares no such attribute
638
805
  */
639
806
  declared(name: string): any;
640
- /** Whether the element's render completed: the moment its properties went live. */
807
+ /**
808
+ * Whether the element's render completed: the moment its properties went
809
+ * live, which css reads as `:state(rendered)`. Unlike `:defined`, which holds
810
+ * from the constructor, it is false until the dom exists.
811
+ * @returns {boolean}
812
+ */
641
813
  get rendered(): boolean;
642
814
  /**
643
815
  * Projects a property back onto its observed attribute, marshalled through
644
- * the mapper the attribute was declared with: the one place a property
645
- * reaches its attribute, so a setter never has to know how its own type
646
- * serializes.
816
+ * the mapper the attribute was declared with.
647
817
  *
648
818
  * A value the attribute already carries is not written at all, so reflecting
649
819
  * what an attribute write just delivered ends there rather than looping, and
@@ -662,18 +832,23 @@ export type Receiver = {
662
832
  * The translations as a template module: `#l10n:t()` for messages, plus date,
663
833
  * number and bytes formatting in the page's locale. The template form and the
664
834
  * imperative `of()` facade both resolve through the registry's scope, so they
665
- * always produce the same result for the same key.
835
+ * always produce the same result for the same key. A template reads `l10n`
836
+ * and `locale` from its bound data only, the most recent layer winning: an
837
+ * overlay pushed while rendering (a row, a response) never reaches them.
666
838
  */
667
839
  declare class Localization {
668
840
  /**
669
841
  * Resolves a message from the translations and interpolates its arguments.
670
- * A single plain object argument interpolates named placeholders
671
- * ({name}); anything else interpolates positional ones ({0}).
842
+ * A single plain object argument (an object literal, or one with a null
843
+ * prototype) interpolates named placeholders ({name}); anything else interpolates positional ones ({0}).
672
844
  * A plural leaf selects its form through Intl.PluralRules over the
673
845
  * numeric {count} named argument.
674
846
  *
675
847
  * @param {string} key
676
848
  * @param {...any} args
849
+ * Each problem (a missing key, placeholder or plural form) is warned once
850
+ * per page.
851
+ *
677
852
  * @this {Receiver}
678
853
  * @returns {string} the message, or the key itself when the translations do not carry it
679
854
  */
@@ -684,16 +859,18 @@ declare class Localization {
684
859
  * @param {Date | number} value
685
860
  * @param {Intl.DateTimeFormatOptions} [options]
686
861
  * @this {Receiver}
862
+ * @returns {string}
687
863
  */
688
- static date(this: Receiver, value: Date | number, options?: Intl.DateTimeFormatOptions): any;
864
+ static date(this: Receiver, value: Date | number, options?: Intl.DateTimeFormatOptions): string;
689
865
  /**
690
866
  * Formats a number through Intl.NumberFormat in the receiver's locale.
691
867
  *
692
868
  * @param {number} value
693
869
  * @param {Intl.NumberFormatOptions} [options]
694
870
  * @this {Receiver}
871
+ * @returns {string}
695
872
  */
696
- static number(this: Receiver, value: number, options?: Intl.NumberFormatOptions): any;
873
+ static number(this: Receiver, value: number, options?: Intl.NumberFormatOptions): string;
697
874
  /**
698
875
  * Formats a byte size with binary thresholds and literal unit suffixes:
699
876
  * the digits honor the locale, the units are the near-universal KiB/MiB/GiB.
@@ -701,21 +878,38 @@ declare class Localization {
701
878
  *
702
879
  * @param {number} value
703
880
  * @this {Receiver}
881
+ * @returns {string}
704
882
  */
705
883
  static bytes(this: Receiver, value: number): string;
884
+ /**
885
+ * What went wrong, as text for the reader. A value carrying a non-empty
886
+ * `problems` array reads as their reasons, one per line, a blank or missing
887
+ * reason reading as the `failure.no-reason` message. Any other value with a
888
+ * `message` reads as that message; anything else as its string form, and
889
+ * null or undefined as the empty string.
890
+ *
891
+ * @param {any} value what was thrown or rejected with
892
+ * @this {Receiver}
893
+ * @returns {string}
894
+ */
895
+ static failure(this: Receiver, value: any): string;
706
896
  /**
707
897
  * An imperative facade over the module functions, resolving the translations
708
- * and the locale from the registry overlays on every call.
898
+ * and the locale from the registry overlays on every call, the same lookup a
899
+ * template makes: a facade taken at module scope, before the plugin
900
+ * configures, still sees the translations.
709
901
  *
710
902
  * @param {{ locale?: string }} [overrides] an explicit locale, winning over the registry one
903
+ * @returns {{ t: (key: string, ...args: any[]) => string, date: (value: Date | number, options?: Intl.DateTimeFormatOptions) => string, number: (value: number, options?: Intl.NumberFormatOptions) => string, bytes: (value: number) => string, failure: (value: any) => string }}
711
904
  */
712
905
  static of(overrides?: {
713
906
  locale?: string;
714
907
  }): {
715
- t: (...args: any[]) => any;
716
- date: (...args: any[]) => any;
717
- number: (...args: any[]) => any;
718
- bytes: (...args: any[]) => any;
908
+ t: (key: string, ...args: any[]) => string;
909
+ date: (value: Date | number, options?: Intl.DateTimeFormatOptions) => string;
910
+ number: (value: number, options?: Intl.NumberFormatOptions) => string;
911
+ bytes: (value: number) => string;
912
+ failure: (value: any) => string;
719
913
  };
720
914
  }
721
915
  export { Attributes, BoundedCache, ExpressionEvaluator, Expressions, Fragments, LightSlots, Localization, Nodes, ParsedElement, Registry, RenderError, Rendering, Template, Templates, registry };