ferrovue 0.3.0 → 0.4.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/README.md +32 -13
- package/dist/attrs.d.ts +2 -52
- package/dist/attrs.js +18 -448
- package/dist/calls.d.ts +4 -0
- package/dist/calls.js +219 -0
- package/dist/children.d.ts +9 -0
- package/dist/children.js +273 -0
- package/dist/classes.d.ts +13 -0
- package/dist/classes.js +176 -0
- package/dist/cli.js +0 -17
- package/dist/client.js +0 -12
- package/dist/compiler.js +25 -90
- package/dist/component.js +10 -86
- package/dist/context.d.ts +4 -66
- package/dist/context.js +2 -33
- package/dist/diff.d.ts +0 -3
- package/dist/diff.js +0 -9
- package/dist/emitter.d.ts +0 -8
- package/dist/emitter.js +0 -12
- package/dist/expr.d.ts +0 -70
- package/dist/expr.js +27 -890
- package/dist/fallthrough.d.ts +9 -0
- package/dist/fallthrough.js +78 -0
- package/dist/fixture.d.ts +2 -1
- package/dist/fixture.js +37 -22
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/islands.d.ts +1 -0
- package/dist/islands.js +1 -0
- package/dist/lists.d.ts +0 -11
- package/dist/lists.js +4 -39
- package/dist/loops.d.ts +3 -0
- package/dist/loops.js +164 -0
- package/dist/model.d.ts +14 -143
- package/dist/model.js +27 -12
- package/dist/narrowing.d.ts +19 -0
- package/dist/narrowing.js +126 -0
- package/dist/numbers.d.ts +8 -0
- package/dist/numbers.js +73 -0
- package/dist/parens.d.ts +0 -27
- package/dist/parens.js +0 -44
- package/dist/plugin.d.ts +84 -0
- package/dist/plugin.js +26 -0
- package/dist/plugins/i18n.d.ts +23 -0
- package/dist/{i18n.js → plugins/i18n.js} +76 -19
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.js +8 -0
- package/dist/plugins/router-link.d.ts +8 -0
- package/dist/{router.js → plugins/router-link.js} +19 -61
- package/dist/plugins/router.d.ts +42 -0
- package/dist/plugins/router.js +256 -0
- package/dist/plugins/scoped.d.ts +12 -0
- package/dist/plugins/scoped.js +125 -0
- package/dist/plugins/shared-types.d.ts +2 -0
- package/dist/plugins/shared-types.js +7 -0
- package/dist/plugins/stores.d.ts +37 -0
- package/dist/plugins/stores.js +377 -0
- package/dist/plugins/teleport.d.ts +5 -0
- package/dist/plugins/teleport.js +55 -0
- package/dist/rust.d.ts +1 -7
- package/dist/rust.js +38 -160
- package/dist/script.d.ts +0 -6
- package/dist/script.js +13 -128
- package/dist/slots.d.ts +13 -0
- package/dist/slots.js +160 -0
- package/dist/strings.d.ts +13 -0
- package/dist/strings.js +208 -0
- package/dist/styles.d.ts +14 -0
- package/dist/styles.js +181 -0
- package/dist/template.d.ts +1 -42
- package/dist/template.js +14 -738
- package/dist/testing.d.ts +1 -0
- package/dist/testing.js +1 -8
- package/dist/types.d.ts +2 -0
- package/dist/typescript.d.ts +0 -13
- package/dist/typescript.js +8 -41
- package/dist/vite.d.ts +1 -0
- package/dist/vite.js +1 -23
- package/package.json +7 -2
- package/dist/i18n.d.ts +0 -27
- package/dist/router.d.ts +0 -17
- package/dist/scoped.d.ts +0 -24
- package/dist/scoped.js +0 -177
- package/dist/stores.d.ts +0 -6
- package/dist/stores.js +0 -229
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ The project has two halves:
|
|
|
26
26
|
| | What it is | Published as |
|
|
27
27
|
|---|---|---|
|
|
28
28
|
| `packages/ferrovue` | The compiler and the `ferrovue` command (TypeScript, runs on Node) | npm: [`ferrovue`](https://www.npmjs.com/package/ferrovue) |
|
|
29
|
-
| `crates/ferrovue` | The runtime the generated Rust calls: escaping, slots, islands, `<RouterLink>` matching | crates.io: [`ferrovue`](https://crates.io/crates/ferrovue) ([API docs](https://docs.rs/ferrovue)) |
|
|
29
|
+
| `crates/ferrovue` | The runtime the generated Rust calls: escaping, slots, islands, `<RouterLink>` matching. The router, vue-i18n and the escaping and number primitives they share are crates of their own (`crates/ferrovue-router`, `ferrovue-i18n`, `ferrovue-core`), which `ferrovue` re-exports | crates.io: [`ferrovue`](https://crates.io/crates/ferrovue) ([API docs](https://docs.rs/ferrovue)) |
|
|
30
30
|
|
|
31
31
|
## Quick start
|
|
32
32
|
|
|
@@ -118,6 +118,10 @@ With `routes` configured, the generated `route_table::router()` builds the route
|
|
|
118
118
|
each request's location with `router.at(path)` and pass the result to the components that take a
|
|
119
119
|
route.
|
|
120
120
|
|
|
121
|
+
The router and vue-i18n are features of the crate, `router` and `i18n`, both on by default. An
|
|
122
|
+
application with neither routes nor translations can leave them out, and build neither
|
|
123
|
+
`ferrovue-router` nor `ferrovue-i18n`: `ferrovue = { version = "0.4", default-features = false }`.
|
|
124
|
+
|
|
121
125
|
With the `maud` feature, `ferrovue::Html` implements `maud::Render`, so `(greeting::html(&props))` can go
|
|
122
126
|
straight into a `maud::html!` page.
|
|
123
127
|
|
|
@@ -248,7 +252,7 @@ gives the ids that other component inherits.
|
|
|
248
252
|
String methods count as JavaScript counts: in UTF-16 code units, so `"🦀".length` is 2 and
|
|
249
253
|
`"🦀 crab".slice(3)` is `"crab"`. Strings are ordered by code unit too, which puts every character
|
|
250
254
|
from U+E000 to U+FFFF after one beyond U+FFFF. Each runtime routine is held to vectors recorded from
|
|
251
|
-
JavaScript (`crates
|
|
255
|
+
JavaScript (`crates/*/tests/vectors/`).
|
|
252
256
|
|
|
253
257
|
A JavaScript string can hold half of a surrogate pair — `"🦀".slice(0, 1)`, `.charAt(1)`,
|
|
254
258
|
`.split("")` — and a Rust string cannot. ferrovue writes U+FFFD in its place, which is exactly what
|
|
@@ -319,12 +323,12 @@ data_list::render(&mut page, &props, data_list::Slots { row: Some(&row), ..Defau
|
|
|
319
323
|
|
|
320
324
|
### Hydrating islands
|
|
321
325
|
|
|
322
|
-
`mountIslands` from `ferrovue
|
|
326
|
+
`mountIslands` from `ferrovue` hydrates every `data-island` element on the page with the
|
|
323
327
|
component of that name, from the props the server wrote. With the Vite plugin, `ferrovue/islands`
|
|
324
328
|
gives it every island there is, so nothing has to be listed by hand:
|
|
325
329
|
|
|
326
330
|
```ts
|
|
327
|
-
import { hydrateState, mountIslands } from "ferrovue
|
|
331
|
+
import { hydrateState, mountIslands } from "ferrovue";
|
|
328
332
|
import islands from "ferrovue/islands"; // written by `ferrovue()` from `ferrovue/vite`
|
|
329
333
|
|
|
330
334
|
hydrateState(pinia);
|
|
@@ -355,7 +359,7 @@ ferrovue::state_script_into(&mut page, "__pinia", &stores); // a <script type=
|
|
|
355
359
|
```
|
|
356
360
|
|
|
357
361
|
```ts
|
|
358
|
-
import { hydrateState } from "ferrovue
|
|
362
|
+
import { hydrateState } from "ferrovue";
|
|
359
363
|
hydrateState(pinia); // before app.mount(): every store starts from what the server rendered
|
|
360
364
|
```
|
|
361
365
|
|
|
@@ -428,18 +432,33 @@ ferrovue version.
|
|
|
428
432
|
## Repository layout
|
|
429
433
|
|
|
430
434
|
```text
|
|
431
|
-
crates/ferrovue/ the Rust runtime crate
|
|
432
|
-
src/
|
|
435
|
+
crates/ferrovue/ the Rust runtime crate, which generated code calls
|
|
436
|
+
src/ a module per part (`Html`, slots, class and style, the state script,
|
|
437
|
+
strings, teleports, fallthrough attributes), each module's unit tests
|
|
438
|
+
beside it in <module>/tests.rs; lib.rs re-exports them all, and the
|
|
439
|
+
three crates below
|
|
433
440
|
tests/conformance/ components, fixtures, recorded HTML, generated Rust
|
|
434
|
-
tests/vectors/ vectors recorded from JavaScript
|
|
441
|
+
tests/vectors/ vectors recorded from JavaScript and Vue
|
|
435
442
|
tests/properties.rs property-based tests of the runtime
|
|
436
443
|
benches/ criterion benchmarks of generated renderers (see Performance)
|
|
444
|
+
crates/ferrovue-core/ escaping and JavaScript's numbers, which the other crates share
|
|
445
|
+
tests/vectors/ vectors recorded from escapeHtml, String(n), Math and toFixed
|
|
446
|
+
crates/ferrovue-router/ vue-router's matching and links (the `router` feature)
|
|
447
|
+
tests/vectors/ vectors recorded from vue-router
|
|
448
|
+
crates/ferrovue-i18n/ vue-i18n's t() (the `i18n` feature)
|
|
437
449
|
packages/ferrovue/ the compiler (npm package)
|
|
438
|
-
src/
|
|
439
|
-
src/
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
450
|
+
src/index.ts `ferrovue`: the browser API, `mountIslands`, `hydrateState` and the types
|
|
451
|
+
src/compiler.ts `ferrovue/compiler`: `generate`, `write`
|
|
452
|
+
src/component.ts, script.ts, typescript.ts
|
|
453
|
+
a `.vue` file read, <script setup>, TypeScript types
|
|
454
|
+
src/template.ts, children.ts, slots.ts, loops.ts
|
|
455
|
+
the compiled template: statements, child components, slots, v-for
|
|
456
|
+
src/expr.ts, strings.ts, numbers.ts, narrowing.ts, calls.ts, lists.ts
|
|
457
|
+
expressions: operators, strings, numbers, narrowing, calls, lists
|
|
458
|
+
src/attrs.ts, classes.ts, styles.ts, fallthrough.ts
|
|
459
|
+
attributes, class and style, attributes a parent passes on
|
|
460
|
+
src/plugin.ts the plugin interface (see CONTRIBUTING.md)
|
|
461
|
+
src/plugins/ vue-router, Pinia, vue-i18n, scoped styles, <Teleport>, shared types
|
|
443
462
|
src/rust.ts, emitter.ts the Rust source written out
|
|
444
463
|
src/cli.ts, vite.ts the `ferrovue` command and the Vite plugin
|
|
445
464
|
src/client.ts browser-side helpers: `mountIslands`, `hydrateState`
|
package/dist/attrs.d.ts
CHANGED
|
@@ -1,67 +1,17 @@
|
|
|
1
1
|
import { type N, type Scope, type Val } from "./model.ts";
|
|
2
2
|
import { Emitter } from "./emitter.ts";
|
|
3
|
-
|
|
3
|
+
export declare function display(e: Emitter, v: Val): boolean;
|
|
4
4
|
export declare function interpolate(e: Emitter, v: Val): void;
|
|
5
|
-
/** The value half of `key="value"`, escaped. */
|
|
6
5
|
export declare function attrValue(e: Emitter, v: Val): void;
|
|
7
|
-
/** `ssrRenderAttr(key, value)`: absent for null/undefined, `key="value"` for anything else. */
|
|
8
6
|
export declare function renderAttr(s: Scope, e: Emitter, key: string, v: Val, n: N): void;
|
|
9
|
-
/** `ssrRenderDynamicAttr(key, value)`: as `renderAttr`, but a boolean attribute is present or
|
|
10
|
-
* absent, and an empty string renders the name alone. */
|
|
11
7
|
export declare function renderDynamicAttr(s: Scope, e: Emitter, key: string, v: Val, n: N): void;
|
|
12
|
-
/** One item of a class list once it is flattened: literal text, known now, or a Rust `&str`
|
|
13
|
-
* expression evaluated at run time — empty when the item contributes nothing. */
|
|
14
|
-
export type ClassItem = {
|
|
15
|
-
lit: string;
|
|
16
|
-
} | {
|
|
17
|
-
code: string;
|
|
18
|
-
};
|
|
19
|
-
/** `normalizeClass`'s view of a class binding, flattened: a string, an array of items, an object
|
|
20
|
-
* of `name: condition`, `cond && "name"`, `cond ? "a" : null`. Every item is trimmed and the empty
|
|
21
|
-
* ones dropped before they are joined with one space, which is what `class_into` does too, so an
|
|
22
|
-
* object's keys become items of their own. */
|
|
23
|
-
export declare function classItems(s: Scope, n: N): ClassItem[];
|
|
24
|
-
/** `ssrRenderClass(value)`: normalised, then escaped. `after` says a class was already written. */
|
|
25
|
-
export declare function renderClass(s: Scope, e: Emitter, n: N, after?: boolean): void;
|
|
26
8
|
export declare const IGNORED_PROPS: Set<string>;
|
|
27
|
-
/** `ssrGetDirectiveProps(_ctx, dir)`: a custom directive's server props, which are none for a
|
|
28
|
-
* directive the configuration declares client-only. `false` when `n` is not such a call. */
|
|
29
9
|
export declare function directiveProps(s: Scope, n: N): boolean;
|
|
30
|
-
/** Whether `n` is the root's `_attrs`: what a parent passes, then the scope ids. */
|
|
31
10
|
export declare function isAttrs(n: N): boolean;
|
|
32
|
-
/** Whether `n` is `$attrs` — `_ctx.$attrs`, or a `useAttrs()` binding — which a component whose
|
|
33
|
-
* root is another's would find holding scope ids as well. */
|
|
34
11
|
export declare function dollarAttrs(s: Scope, n: N): boolean;
|
|
35
|
-
/** The parts `_mergeProps(…)` merges, or the one object that is not merged. */
|
|
36
12
|
export declare function mergedParts(n: N): N[];
|
|
37
|
-
/** `ssrRenderAttrs(obj)`, key by key in the object's order, and the inherited scope ids where the
|
|
38
|
-
* root's `_attrs` is merged in. When a parent may pass attributes, which only the run time knows,
|
|
39
|
-
* `$attrs` and the root's `_attrs` are merged with the element's own by `fv::attrs_into` — but only
|
|
40
|
-
* when some were passed: with none, the element is written as it is without. */
|
|
41
13
|
export declare function renderAttrs(s: Scope, e: Emitter, n: N): void;
|
|
42
|
-
/** `mergeProps(a, _attrs, b, …)` as one object literal, without `_attrs` and `$attrs`, which hold
|
|
43
|
-
* what only the run time knows. Of the rest, `class` and `style` values are merged as an array —
|
|
44
|
-
* unless a class equals the one so far, which Vue then keeps once — and any other key keeps the
|
|
45
|
-
* place it first had with the last value given. */
|
|
46
14
|
export declare function mergeProps(s: Scope, n: N): N;
|
|
47
|
-
/** The attributes of an object literal as `fv::Attr` entries, `("name", value)`, for a merge at run
|
|
48
|
-
* time: given to a child component (`vnode`), whose virtual node normalises a class array or object
|
|
49
|
-
* to a string, or an element's own (`own`), which `mergeProps` keeps as an object. */
|
|
50
15
|
export declare function attrEntries(s: Scope, obj: N, side: "vnode" | "own"): string[];
|
|
51
|
-
/** One attribute's value as an `fv::Attr`. */
|
|
52
16
|
export declare function attrOf(s: Scope, key: string, n: N, side: "vnode" | "own"): string;
|
|
53
|
-
|
|
54
|
-
export interface StyleItem {
|
|
55
|
-
cond: string | null;
|
|
56
|
-
entries: {
|
|
57
|
-
key: string;
|
|
58
|
-
css: string;
|
|
59
|
-
value: N;
|
|
60
|
-
}[];
|
|
61
|
-
}
|
|
62
|
-
/** The objects a style binding merges, in order: an object literal, a static `style` the compiler
|
|
63
|
-
* parsed, `v-show`'s `cond ? null : { display: "none" }`, and arrays of those. */
|
|
64
|
-
export declare function styleItems(s: Scope, n: N, when: string | null): StyleItem[];
|
|
65
|
-
/** `ssrRenderStyle(value)`: a string as it is, or the objects merged — each property where it first
|
|
66
|
-
* appears, with the last value given — and written `name:value;`, all escaped. */
|
|
67
|
-
export declare function renderStyle(s: Scope, e: Emitter, n: N): void;
|
|
17
|
+
export declare function valueAttr(s: Scope, v: Val, n: N): string;
|