marko 5.22.6 → 5.22.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * @template T
3
3
  * @typedef {{
4
- * value?: readonly [T];
5
- * then?: { renderBody: Marko.Body<[Awaited<T>], void> };
6
- * catch?: { renderBody: Marko.Body<[unknown], void> };
7
- * placeholder?: { renderBody: Marko.Body<[], void> };
4
+ * value: readonly [T];
5
+ * then?: { renderBody: Marko.Body<[Awaited<T>]> };
6
+ * catch?: { renderBody: Marko.Body<[unknown]> };
7
+ * placeholder?: { renderBody: Marko.Body };
8
8
  * "client-reorder"?: boolean;
9
9
  * name?: string;
10
10
  * timeout?: number;
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 630 630">
2
+ <rect width="630" height="630" fill="#f7df1e"/>
3
+ <path d="m423.2 492.19c12.69 20.72 29.2 35.95 58.4 35.95 24.53 0 40.2-12.26 40.2-29.2 0-20.3-16.1-27.49-43.1-39.3l-14.8-6.35c-42.72-18.2-71.1-41-71.1-89.2 0-44.4 33.83-78.2 86.7-78.2 37.64 0 64.7 13.1 84.2 47.4l-46.1 29.6c-10.15-18.2-21.1-25.37-38.1-25.37-17.34 0-28.33 11-28.33 25.37 0 17.76 11 24.95 36.4 35.95l14.8 6.34c50.3 21.57 78.7 43.56 78.7 93 0 53.3-41.87 82.5-98.1 82.5-54.98 0-90.5-26.2-107.88-60.54zm-209.13 5.13c9.3 16.5 17.76 30.45 38.1 30.45 19.45 0 31.72-7.61 31.72-37.2v-201.3h59.2v202.1c0 61.3-35.94 89.2-88.4 89.2-47.4 0-74.85-24.53-88.81-54.075z"/>
4
+ </svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="512" viewBox="0 0 2560 1400"><path fill="url(#a)" d="M427 0h361L361 697l427 697H427L0 698z"/><linearGradient id="a" x2="0" y2="1"><stop offset="0" stop-color="hsl(181, 96.3%, 38.8%)"/><stop offset=".25" stop-color="hsl(186, 94.9%, 46.1%)"/><stop offset=".5" stop-color="hsl(191, 93.3%, 60.8%)"/><stop offset=".5" stop-color="hsl(195, 94.3%, 50.8%)"/><stop offset=".75" stop-color="hsl(199, 95.9%, 48.0%)"/><stop offset="1" stop-color="hsl(203, 94.9%, 38.6%)"/></linearGradient><path fill="url(#b)" d="M854 697h361L788 0H427z"/><linearGradient id="b" x2="0" y2="1"><stop offset="0" stop-color="hsl(170, 80.3%, 50.8%)"/><stop offset=".5" stop-color="hsl(161, 79.1%, 47.3%)"/><stop offset="1" stop-color="hsl(157, 78.1%, 38.9%)"/></linearGradient><path fill="url(#c)" d="M1281 0h361l-427 697H854z"/><linearGradient id="c" x2="0" y2="1"><stop offset="0" stop-color="hsl(86, 95.9%, 37.1%)"/><stop offset=".5" stop-color="hsl(86, 91.9%, 45.0%)"/><stop offset="1" stop-color="hsl(90, 82.1%, 51.2%)"/></linearGradient><path fill="url(#d)" d="M1642 0h-361l428 697-428 697h361l428-697z"/><linearGradient id="d" x2="0" y2="1"><stop offset="0" stop-color="hsl(55, 99.9%, 53.1%)"/><stop offset=".25" stop-color="hsl(51, 99.9%, 50.0%)"/><stop offset=".5" stop-color="hsl(47, 99.2%, 49.8%)"/><stop offset=".5" stop-color="hsl(39, 99.9%, 50.0%)"/><stop offset=".75" stop-color="hsl(35, 99.9%, 50.0%)"/><stop offset="1" stop-color="hsl(29, 99.9%, 46.9%)"/></linearGradient><path fill="url(#e)" d="M2132 0h-361l427 697-428 697h361l428-697z"/><linearGradient id="e" x2="0" y2="1"><stop offset="0" stop-color="hsl(352, 99.9%, 62.9%)"/><stop offset=".25" stop-color="hsl(345, 90.3%, 51.8%)"/><stop offset=".5" stop-color="hsl(341, 88.3%, 51.8%)"/><stop offset=".5" stop-color="hsl(336, 80.9%, 45.4%)"/><stop offset=".75" stop-color="hsl(332, 80.3%, 44.8%)"/><stop offset="1.1" stop-color="hsl(328, 78.1%, 35.9%)"/></linearGradient></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg"><rect fill="#3178c6" height="512" rx="50" width="512"/><rect fill="#3178c6" height="512" rx="50" width="512"/><path clip-rule="evenodd" d="m316.939 407.424v50.061c8.138 4.172 17.763 7.3 28.875 9.386s22.823 3.129 35.135 3.129c11.999 0 23.397-1.147 34.196-3.442 10.799-2.294 20.268-6.075 28.406-11.342 8.138-5.266 14.581-12.15 19.328-20.65s7.121-19.007 7.121-31.522c0-9.074-1.356-17.026-4.069-23.857s-6.625-12.906-11.738-18.225c-5.112-5.319-11.242-10.091-18.389-14.315s-15.207-8.213-24.18-11.967c-6.573-2.712-12.468-5.345-17.685-7.9-5.217-2.556-9.651-5.163-13.303-7.822-3.652-2.66-6.469-5.476-8.451-8.448-1.982-2.973-2.974-6.336-2.974-10.091 0-3.441.887-6.544 2.661-9.308s4.278-5.136 7.512-7.118c3.235-1.981 7.199-3.52 11.894-4.615 4.696-1.095 9.912-1.642 15.651-1.642 4.173 0 8.581.313 13.224.938 4.643.626 9.312 1.591 14.008 2.894 4.695 1.304 9.259 2.947 13.694 4.928 4.434 1.982 8.529 4.276 12.285 6.884v-46.776c-7.616-2.92-15.937-5.084-24.962-6.492s-19.381-2.112-31.066-2.112c-11.895 0-23.163 1.278-33.805 3.833s-20.006 6.544-28.093 11.967c-8.086 5.424-14.476 12.333-19.171 20.729-4.695 8.395-7.043 18.433-7.043 30.114 0 14.914 4.304 27.638 12.912 38.172 8.607 10.533 21.675 19.45 39.204 26.751 6.886 2.816 13.303 5.579 19.25 8.291s11.086 5.528 15.415 8.448c4.33 2.92 7.747 6.101 10.252 9.543 2.504 3.441 3.756 7.352 3.756 11.733 0 3.233-.783 6.231-2.348 8.995s-3.939 5.162-7.121 7.196-7.147 3.624-11.894 4.771c-4.748 1.148-10.303 1.721-16.668 1.721-10.851 0-21.597-1.903-32.24-5.71-10.642-3.806-20.502-9.516-29.579-17.13zm-84.159-123.342h64.22v-41.082h-179v41.082h63.906v182.918h50.874z" fill="#fff" fill-rule="evenodd"/></svg>
@@ -10,6 +10,7 @@
10
10
  "Styles",
11
11
  "Events",
12
12
  "Body content",
13
+ "TypeScript",
13
14
  "Marko 5 upgrade",
14
15
  "Troubleshooting Streaming"
15
16
  ]
@@ -0,0 +1,359 @@
1
+ # TypeScript in Marko
2
+
3
+ > **Note:** Types are supported in Marko v5.22.7+ and Marko v4.24.6+
4
+
5
+ Marko’s TypeScript support offers in-editor error checking, makes refactoring less scary, verifies that data matches expectations, and even helps with API design.
6
+
7
+ Or maybe you just want more autocomplete in VSCode. That works too.
8
+
9
+ ## Enabling TypeScript in your Marko project
10
+
11
+ There are two (non-exclusive) ways to add TypeScript to a Marko project:
12
+
13
+ - **For sites and web apps**, you can place [a `tsconfig.json` file](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) at the project root:
14
+ <pre>
15
+ 📁 components/
16
+ 📁 node_modules/
17
+ <img src="./icons/marko.svg" width=16> index.marko
18
+ 📦 package.json
19
+ <mark><img src="./icons/ts.svg" width=16> tsconfig.json</mark>
20
+ </pre>
21
+ - **If you’re [publishing packages of Marko tags](https://markojs.com/docs/custom-tags/#publishing-tags-to-npm)**, add the following to [your `marko.json`](https://markojs.com/docs/marko-json/):
22
+ ```json
23
+ "script-lang": "ts"
24
+ ```
25
+ This will automatically expose type-checking and autocomplete for the published tags.
26
+
27
+ > **ProTip**: You can also use the `script-lang` method for sites and apps.
28
+
29
+ ## Typing a tag's `input`
30
+
31
+ A `.marko` file will use any exported `Input` type for [that file’s `input` object](https://markojs.com/docs/class-components/#input).
32
+
33
+ This can be `export type Input` or `export interface Input`.
34
+
35
+ ### Example
36
+
37
+ _PriceField.marko_
38
+
39
+ ```marko
40
+ export interface Input {
41
+ currency: string;
42
+ amount: number;
43
+ }
44
+
45
+ <label>
46
+ Price in ${input.currency}:
47
+ <input type="number" value=input.amount min=0 step=0.01>
48
+ </label>
49
+ ```
50
+
51
+ You can also import, reuse, and extend `Input` interfaces from other `.marko` or `.ts` files:
52
+
53
+ ```marko
54
+ import { Input as PriceInput } from "<PriceField>";
55
+ import { ExtraTypes } from "lib/utils.ts";
56
+ export type Input = { ...PriceInput, ...ExtraTypes };
57
+ ```
58
+
59
+ ```marko
60
+ import { Input as PriceInput } from "<PriceField>";
61
+ export interface Input extends PriceInput {
62
+ discounted: boolean;
63
+ expiresAt: Date;
64
+ };
65
+ ```
66
+
67
+ ### Generic `Input`s
68
+
69
+ [Generic Types and Type Parameters](https://www.typescriptlang.org/docs/handbook/2/generics.html) on `Input` are recognized throughout the entire `.marko` template (excluding [static statements](https://markojs.com/docs/syntax/#static-javascript)).
70
+
71
+ For example, if you set up a component like this:
72
+
73
+ _components/my-select.marko_
74
+
75
+ ```marko
76
+ export interface Input<T> {
77
+ options: T[];
78
+ onSelect: (newVal: T) => unknown;
79
+ }
80
+
81
+ static function staticFn() {
82
+ // can NOT use `T` here
83
+ }
84
+
85
+ $ const instanceFn = (val: T) => {
86
+ // can use `T` here
87
+ }
88
+
89
+ // can use `as T` here
90
+ <select on-input(evt => input.onSelect(options[evt.target.value] as T))>
91
+ <for|value, i| of=input.options>
92
+ <option value=i>${value}</option>
93
+ </for>
94
+ </select>
95
+ ```
96
+
97
+ …then your editor will figure out the types of inputs to that component:
98
+
99
+ ```marko
100
+ <my-select options=[1,2,3] onSelect=val => {}/>
101
+ // ^^^ number
102
+
103
+ <my-select options=["M","K","O"] onSelect=val => {}/>
104
+ // ^^^ string
105
+ ```
106
+
107
+ ## Built-in Marko Types
108
+
109
+ Marko exposes [type definitions](https://github.com/marko-js/marko/blob/main/packages/marko/index.d.ts) you can reuse in [a TypeScript namespace](https://www.typescriptlang.org/docs/handbook/namespaces.html) called `Marko`:
110
+
111
+ - **`Marko.Template<Input, Return>`**
112
+ - The type of a `.marko` file
113
+ - `typeof import("./template.marko")`
114
+ - **`Marko.TemplateInput<Input>`**
115
+ - The object accepted by the render methods of a template. It includes the template's `Input` as well as `$global` values.
116
+ - **`Marko.Body<Params, Return>`**
117
+ - The type of the [body content](https://markojs.com/docs/body-content/) of a tag (`renderBody`)
118
+ - **`Marko.Component<Input, State>`**
119
+ - The base class for a [class component](https://markojs.com/docs/class-components/)
120
+ - **`Marko.Renderable`**
121
+ - Values accepted by the [`<${dynamic}/>` tag](https://markojs.com/docs/syntax/#dynamic-tagname)
122
+ - `string | Marko.Template | Marko.Body | { renderBody: Marko.Body}`
123
+ - **`Marko.Out`**
124
+ - The render context with methods like `write`, `beginAsync`, etc.
125
+ - `ReturnType<template.render>`
126
+ - **`Marko.Global`**
127
+ - The type of the object on `out.global` that can be passed to a template's render methods as the `$global` property
128
+ - **`Marko.RenderResult`**
129
+ - The [result](https://markojs.com/docs/rendering/#renderresult) of rendering a Marko template
130
+ - `ReturnType<template.renderSync>`
131
+ - `Awaited<ReturnType<template.render>>`
132
+ - **`Marko.Emitter`**
133
+ - `EventEmitter` from `@types/node`
134
+ - **`Marko.NativeTags`**
135
+ - `Marko.NativeTags`: An object containing all native tags and their types
136
+ - **`Marko.NativeTagInput<TagName>`** and **`Marko.NativeTagReturn<TagName>`**
137
+ - Helpers to extract the input and return types for the specified `keyof Marko.NativeTag`
138
+ - **`Marko.BodyParameters<Body>`** and **`Marko.BodyReturnType<Body>`**
139
+ - Helpers to extract the parameters and return types from the specified `Marko.Body`
140
+ - **`Marko.Repeated<T>`** and **`Marko.Repeatable<T>`**
141
+ - Used to represent types for attributes tags which can have one or many instances
142
+ - `Marko.Repeated<T>`: `[T, T, ...T[]]` (array with at least two items)
143
+ - `Marko.Repeatable<T>`: `T | Marko.Repeated<T>`
144
+
145
+ ### Typing `renderBody`
146
+
147
+ The most commonly used type from the `Marko` namespace is `Marko.Body` which can be used to type `input.renderBody`:
148
+
149
+ _child.marko_
150
+
151
+ ```marko
152
+ export interface Input {
153
+ renderBody?: Marko.Body;
154
+ }
155
+ ```
156
+
157
+ Here, the following will be acceptable values:
158
+
159
+ _index.marko_
160
+
161
+ ```marko
162
+ <child/>
163
+ <child>Text in render body</child>
164
+ <child>
165
+ <div>Any combination of components</div>
166
+ </child>
167
+ ```
168
+
169
+ Passing other values (including components) will cause a type error:
170
+
171
+ _index.marko_
172
+
173
+ ```marko
174
+ import OtherTag from "<other-tag>";
175
+ <child renderBody=OtherTag/>
176
+ ```
177
+
178
+ ### Typing Tag Parameters
179
+
180
+ Tag parameters are passed to the `renderBody` by the child tag. For this reason, `Marko.Body` also allows typing of its parameters:
181
+
182
+ _for-by-two.marko_
183
+
184
+ ```marko
185
+ export interface Input {
186
+ to: number;
187
+ renderBody: Marko.Body<[number]>
188
+ }
189
+
190
+ <for|i| from=0 to=input.to by=2>
191
+ <${input.renderBody}(i)/>
192
+ </for>
193
+ ```
194
+
195
+ _index.marko_
196
+
197
+ ```marko
198
+ <for-by-two|i| to=10>
199
+ <div>${i}</div>
200
+ </for-by-two>
201
+ ```
202
+
203
+ ### Extending a native tag type
204
+
205
+ The types for native tags are accessed via the global `Marko.NativeTags` type. Here's an example of a component that adds a feature to the `button` element:
206
+
207
+ _color-button.marko_
208
+
209
+ ```marko
210
+ export interface Input extends Marko.NativeTagInput<"button"> {
211
+ color: string;
212
+ renderBody?: Marko.Body;
213
+ }
214
+
215
+ $ const { color, renderBody, ...restOfInput } = input;
216
+
217
+ <button style=`color: ${color}` ...restOfInput>
218
+ <${renderBody}/>
219
+ </button>
220
+ ```
221
+
222
+ ## TypeScript Syntax in `.marko`
223
+
224
+ Any [JavaScript expression in Marko](https://markojs.com/docs/syntax/#inline-javascript) can also be written as a TypeScript expression.
225
+
226
+ ### Tag Type Parameters
227
+
228
+ ```marko
229
+ <child <T>|value: T|>
230
+ ...
231
+ </child>
232
+ ```
233
+
234
+ ### Tag Type Arguments
235
+
236
+ _components/child.marko_
237
+
238
+ ```marko
239
+ export interface Input<T> {
240
+ value: T;
241
+ }
242
+ ```
243
+
244
+ _index.marko_
245
+
246
+ ```marko
247
+ // number would be inferred in this case, but we can be explicit
248
+ <child<number> value=1 />
249
+ ```
250
+
251
+ ### Method Shorthand Type Parameters
252
+
253
+ ```marko
254
+ <child process<T>() { /* ... */ } />
255
+ ```
256
+
257
+ ### Attribute Type Assertions
258
+
259
+ The types of attribute values can _usually_ be inferred. When needed, you can assert values to be more specific with [TypeScript’s `as` keyword](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-assertions):
260
+
261
+ ```marko
262
+ <some-component
263
+ number=1 as const
264
+ names=[] as string[]
265
+ />
266
+ ```
267
+
268
+ # JSDoc Support
269
+
270
+ For existing projects that want to incrementally add type safety, adding full TypeScript support is a big leap. This is why Marko also includes full support for [incremental typing via JSDoc](https://www.typescriptlang.org/docs/handbook/intro-to-js-ts.html).
271
+
272
+ ## Setup
273
+
274
+ You can enable type checking in an existing `.marko` file by adding a `// @ts-check` comment at the top:
275
+
276
+ ```js
277
+ // @ts-check
278
+ ```
279
+
280
+ If you want to enable type checking for all Marko & JavaScript files in a JavaScript project, you can switch to using a [`jsconfig.json`](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#using-tsconfigjson-or-jsconfigjson). You can skip checking some files by adding a `// @ts-nocheck` comment to files.
281
+
282
+ Once that has been enabled, you can start by typing the input with JSDoc. Here's an example component with typed `input`:
283
+
284
+ ```marko
285
+ // @ts-check
286
+
287
+ /**
288
+ * @typedef {{
289
+ * firstName: string,
290
+ * lastName: string,
291
+ * }} Input
292
+ */
293
+
294
+ <div>${firstName} ${lastName}</div>
295
+ ```
296
+
297
+ ## With a separate `component.js` file
298
+
299
+ Many components in existing projects adhere to the following structure:
300
+
301
+ <pre>
302
+ 📁 components/
303
+ 📁 color-rotate-button/
304
+ <img src="./icons/marko.svg" width=16> index.marko
305
+ <img src="./icons/js.svg" width=16> component.js
306
+ </pre>
307
+
308
+ The `color-rotate-button` takes a list of colors and moves to the next one each time the button is clicked:
309
+
310
+ ```marko
311
+ <color-rotate-button colors=["red", "blue", "yellow"]>
312
+ Next Color
313
+ </color-rotate-button>
314
+ ```
315
+
316
+ Here is an example of how this `color-rotate-button` component could be typed:
317
+
318
+ _components/color-rotate-button/component.js_
319
+
320
+ ```js
321
+ // @ts-check
322
+
323
+ /**
324
+ * @typedef {{
325
+ * colors: string[],
326
+ * renderBody: Marko.Renderable
327
+ * }} Input
328
+ * @typedef {{
329
+ * colorIndex: number
330
+ * }} State
331
+ * @extends {Marko.Component<Input, State>}
332
+ */
333
+ export default class extends Marko.Component {
334
+ onCreate() {
335
+ this.state = {
336
+ colorIndex: 0
337
+ };
338
+ }
339
+
340
+ rotateColor() {
341
+ this.state.colorIndex =
342
+ (this.state.colorIndex + 1) % this.input.colors.length;
343
+ }
344
+ }
345
+ ```
346
+
347
+ _components/color-rotate-button/index.marko_
348
+
349
+ ```marko
350
+ // @ts-check
351
+
352
+ /* Input will be automatically imported from `component.js`! */
353
+
354
+ <button
355
+ onClick('rotateColor')
356
+ style=`color: ${input.colors[state.colorIndex]}`>
357
+ <${input.renderBody}/>
358
+ </button>
359
+ ```
package/index.d.ts CHANGED
@@ -11,7 +11,14 @@ declare namespace NodeJS {
11
11
  declare namespace Marko {
12
12
  /** A mutable global object for the current render. */
13
13
  export interface Global {
14
+ /** A list of globals that should be serialized to the browser. */
14
15
  serializedGlobals?: Record<string, boolean>;
16
+ /** A CSP Nonce to add to each script output from Marko. */
17
+ cspNonce?: string;
18
+ /** Used to uniquely identify a instance of a Marko runtime. */
19
+ runtimeId?: string;
20
+ /** Used for rendering multiple Marko templates in a single hydrated page. */
21
+ componentIdPrefix?: string;
15
22
  [attr: PropertyKey]: unknown;
16
23
  }
17
24
 
@@ -211,7 +218,10 @@ declare namespace Marko {
211
218
  }
212
219
 
213
220
  /** The top level api for a Marko Template. */
214
- export abstract class Template {
221
+ export abstract class Template<
222
+ Input = { [attr: PropertyKey]: any },
223
+ Return = unknown
224
+ > {
215
225
  /** Creates a Marko compatible output stream. */
216
226
  createOut(): Out;
217
227
 
@@ -228,7 +238,7 @@ declare namespace Marko {
228
238
  /** @marko-overload-start */
229
239
  /** Asynchronously render the template. */
230
240
  abstract render(
231
- input: Marko.TemplateInput,
241
+ input: Marko.TemplateInput<Input>,
232
242
  stream?: {
233
243
  write: (chunk: string) => void;
234
244
  end: (chunk?: string) => void;
@@ -237,15 +247,15 @@ declare namespace Marko {
237
247
 
238
248
  /** Synchronously render the template. */
239
249
  abstract renderSync(
240
- input: Marko.TemplateInput
250
+ input: Marko.TemplateInput<Input>
241
251
  ): Marko.RenderResult<Marko.Component>;
242
252
 
243
253
  /** Synchronously render a template to a string. */
244
- abstract renderToString(input: Marko.TemplateInput): string;
254
+ abstract renderToString(input: Marko.TemplateInput<Input>): string;
245
255
 
246
256
  /** Render a template and return a stream.Readable in nodejs or a ReadableStream in a web worker environment. */
247
257
  abstract stream(
248
- input: Marko.TemplateInput
258
+ input: Marko.TemplateInput<Input>
249
259
  ): ReadableStream<string> & NodeJS.ReadableStream;
250
260
  /** @marko-overload-end */
251
261
  }
@@ -303,7 +313,6 @@ declare namespace Marko {
303
313
 
304
314
  export type Repeated<T> = [T, T, ...T[]];
305
315
  export type Repeatable<T> = T | Repeated<T>;
306
- export type MaybeRepeatable<T> = undefined | Repeatable<T>;
307
316
 
308
317
  export interface NativeTags {
309
318
  [name: string]: {
@@ -311,4 +320,9 @@ declare namespace Marko {
311
320
  return: unknown;
312
321
  };
313
322
  }
323
+
324
+ export type NativeTagInput<Name extends keyof NativeTags> =
325
+ NativeTags[Name]["input"];
326
+ export type NativeTagReturn<Name extends keyof NativeTags> =
327
+ NativeTags[Name]["return"];
314
328
  }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "5.22.6",
3
+ "version": "5.22.8",
4
4
  "license": "MIT",
5
5
  "description": "UI Components + streaming, async, high performance, HTML templating for Node.js and the browser.",
6
6
  "dependencies": {
7
- "@marko/compiler": "^5.23.5",
8
- "@marko/translator-default": "^5.22.5",
7
+ "@marko/compiler": "^5.23.6",
8
+ "@marko/translator-default": "^5.22.6",
9
9
  "app-module-path": "^2.2.0",
10
10
  "argly": "^1.2.0",
11
11
  "browser-refresh-client": "1.1.4",
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * @template T
3
3
  * @typedef {{
4
- * value?: readonly [T];
5
- * then?: { renderBody: Marko.Body<[Awaited<T>], void> };
6
- * catch?: { renderBody: Marko.Body<[unknown], void> };
7
- * placeholder?: { renderBody: Marko.Body<[], void> };
4
+ * value: readonly [T];
5
+ * then?: { renderBody: Marko.Body<[Awaited<T>]> };
6
+ * catch?: { renderBody: Marko.Body<[unknown]> };
7
+ * placeholder?: { renderBody: Marko.Body };
8
8
  * "client-reorder"?: boolean;
9
9
  * name?: string;
10
10
  * timeout?: number;