mirror of
https://github.com/leptos-rs/leptos.git
synced 2025-12-28 11:21:55 -05:00
Compare commits
2 Commits
protected-
...
spin_3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5baa76603b | ||
|
|
a2927d7f18 |
4
.github/workflows/ci-semver.yml
vendored
4
.github/workflows/ci-semver.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
test:
|
||||
needs: [get-leptos-changed]
|
||||
if: needs.get-leptos-changed.outputs.leptos_changed == 'true'
|
||||
name: Run semver check (nightly-2024-04-14)
|
||||
name: Run semver check (nightly-2024-03-31)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -25,4 +25,4 @@ jobs:
|
||||
- name: Semver Checks
|
||||
uses: obi1kenobi/cargo-semver-checks-action@v2
|
||||
with:
|
||||
rust-toolchain: nightly-2024-04-14
|
||||
rust-toolchain: nightly-2024-03-31
|
||||
|
||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -40,4 +40,4 @@ jobs:
|
||||
with:
|
||||
directory: ${{ matrix.directory }}
|
||||
cargo_make_task: "ci"
|
||||
toolchain: nightly-2024-04-14
|
||||
toolchain: nightly-2024-03-31
|
||||
|
||||
2
.github/workflows/run-cargo-make-task.yml
vendored
2
.github/workflows/run-cargo-make-task.yml
vendored
@@ -55,7 +55,7 @@ jobs:
|
||||
run: cargo binstall cargo-leptos --no-confirm
|
||||
|
||||
- name: Install Trunk
|
||||
uses: jetli/trunk-action@v0.5.0
|
||||
uses: jetli/trunk-action@v0.4.0
|
||||
with:
|
||||
version: "latest"
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
# utilities
|
||||
"oco",
|
||||
|
||||
# core
|
||||
"leptos",
|
||||
"leptos_dom",
|
||||
@@ -32,7 +29,6 @@ version = "0.6.11"
|
||||
rust-version = "1.75"
|
||||
|
||||
[workspace.dependencies]
|
||||
oco_ref = { path = "./oco", version = "0.1.0" }
|
||||
leptos = { path = "./leptos", version = "0.6.11" }
|
||||
leptos_dom = { path = "./leptos_dom", version = "0.6.11" }
|
||||
leptos_hot_reload = { path = "./leptos_hot_reload", version = "0.6.11" }
|
||||
|
||||
1
docs/book_ru/.gitignore
vendored
1
docs/book_ru/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
book
|
||||
@@ -1,2 +0,0 @@
|
||||
Перевод в процессе, книга скоро будет доступна
|
||||
> Translation underway, book will be available soon
|
||||
@@ -1,10 +0,0 @@
|
||||
[output.html]
|
||||
additional-css = ["./mdbook-admonish.css"]
|
||||
[output.html.playground]
|
||||
runnable = false
|
||||
|
||||
[preprocessor]
|
||||
|
||||
[preprocessor.admonish]
|
||||
command = "mdbook-admonish"
|
||||
assets_version = "3.0.1" # не редактировать: управляется `mdbook-admonish install`
|
||||
@@ -1,345 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
:root {
|
||||
--md-admonition-icon--admonish-note: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z'/></svg>");
|
||||
--md-admonition-icon--admonish-abstract: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M17 9H7V7h10m0 6H7v-2h10m-3 6H7v-2h7M12 3a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m7 0h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z'/></svg>");
|
||||
--md-admonition-icon--admonish-info: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M13 9h-2V7h2m0 10h-2v-6h2m-1-9A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2z'/></svg>");
|
||||
--md-admonition-icon--admonish-tip: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M17.66 11.2c-.23-.3-.51-.56-.77-.82-.67-.6-1.43-1.03-2.07-1.66C13.33 7.26 13 4.85 13.95 3c-.95.23-1.78.75-2.49 1.32-2.59 2.08-3.61 5.75-2.39 8.9.04.1.08.2.08.33 0 .22-.15.42-.35.5-.23.1-.47.04-.66-.12a.58.58 0 0 1-.14-.17c-1.13-1.43-1.31-3.48-.55-5.12C5.78 10 4.87 12.3 5 14.47c.06.5.12 1 .29 1.5.14.6.41 1.2.71 1.73 1.08 1.73 2.95 2.97 4.96 3.22 2.14.27 4.43-.12 6.07-1.6 1.83-1.66 2.47-4.32 1.53-6.6l-.13-.26c-.21-.46-.77-1.26-.77-1.26m-3.16 6.3c-.28.24-.74.5-1.1.6-1.12.4-2.24-.16-2.9-.82 1.19-.28 1.9-1.16 2.11-2.05.17-.8-.15-1.46-.28-2.23-.12-.74-.1-1.37.17-2.06.19.38.39.76.63 1.06.77 1 1.98 1.44 2.24 2.8.04.14.06.28.06.43.03.82-.33 1.72-.93 2.27z'/></svg>");
|
||||
--md-admonition-icon--admonish-success: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='m9 20.42-6.21-6.21 2.83-2.83L9 14.77l9.88-9.89 2.83 2.83L9 20.42z'/></svg>");
|
||||
--md-admonition-icon--admonish-question: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='m15.07 11.25-.9.92C13.45 12.89 13 13.5 13 15h-2v-.5c0-1.11.45-2.11 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41a2 2 0 0 0-2-2 2 2 0 0 0-2 2H8a4 4 0 0 1 4-4 4 4 0 0 1 4 4 3.2 3.2 0 0 1-.93 2.25M13 19h-2v-2h2M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10c0-5.53-4.5-10-10-10z'/></svg>");
|
||||
--md-admonition-icon--admonish-warning: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M13 14h-2V9h2m0 9h-2v-2h2M1 21h22L12 2 1 21z'/></svg>");
|
||||
--md-admonition-icon--admonish-failure: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20 6.91 17.09 4 12 9.09 6.91 4 4 6.91 9.09 12 4 17.09 6.91 20 12 14.91 17.09 20 20 17.09 14.91 12 20 6.91z'/></svg>");
|
||||
--md-admonition-icon--admonish-danger: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M11 15H6l7-14v8h5l-7 14v-8z'/></svg>");
|
||||
--md-admonition-icon--admonish-bug: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M14 12h-4v-2h4m0 6h-4v-2h4m6-6h-2.81a5.985 5.985 0 0 0-1.82-1.96L17 4.41 15.59 3l-2.17 2.17a6.002 6.002 0 0 0-2.83 0L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8z'/></svg>");
|
||||
--md-admonition-icon--admonish-example: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M7 13v-2h14v2H7m0 6v-2h14v2H7M7 7V5h14v2H7M3 8V5H2V4h2v4H3m-1 9v-1h3v4H2v-1h2v-.5H3v-1h1V17H2m2.25-7a.75.75 0 0 1 .75.75c0 .2-.08.39-.21.52L3.12 13H5v1H2v-.92L4 11H2v-1h2.25z'/></svg>");
|
||||
--md-admonition-icon--admonish-quote: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M14 17h3l2-4V7h-6v6h3M6 17h3l2-4V7H5v6h3l-2 4z'/></svg>");
|
||||
--md-details-icon: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42Z'/></svg>");
|
||||
}
|
||||
|
||||
:is(.admonition) {
|
||||
display: flow-root;
|
||||
margin: 1.5625em 0;
|
||||
padding: 0 1.2rem;
|
||||
color: var(--fg);
|
||||
page-break-inside: avoid;
|
||||
background-color: var(--bg);
|
||||
border: 0 solid black;
|
||||
border-inline-start-width: 0.4rem;
|
||||
border-radius: 0.2rem;
|
||||
box-shadow: 0 0.2rem 1rem rgba(0, 0, 0, 0.05), 0 0 0.1rem rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
@media print {
|
||||
:is(.admonition) {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
:is(.admonition) > * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
:is(.admonition) :is(.admonition) {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
:is(.admonition) > .tabbed-set:only-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
html :is(.admonition) > :last-child {
|
||||
margin-bottom: 1.2rem;
|
||||
}
|
||||
|
||||
a.admonition-anchor-link {
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: -1.2rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
a.admonition-anchor-link:link, a.admonition-anchor-link:visited {
|
||||
color: var(--fg);
|
||||
}
|
||||
a.admonition-anchor-link:link:hover, a.admonition-anchor-link:visited:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
a.admonition-anchor-link::before {
|
||||
content: "§";
|
||||
}
|
||||
|
||||
:is(.admonition-title, summary.admonition-title) {
|
||||
position: relative;
|
||||
min-height: 4rem;
|
||||
margin-block: 0;
|
||||
margin-inline: -1.6rem -1.2rem;
|
||||
padding-block: 0.8rem;
|
||||
padding-inline: 4.4rem 1.2rem;
|
||||
font-weight: 700;
|
||||
background-color: rgba(68, 138, 255, 0.1);
|
||||
print-color-adjust: exact;
|
||||
-webkit-print-color-adjust: exact;
|
||||
display: flex;
|
||||
}
|
||||
:is(.admonition-title, summary.admonition-title) p {
|
||||
margin: 0;
|
||||
}
|
||||
html :is(.admonition-title, summary.admonition-title):last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
:is(.admonition-title, summary.admonition-title)::before {
|
||||
position: absolute;
|
||||
top: 0.625em;
|
||||
inset-inline-start: 1.6rem;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
background-color: #448aff;
|
||||
print-color-adjust: exact;
|
||||
-webkit-print-color-adjust: exact;
|
||||
mask-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"></svg>');
|
||||
-webkit-mask-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"></svg>');
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-size: contain;
|
||||
content: "";
|
||||
}
|
||||
:is(.admonition-title, summary.admonition-title):hover a.admonition-anchor-link {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
details.admonition > summary.admonition-title::after {
|
||||
position: absolute;
|
||||
top: 0.625em;
|
||||
inset-inline-end: 1.6rem;
|
||||
height: 2rem;
|
||||
width: 2rem;
|
||||
background-color: currentcolor;
|
||||
mask-image: var(--md-details-icon);
|
||||
-webkit-mask-image: var(--md-details-icon);
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-size: contain;
|
||||
content: "";
|
||||
transform: rotate(0deg);
|
||||
transition: transform 0.25s;
|
||||
}
|
||||
details[open].admonition > summary.admonition-title::after {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
:is(.admonition):is(.admonish-note) {
|
||||
border-color: #448aff;
|
||||
}
|
||||
|
||||
:is(.admonish-note) > :is(.admonition-title, summary.admonition-title) {
|
||||
background-color: rgba(68, 138, 255, 0.1);
|
||||
}
|
||||
:is(.admonish-note) > :is(.admonition-title, summary.admonition-title)::before {
|
||||
background-color: #448aff;
|
||||
mask-image: var(--md-admonition-icon--admonish-note);
|
||||
-webkit-mask-image: var(--md-admonition-icon--admonish-note);
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
:is(.admonition):is(.admonish-abstract, .admonish-summary, .admonish-tldr) {
|
||||
border-color: #00b0ff;
|
||||
}
|
||||
|
||||
:is(.admonish-abstract, .admonish-summary, .admonish-tldr) > :is(.admonition-title, summary.admonition-title) {
|
||||
background-color: rgba(0, 176, 255, 0.1);
|
||||
}
|
||||
:is(.admonish-abstract, .admonish-summary, .admonish-tldr) > :is(.admonition-title, summary.admonition-title)::before {
|
||||
background-color: #00b0ff;
|
||||
mask-image: var(--md-admonition-icon--admonish-abstract);
|
||||
-webkit-mask-image: var(--md-admonition-icon--admonish-abstract);
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
:is(.admonition):is(.admonish-info, .admonish-todo) {
|
||||
border-color: #00b8d4;
|
||||
}
|
||||
|
||||
:is(.admonish-info, .admonish-todo) > :is(.admonition-title, summary.admonition-title) {
|
||||
background-color: rgba(0, 184, 212, 0.1);
|
||||
}
|
||||
:is(.admonish-info, .admonish-todo) > :is(.admonition-title, summary.admonition-title)::before {
|
||||
background-color: #00b8d4;
|
||||
mask-image: var(--md-admonition-icon--admonish-info);
|
||||
-webkit-mask-image: var(--md-admonition-icon--admonish-info);
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
:is(.admonition):is(.admonish-tip, .admonish-hint, .admonish-important) {
|
||||
border-color: #00bfa5;
|
||||
}
|
||||
|
||||
:is(.admonish-tip, .admonish-hint, .admonish-important) > :is(.admonition-title, summary.admonition-title) {
|
||||
background-color: rgba(0, 191, 165, 0.1);
|
||||
}
|
||||
:is(.admonish-tip, .admonish-hint, .admonish-important) > :is(.admonition-title, summary.admonition-title)::before {
|
||||
background-color: #00bfa5;
|
||||
mask-image: var(--md-admonition-icon--admonish-tip);
|
||||
-webkit-mask-image: var(--md-admonition-icon--admonish-tip);
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
:is(.admonition):is(.admonish-success, .admonish-check, .admonish-done) {
|
||||
border-color: #00c853;
|
||||
}
|
||||
|
||||
:is(.admonish-success, .admonish-check, .admonish-done) > :is(.admonition-title, summary.admonition-title) {
|
||||
background-color: rgba(0, 200, 83, 0.1);
|
||||
}
|
||||
:is(.admonish-success, .admonish-check, .admonish-done) > :is(.admonition-title, summary.admonition-title)::before {
|
||||
background-color: #00c853;
|
||||
mask-image: var(--md-admonition-icon--admonish-success);
|
||||
-webkit-mask-image: var(--md-admonition-icon--admonish-success);
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
:is(.admonition):is(.admonish-question, .admonish-help, .admonish-faq) {
|
||||
border-color: #64dd17;
|
||||
}
|
||||
|
||||
:is(.admonish-question, .admonish-help, .admonish-faq) > :is(.admonition-title, summary.admonition-title) {
|
||||
background-color: rgba(100, 221, 23, 0.1);
|
||||
}
|
||||
:is(.admonish-question, .admonish-help, .admonish-faq) > :is(.admonition-title, summary.admonition-title)::before {
|
||||
background-color: #64dd17;
|
||||
mask-image: var(--md-admonition-icon--admonish-question);
|
||||
-webkit-mask-image: var(--md-admonition-icon--admonish-question);
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
:is(.admonition):is(.admonish-warning, .admonish-caution, .admonish-attention) {
|
||||
border-color: #ff9100;
|
||||
}
|
||||
|
||||
:is(.admonish-warning, .admonish-caution, .admonish-attention) > :is(.admonition-title, summary.admonition-title) {
|
||||
background-color: rgba(255, 145, 0, 0.1);
|
||||
}
|
||||
:is(.admonish-warning, .admonish-caution, .admonish-attention) > :is(.admonition-title, summary.admonition-title)::before {
|
||||
background-color: #ff9100;
|
||||
mask-image: var(--md-admonition-icon--admonish-warning);
|
||||
-webkit-mask-image: var(--md-admonition-icon--admonish-warning);
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
:is(.admonition):is(.admonish-failure, .admonish-fail, .admonish-missing) {
|
||||
border-color: #ff5252;
|
||||
}
|
||||
|
||||
:is(.admonish-failure, .admonish-fail, .admonish-missing) > :is(.admonition-title, summary.admonition-title) {
|
||||
background-color: rgba(255, 82, 82, 0.1);
|
||||
}
|
||||
:is(.admonish-failure, .admonish-fail, .admonish-missing) > :is(.admonition-title, summary.admonition-title)::before {
|
||||
background-color: #ff5252;
|
||||
mask-image: var(--md-admonition-icon--admonish-failure);
|
||||
-webkit-mask-image: var(--md-admonition-icon--admonish-failure);
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
:is(.admonition):is(.admonish-danger, .admonish-error) {
|
||||
border-color: #ff1744;
|
||||
}
|
||||
|
||||
:is(.admonish-danger, .admonish-error) > :is(.admonition-title, summary.admonition-title) {
|
||||
background-color: rgba(255, 23, 68, 0.1);
|
||||
}
|
||||
:is(.admonish-danger, .admonish-error) > :is(.admonition-title, summary.admonition-title)::before {
|
||||
background-color: #ff1744;
|
||||
mask-image: var(--md-admonition-icon--admonish-danger);
|
||||
-webkit-mask-image: var(--md-admonition-icon--admonish-danger);
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
:is(.admonition):is(.admonish-bug) {
|
||||
border-color: #f50057;
|
||||
}
|
||||
|
||||
:is(.admonish-bug) > :is(.admonition-title, summary.admonition-title) {
|
||||
background-color: rgba(245, 0, 87, 0.1);
|
||||
}
|
||||
:is(.admonish-bug) > :is(.admonition-title, summary.admonition-title)::before {
|
||||
background-color: #f50057;
|
||||
mask-image: var(--md-admonition-icon--admonish-bug);
|
||||
-webkit-mask-image: var(--md-admonition-icon--admonish-bug);
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
:is(.admonition):is(.admonish-example) {
|
||||
border-color: #7c4dff;
|
||||
}
|
||||
|
||||
:is(.admonish-example) > :is(.admonition-title, summary.admonition-title) {
|
||||
background-color: rgba(124, 77, 255, 0.1);
|
||||
}
|
||||
:is(.admonish-example) > :is(.admonition-title, summary.admonition-title)::before {
|
||||
background-color: #7c4dff;
|
||||
mask-image: var(--md-admonition-icon--admonish-example);
|
||||
-webkit-mask-image: var(--md-admonition-icon--admonish-example);
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
:is(.admonition):is(.admonish-quote, .admonish-cite) {
|
||||
border-color: #9e9e9e;
|
||||
}
|
||||
|
||||
:is(.admonish-quote, .admonish-cite) > :is(.admonition-title, summary.admonition-title) {
|
||||
background-color: rgba(158, 158, 158, 0.1);
|
||||
}
|
||||
:is(.admonish-quote, .admonish-cite) > :is(.admonition-title, summary.admonition-title)::before {
|
||||
background-color: #9e9e9e;
|
||||
mask-image: var(--md-admonition-icon--admonish-quote);
|
||||
-webkit-mask-image: var(--md-admonition-icon--admonish-quote);
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.navy :is(.admonition) {
|
||||
background-color: var(--sidebar-bg);
|
||||
}
|
||||
|
||||
.ayu :is(.admonition),
|
||||
.coal :is(.admonition) {
|
||||
background-color: var(--theme-hover);
|
||||
}
|
||||
|
||||
.rust :is(.admonition) {
|
||||
background-color: var(--sidebar-bg);
|
||||
color: var(--sidebar-fg);
|
||||
}
|
||||
.rust .admonition-anchor-link:link, .rust .admonition-anchor-link:visited {
|
||||
color: var(--sidebar-fg);
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/">
|
||||
<link rel="canonical" href="https://book.leptos.dev/">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/15_global_state.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/15_global_state.html">
|
||||
@@ -1,56 +0,0 @@
|
||||
# Summary
|
||||
|
||||
- [Introduction](./01_introduction.md)
|
||||
- [Getting Started](./getting_started/README.md)
|
||||
- [Leptos DX](./getting_started/leptos_dx.md)
|
||||
- [The Leptos Community and leptos-* Crates](./getting_started/community_crates.md)
|
||||
- [Part 1: Building User Interfaces](./view/README.md)
|
||||
- [A Basic Component](./view/01_basic_component.md)
|
||||
- [Dynamic Attributes](./view/02_dynamic_attributes.md)
|
||||
- [Components and Props](./view/03_components.md)
|
||||
- [Iteration](./view/04_iteration.md)
|
||||
- [Iterating over More Complex Data](./view/04b_iteration.md)
|
||||
- [Forms and Inputs](./view/05_forms.md)
|
||||
- [Control Flow](./view/06_control_flow.md)
|
||||
- [Error Handling](./view/07_errors.md)
|
||||
- [Parent-Child Communication](./view/08_parent_child.md)
|
||||
- [Passing Children to Components](./view/09_component_children.md)
|
||||
- [No Macros: The View Builder Syntax](./view/builder.md)
|
||||
- [Reactivity](./reactivity/README.md)
|
||||
- [Working with Signals](./reactivity/working_with_signals.md)
|
||||
- [Responding to Changes with `create_effect`](./reactivity/14_create_effect.md)
|
||||
- [Interlude: Reactivity and Functions](./reactivity/interlude_functions.md)
|
||||
- [Testing](./testing.md)
|
||||
- [Async](./async/README.md)
|
||||
- [Loading Data with Resources](./async/10_resources.md)
|
||||
- [Suspense](./async/11_suspense.md)
|
||||
- [Transition](./async/12_transition.md)
|
||||
- [Actions](./async/13_actions.md)
|
||||
- [Interlude: Projecting Children](./interlude_projecting_children.md)
|
||||
- [Global State Management](./15_global_state.md)
|
||||
- [Router](./router/README.md)
|
||||
- [Defining `<Routes/>`](./router/16_routes.md)
|
||||
- [Nested Routing](./router/17_nested_routing.md)
|
||||
- [Params and Queries](./router/18_params_and_queries.md)
|
||||
- [`<A/>`](./router/19_a.md)
|
||||
- [`<Form/>`](./router/20_form.md)
|
||||
- [Interlude: Styling](./interlude_styling.md)
|
||||
- [Metadata](./metadata.md)
|
||||
- [Client-Side Rendering: Wrapping Up](./csr_wrapping_up.md)
|
||||
- [Part 2: Server Side Rendering](./ssr/README.md)
|
||||
- [`cargo-leptos`](./ssr/21_cargo_leptos.md)
|
||||
- [The Life of a Page Load](./ssr/22_life_cycle.md)
|
||||
- [Async Rendering and SSR “Modes”](./ssr/23_ssr_modes.md)
|
||||
- [Hydration Bugs](./ssr/24_hydration_bugs.md)
|
||||
- [Working with the Server](./server/README.md)
|
||||
- [Server Functions](./server/25_server_functions.md)
|
||||
- [Extractors](./server/26_extractors.md)
|
||||
- [Responses and Redirects](./server/27_response.md)
|
||||
- [Progressive Enhancement and Graceful Degradation](./progressive_enhancement/README.md)
|
||||
- [`<ActionForm/>`s](./progressive_enhancement/action_form.md)
|
||||
- [Deployment](./deployment/README.md)
|
||||
- [Optimizing WASM Binary Size](./deployment/binary_size.md)
|
||||
- [Guide: Islands](./islands.md)
|
||||
|
||||
- [Appendix: How Does the Reactive System Work?](./appendix_reactive_graph.md)
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/appendix_reactive_graph.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/appendix_reactive_graph.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/async/10_resources.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/async/10_resources.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/async/11_suspense.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/async/11_suspense.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/async/12_transition.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/async/12_transition.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/async/13_action.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/async/13_action.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/async/index.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/async/index.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/csr_wrapping_up.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/csr_wrapping_up.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/deployment/index.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/deployment/index.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/deployment/binary_size.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/deployment/binary_size.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/getting_started/index.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/getting_started/index.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/getting_started/community_crates.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/getting_started/community_crates.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/getting_started/leptos_dx.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/getting_started/leptos_dx.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/interlude_projecting_children.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/interlude_projecting_children.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/interlude_styling.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/interlude_styling.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/islands.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/islands.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/metadata.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/metadata.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/progressive_enhancement/index.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/progressive_enhancement/index.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/progressive_enhancement/action_form.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/progressive_enhancement/action_form.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/reactivity/14_create_effect.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/reactivity/14_create_effect.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/reactivity/index.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/reactivity/index.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/reactivity/interlude_functions.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/reactivity/interlude_functions.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/reactivity/working_with_signals.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/reactivity/working_with_signals.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/router/16_routes.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/router/16_routes.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/router/17_nested_routing.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/router/17_nested_routing.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/router/18_params_and_queries.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/router/18_params_and_queries.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/router/19_a.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/router/19_a.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/router/20_form.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/router/20_form.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/router/index.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/router/index.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/server/25_server_functions.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/server/25_server_functions.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/server/26_extractors.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/server/26_extractors.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/server/27_response.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/server/27_response.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/server/index.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/server/index.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/ssr/21_cargo_leptos.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/ssr/21_cargo_leptos.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/ssr/22_life_cycle.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/ssr/22_life_cycle.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/ssr/23_ssr_modes.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/ssr/23_ssr_modes.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/ssr/24_hydration_bugs.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/ssr/24_hydration_bugs.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/ssr/index.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/ssr/index.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/testing.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/testing.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/view/01_basic_component.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/view/01_basic_component.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/view/02_dynamic_attributes.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/view/02_dynamic_attributes.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/view/03_components.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/view/03_components.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/view/04_iteration.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/view/04_iteration.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/view/04b_iteration.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/view/04b_iteration.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/view/05_forms.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/view/05_forms.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/view/06_control_flow.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/view/06_control_flow.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/view/07_errors.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/view/07_errors.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/view/08_parent_child.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/view/08_parent_child.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/view/09_component_children.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/view/09_component_children.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/view/index.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/view/index.html">
|
||||
@@ -1,2 +0,0 @@
|
||||
<meta http-equiv="refresh" content="0; URL=https://book.leptos.dev/view/builder.html">
|
||||
<link rel="canonical" href="https://book.leptos.dev/view/builder.html">
|
||||
@@ -48,28 +48,6 @@ use leptos_reactive::{provide_context, run_as_child, signal_prelude::*};
|
||||
/// {move || {
|
||||
/// /* etc. */
|
||||
/// ```
|
||||
///
|
||||
/// ## Beginner's Tip: ErrorBoundary Requires Your Error To Implement std::error::Error.
|
||||
/// `ErrorBoundary` requires your `Result<T,E>` to implement [IntoView](https://docs.rs/leptos/latest/leptos/trait.IntoView.html).
|
||||
/// `Result<T,E>` only implements `IntoView` if `E` implements [std::error::Error](https://doc.rust-lang.org/std/error/trait.Error.html).
|
||||
/// So, for instance, if you pass a `Result<T,String>` where `T` implements [IntoView](https://docs.rs/leptos/latest/leptos/trait.IntoView.html)
|
||||
/// and attempt to render the error for the purposes of `ErrorBoundary` you'll get a compiler error like this.
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// error[E0599]: the method `into_view` exists for enum `Result<ViewableLoginFlow, String>`, but its trait bounds were not satisfied
|
||||
/// --> src/login.rs:229:32
|
||||
/// |
|
||||
/// 229 | err => err.into_view(),
|
||||
/// | ^^^^^^^^^ method cannot be called on `Result<ViewableLoginFlow, String>` due to unsatisfied trait bounds
|
||||
/// |
|
||||
/// = note: the following trait bounds were not satisfied:
|
||||
/// `<&Result<ViewableLoginFlow, std::string::String> as FnOnce<()>>::Output = _`
|
||||
/// which is required by `&Result<ViewableLoginFlow, std::string::String>: leptos::IntoView`
|
||||
/// ... more notes here ...
|
||||
/// ```
|
||||
///
|
||||
/// For more information about how to easily implement `Error` see
|
||||
/// [thiserror](https://docs.rs/thiserror/latest/thiserror/)
|
||||
#[component]
|
||||
pub fn ErrorBoundary<F, IV>(
|
||||
/// The components inside the tag which will get rendered
|
||||
|
||||
@@ -251,7 +251,7 @@ where
|
||||
|
||||
impl IntoView for TextProp {
|
||||
fn into_view(self) -> View {
|
||||
(move || self.get()).into_view()
|
||||
self.get().into_view()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ impl IntoAttribute for Option<Box<dyn IntoAttribute>> {
|
||||
|
||||
impl IntoAttribute for TextProp {
|
||||
fn into_attribute(self) -> Attribute {
|
||||
(move || self.get()).into_attribute()
|
||||
self.get().into_attribute()
|
||||
}
|
||||
|
||||
impl_into_attr_boxed! {}
|
||||
|
||||
@@ -11,13 +11,13 @@ dependencies = [
|
||||
[tasks.test-leptos_macro-example]
|
||||
description = "Tests the leptos_macro/example to check if macro handles doc comments correctly"
|
||||
command = "cargo"
|
||||
args = ["+nightly-2024-04-14", "test", "--doc"]
|
||||
args = ["+nightly-2024-03-31", "test", "--doc"]
|
||||
cwd = "example"
|
||||
install_crate = false
|
||||
|
||||
[tasks.doc-leptos_macro-example]
|
||||
description = "Docs the leptos_macro/example to check if macro handles doc comments correctly"
|
||||
command = "cargo"
|
||||
args = ["+nightly-2024-04-14", "doc"]
|
||||
args = ["+nightly-2024-03-31", "doc"]
|
||||
cwd = "example"
|
||||
install_crate = false
|
||||
|
||||
@@ -365,33 +365,6 @@ impl ToTokens for Model {
|
||||
})
|
||||
.collect::<TokenStream>();
|
||||
|
||||
let dyn_binding_props = props
|
||||
.iter()
|
||||
.filter(
|
||||
|Prop {
|
||||
prop_opts: PropOpt { attrs, .. },
|
||||
..
|
||||
}| *attrs,
|
||||
)
|
||||
.filter_map(
|
||||
|Prop {
|
||||
name,
|
||||
prop_opts: PropOpt { attrs, .. },
|
||||
..
|
||||
}| {
|
||||
let ident = &name.ident;
|
||||
|
||||
if *attrs {
|
||||
Some(quote! {
|
||||
::leptos::leptos_dom::html::Binding::Attribute { name, value } => self.#ident.push((name, value)),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
)
|
||||
.collect::<TokenStream>();
|
||||
|
||||
let body = quote! {
|
||||
#destructure_props
|
||||
#tracing_span_expr
|
||||
@@ -531,21 +504,6 @@ impl ToTokens for Model {
|
||||
}
|
||||
}
|
||||
|
||||
impl #impl_generics #props_name #generics #where_clause {
|
||||
fn dyn_bindings<B: Into<::leptos::leptos_dom::html::Binding>>(mut self, bindings: impl std::iter::IntoIterator<Item = B>) -> Self {
|
||||
for binding in bindings.into_iter() {
|
||||
let binding: ::leptos::leptos_dom::html::Binding = binding.into();
|
||||
|
||||
match binding {
|
||||
#dyn_binding_props
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#into_view
|
||||
|
||||
#docs
|
||||
|
||||
@@ -489,7 +489,7 @@ pub fn template(tokens: TokenStream) -> TokenStream {
|
||||
/// use leptos::html::Div;
|
||||
///
|
||||
/// #[component]
|
||||
/// fn MyComponent(render_prop: impl Fn() -> HtmlElement<Div>) -> impl IntoView {
|
||||
/// fn MyComponent<T: Fn() -> HtmlElement<Div>>(render_prop: impl Fn() -> HtmlElement<Div>) -> impl IntoView {
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
|
||||
@@ -27,30 +27,6 @@ pub(crate) fn component_to_tokens(
|
||||
}
|
||||
});
|
||||
|
||||
let spread_bindings = node.attributes().iter().filter_map(|node| {
|
||||
use rstml::node::NodeBlock;
|
||||
use syn::{Expr, ExprRange, RangeLimits, Stmt};
|
||||
|
||||
if let NodeAttribute::Block(NodeBlock::ValidBlock(block)) = node {
|
||||
match block.stmts.first()? {
|
||||
Stmt::Expr(
|
||||
Expr::Range(ExprRange {
|
||||
start: None,
|
||||
limits: RangeLimits::HalfOpen(_),
|
||||
end: Some(end),
|
||||
..
|
||||
}),
|
||||
_,
|
||||
) => Some(
|
||||
quote! { .dyn_bindings(#[allow(unused_brace)] {#end}) },
|
||||
),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
let props = attrs
|
||||
.clone()
|
||||
.filter(|attr| {
|
||||
@@ -246,8 +222,7 @@ pub(crate) fn component_to_tokens(
|
||||
#[allow(clippy::let_unit_value, clippy::unit_arg)]
|
||||
let props = props
|
||||
#build
|
||||
#dyn_attrs
|
||||
#(#spread_bindings)*;
|
||||
#dyn_attrs;
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
::leptos::component_view(
|
||||
|
||||
@@ -3,11 +3,7 @@ use convert_case::{Case::Snake, Casing};
|
||||
use proc_macro2::{Ident, Span, TokenStream, TokenTree};
|
||||
use quote::{quote, quote_spanned};
|
||||
use rstml::node::{KeyedAttribute, Node, NodeElement, NodeName};
|
||||
use syn::{
|
||||
spanned::Spanned,
|
||||
Expr::{self, Tuple},
|
||||
ExprArray, ExprLit, ExprPath, Lit,
|
||||
};
|
||||
use syn::{spanned::Spanned, Expr, Expr::Tuple, ExprLit, ExprPath, Lit};
|
||||
|
||||
pub mod client_builder;
|
||||
pub mod client_template;
|
||||
@@ -408,72 +404,27 @@ fn fancy_class_name<'a>(
|
||||
node.key.span()=> .class
|
||||
};
|
||||
let class_name = &tuple.elems[0];
|
||||
let class_name = if let Expr::Lit(ExprLit {
|
||||
lit: Lit::Str(s),
|
||||
..
|
||||
}) = class_name
|
||||
{
|
||||
s.value()
|
||||
} else {
|
||||
proc_macro_error::emit_error!(
|
||||
class_name.span(),
|
||||
"class name must be a string literal"
|
||||
);
|
||||
Default::default()
|
||||
};
|
||||
let value = &tuple.elems[1];
|
||||
|
||||
match class_name {
|
||||
Expr::Lit(ExprLit {
|
||||
lit: Lit::Str(s), ..
|
||||
}) => {
|
||||
let class_name = s.value();
|
||||
return Some((
|
||||
quote! {
|
||||
#class(#class_name, #value)
|
||||
},
|
||||
class_name,
|
||||
value,
|
||||
));
|
||||
}
|
||||
|
||||
Expr::Array(ExprArray { elems, .. }) => {
|
||||
let (tokens, class_name): (Vec<_>, Vec<_>) = elems
|
||||
.iter()
|
||||
.map(|elem| match elem {
|
||||
Expr::Lit(ExprLit {
|
||||
lit: Lit::Str(s), ..
|
||||
}) => {
|
||||
let class_name = s.value();
|
||||
let tokens = quote! {
|
||||
#class(#class_name, #value)
|
||||
};
|
||||
(tokens, class_name)
|
||||
}
|
||||
|
||||
_ => {
|
||||
proc_macro_error::emit_error!(
|
||||
elem.span(),
|
||||
"class name elements must be string \
|
||||
literals"
|
||||
);
|
||||
|
||||
(TokenStream::new(), Default::default())
|
||||
}
|
||||
})
|
||||
.unzip();
|
||||
|
||||
let class_name = class_name.join(" ");
|
||||
return Some((
|
||||
quote! { #(#tokens)*},
|
||||
class_name,
|
||||
value,
|
||||
));
|
||||
}
|
||||
|
||||
_ => {
|
||||
proc_macro_error::emit_error!(
|
||||
class_name.span(),
|
||||
"class name must be a string literal or array of \
|
||||
string literals"
|
||||
);
|
||||
let class_name = Default::default();
|
||||
return Some((
|
||||
quote! {
|
||||
#class(#class_name, #value)
|
||||
},
|
||||
class_name,
|
||||
value,
|
||||
));
|
||||
}
|
||||
}
|
||||
return Some((
|
||||
quote! {
|
||||
#class(#class_name, #value)
|
||||
},
|
||||
class_name,
|
||||
value,
|
||||
));
|
||||
} else {
|
||||
proc_macro_error::emit_error!(
|
||||
tuple.span(),
|
||||
|
||||
@@ -9,7 +9,6 @@ description = "Reactive system for the Leptos web framework."
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
oco_ref = { workspace = true }
|
||||
slotmap = { version = "1", features = ["serde"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde-lite = { version = "0.5", optional = true }
|
||||
|
||||
@@ -95,6 +95,7 @@ mod hydration;
|
||||
pub mod macros;
|
||||
mod memo;
|
||||
mod node;
|
||||
pub mod oco;
|
||||
mod resource;
|
||||
mod runtime;
|
||||
mod selector;
|
||||
@@ -119,7 +120,6 @@ pub use hydration::{FragmentData, SharedContext};
|
||||
pub use memo::*;
|
||||
pub use node::Disposer;
|
||||
pub use oco::*;
|
||||
pub use oco_ref as oco;
|
||||
pub use resource::*;
|
||||
use runtime::*;
|
||||
pub use runtime::{
|
||||
|
||||
@@ -1,37 +1,6 @@
|
||||
//! This module contains the `Oco` (Owned Clones Once) smart pointer,
|
||||
//! which is used to store immutable references to values.
|
||||
//! This is useful for storing, for example, strings.
|
||||
//!
|
||||
//! Imagine this as an alternative to [`Cow`] with an additional, reference-counted
|
||||
//! branch.
|
||||
//!
|
||||
//! ```rust
|
||||
//! use oco_ref::Oco;
|
||||
//! use std::rc::Rc;
|
||||
//!
|
||||
//! let static_str = "foo";
|
||||
//! let rc_str: Rc<str> = "bar".into();
|
||||
//! let owned_str: String = "baz".into();
|
||||
//!
|
||||
//! fn uses_oco(value: impl Into<Oco<'static, str>>) {
|
||||
//! let mut value = value.into();
|
||||
//!
|
||||
//! // ensures that the value is either a reference, or reference-counted
|
||||
//! // O(n) at worst
|
||||
//! let clone1 = value.clone_inplace();
|
||||
//!
|
||||
//! // these subsequent clones are O(1)
|
||||
//! let clone2 = value.clone();
|
||||
//! let clone3 = value.clone();
|
||||
//! }
|
||||
//!
|
||||
//! uses_oco(static_str);
|
||||
//! uses_oco(rc_str);
|
||||
//! uses_oco(owned_str);
|
||||
//! ```
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use std::{
|
||||
@@ -44,24 +13,16 @@ use std::{
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
/// "Owned Clones Once": a smart pointer that can be either a reference,
|
||||
/// an owned value, or a reference-counted pointer. This is useful for
|
||||
/// "Owned Clones Once" - a smart pointer that can be either a reference,
|
||||
/// an owned value, or a reference counted pointer. This is useful for
|
||||
/// storing immutable values, such as strings, in a way that is cheap to
|
||||
/// clone and pass around.
|
||||
///
|
||||
/// The cost of the `Clone` implementation depends on the branch. Cloning the [`Oco::Borrowed`]
|
||||
/// The `Clone` implementation is amortized `O(1)`. Cloning the [`Oco::Borrowed`]
|
||||
/// variant simply copies the references (`O(1)`). Cloning the [`Oco::Counted`]
|
||||
/// variant increments a reference count (`O(1)`). Cloning the [`Oco::Owned`]
|
||||
/// variant requires an `O(n)` clone of the data.
|
||||
///
|
||||
/// For an amortized `O(1)` clone, you can use [`Oco::clone_inplace()`]. Using this method,
|
||||
/// [`Oco::Borrowed`] and [`Oco::Counted`] are still `O(1)`. [`Oco::Owned`] does a single `O(n)`
|
||||
/// clone, but converts the object to the [`Oco::Counted`] branch, which means future clones will
|
||||
/// be `O(1)`.
|
||||
///
|
||||
/// In general, you'll either want to call `clone_inplace()` once, before sharing the `Oco` with
|
||||
/// other parts of your application (so that all future clones are `O(1)`), or simply use this as
|
||||
/// if it is a [`Cow`] with an additional branch for reference-counted values.
|
||||
/// variant upgrades it to [`Oco::Counted`], which requires an `O(n)` clone of the
|
||||
/// data, but all subsequent clones will be `O(1)`.
|
||||
pub enum Oco<'a, T: ?Sized + ToOwned + 'a> {
|
||||
/// A static reference to a value.
|
||||
Borrowed(&'a T),
|
||||
@@ -85,7 +46,7 @@ impl<'a, T: ?Sized + ToOwned> Oco<'a, T> {
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use std::rc::Rc;
|
||||
/// # use oco_ref::Oco;
|
||||
/// # use leptos_reactive::oco::Oco;
|
||||
/// assert!(Oco::<str>::Borrowed("Hello").is_borrowed());
|
||||
/// assert!(!Oco::<str>::Counted(Rc::from("Hello")).is_borrowed());
|
||||
/// assert!(!Oco::<str>::Owned("Hello".to_string()).is_borrowed());
|
||||
@@ -98,7 +59,7 @@ impl<'a, T: ?Sized + ToOwned> Oco<'a, T> {
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use std::rc::Rc;
|
||||
/// # use oco_ref::Oco;
|
||||
/// # use leptos_reactive::oco::Oco;
|
||||
/// assert!(Oco::<str>::Counted(Rc::from("Hello")).is_counted());
|
||||
/// assert!(!Oco::<str>::Borrowed("Hello").is_counted());
|
||||
/// assert!(!Oco::<str>::Owned("Hello".to_string()).is_counted());
|
||||
@@ -111,7 +72,7 @@ impl<'a, T: ?Sized + ToOwned> Oco<'a, T> {
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use std::rc::Rc;
|
||||
/// # use oco_ref::Oco;
|
||||
/// # use leptos_reactive::oco::Oco;
|
||||
/// assert!(Oco::<str>::Owned("Hello".to_string()).is_owned());
|
||||
/// assert!(!Oco::<str>::Borrowed("Hello").is_owned());
|
||||
/// assert!(!Oco::<str>::Counted(Rc::from("Hello")).is_owned());
|
||||
@@ -169,7 +130,7 @@ impl Oco<'_, str> {
|
||||
/// Returns a `&str` slice of this [`Oco`].
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use oco_ref::Oco;
|
||||
/// # use leptos_reactive::oco::Oco;
|
||||
/// let oco = Oco::<str>::Borrowed("Hello");
|
||||
/// let s: &str = oco.as_str();
|
||||
/// assert_eq!(s, "Hello");
|
||||
@@ -184,7 +145,7 @@ impl Oco<'_, CStr> {
|
||||
/// Returns a `&CStr` slice of this [`Oco`].
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use oco_ref::Oco;
|
||||
/// # use leptos_reactive::oco::Oco;
|
||||
/// use std::ffi::CStr;
|
||||
///
|
||||
/// let oco =
|
||||
@@ -202,7 +163,7 @@ impl Oco<'_, OsStr> {
|
||||
/// Returns a `&OsStr` slice of this [`Oco`].
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use oco_ref::Oco;
|
||||
/// # use leptos_reactive::oco::Oco;
|
||||
/// use std::ffi::OsStr;
|
||||
///
|
||||
/// let oco = Oco::<OsStr>::Borrowed(OsStr::new("Hello"));
|
||||
@@ -219,7 +180,7 @@ impl Oco<'_, Path> {
|
||||
/// Returns a `&Path` slice of this [`Oco`].
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use oco_ref::Oco;
|
||||
/// # use leptos_reactive::oco::Oco;
|
||||
/// use std::path::Path;
|
||||
///
|
||||
/// let oco = Oco::<Path>::Borrowed(Path::new("Hello"));
|
||||
@@ -239,7 +200,7 @@ where
|
||||
/// Returns a `&[T]` slice of this [`Oco`].
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use oco_ref::Oco;
|
||||
/// # use leptos_reactive::oco::Oco;
|
||||
/// let oco = Oco::<[u8]>::Borrowed(b"Hello");
|
||||
/// let s: &[u8] = oco.as_slice();
|
||||
/// assert_eq!(s, b"Hello");
|
||||
@@ -261,7 +222,7 @@ where
|
||||
/// # Examples
|
||||
/// [`String`] :
|
||||
/// ```
|
||||
/// # use oco_ref::Oco;
|
||||
/// # use leptos_reactive::oco::Oco;
|
||||
/// let oco = Oco::<str>::Owned("Hello".to_string());
|
||||
/// let oco2 = oco.clone();
|
||||
/// assert_eq!(oco, oco2);
|
||||
@@ -269,7 +230,7 @@ where
|
||||
/// ```
|
||||
/// [`Vec`] :
|
||||
/// ```
|
||||
/// # use oco_ref::Oco;
|
||||
/// # use leptos_reactive::oco::Oco;
|
||||
/// let oco = Oco::<[u8]>::Owned(b"Hello".to_vec());
|
||||
/// let oco2 = oco.clone();
|
||||
/// assert_eq!(oco, oco2);
|
||||
@@ -293,7 +254,7 @@ where
|
||||
/// was previously [`Oco::Owned`].
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use oco_ref::Oco;
|
||||
/// # use leptos_reactive::oco::Oco;
|
||||
/// let mut oco1 = Oco::<str>::Owned("Hello".to_string());
|
||||
/// let oco2 = oco1.clone_inplace();
|
||||
/// assert_eq!(oco1, oco2);
|
||||
@@ -3,7 +3,7 @@ use crate::{
|
||||
Oco, ReadSignal, RwSignal, SignalDispose, SignalGet, SignalGetUntracked,
|
||||
SignalStream, SignalWith, SignalWithUntracked, StoredValue,
|
||||
};
|
||||
use std::{borrow::Cow, fmt::Debug, rc::Rc};
|
||||
use std::{fmt::Debug, rc::Rc};
|
||||
|
||||
/// Helper trait for converting `Fn() -> T` closures into
|
||||
/// [`Signal<T>`].
|
||||
@@ -1345,33 +1345,12 @@ impl From<Oco<'static, str>> for TextProp {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for MaybeProp<TextProp> {
|
||||
fn from(s: String) -> Self {
|
||||
Self(Some(MaybeSignal::from(Some(Oco::from(s).into()))))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Rc<str>> for MaybeProp<TextProp> {
|
||||
fn from(s: Rc<str>) -> Self {
|
||||
Self(Some(MaybeSignal::from(Some(Oco::from(s).into()))))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&'static str> for MaybeProp<TextProp> {
|
||||
fn from(s: &'static str) -> Self {
|
||||
Self(Some(MaybeSignal::from(Some(Oco::from(s).into()))))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<str>> for MaybeProp<TextProp> {
|
||||
fn from(s: Box<str>) -> Self {
|
||||
Self(Some(MaybeSignal::from(Some(Oco::from(s).into()))))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Cow<'static, str>> for MaybeProp<TextProp> {
|
||||
fn from(s: Cow<'static, str>) -> Self {
|
||||
Self(Some(MaybeSignal::from(Some(Oco::from(s).into()))))
|
||||
impl<T> From<T> for MaybeProp<TextProp>
|
||||
where
|
||||
T: Into<Oco<'static, str>>,
|
||||
{
|
||||
fn from(s: T) -> Self {
|
||||
Self(Some(MaybeSignal::from(Some(s.into().into()))))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
[package]
|
||||
name = "oco_ref"
|
||||
edition = "2021"
|
||||
version = "0.1.1"
|
||||
authors = ["Danik Vitek", "Greg Johnston"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/leptos-rs/leptos"
|
||||
description = "A smart pointer for storing immutable values with relatively-cheap cloning. (Like a `Cow` meets an `Rc`!)"
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
serde = "1"
|
||||
thiserror = "1"
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = "1"
|
||||
@@ -1,31 +0,0 @@
|
||||
This module contains the `Oco` (Owned Clones Once) smart pointer,
|
||||
which is used to store immutable references to values.
|
||||
This is useful for storing, for example, strings.
|
||||
|
||||
Imagine this as an alternative to [`Cow`] with an additional, reference-counted
|
||||
branch.
|
||||
|
||||
```rust
|
||||
use oco_ref::Oco;
|
||||
use std::rc::Rc;
|
||||
|
||||
let static_str = "foo";
|
||||
let rc_str: Rc<str> = "bar".into();
|
||||
let owned_str: String = "baz".into();
|
||||
|
||||
fn uses_oco(value: impl Into<Oco<'static, str>>) {
|
||||
let mut value = value.into();
|
||||
|
||||
// ensures that the value is either a reference, or reference-counted
|
||||
// O(n) at worst
|
||||
let clone1 = value.clone_inplace();
|
||||
|
||||
// these subsequent clones are O(1)
|
||||
let clone2 = value.clone();
|
||||
let clone3 = value.clone();
|
||||
}
|
||||
|
||||
uses_oco(static_str);
|
||||
uses_oco(rc_str);
|
||||
uses_oco(owned_str);
|
||||
```
|
||||
@@ -1,7 +0,0 @@
|
||||
# `projects` README
|
||||
|
||||
The `projects` directory is intended as a collective of medium-to-large-scale examples: a place to show a variety of use cases and integrations between Leptos and other libraries. Over time, our hope is that this allows us to showcase a wider variety of user examples, without the main `examples` directory becoming too overwhelming to be useful.
|
||||
|
||||
The `examples` directory is included in our CI, and examples are regularly linted and tested. The barrier to entry for the `projects` directory is intended to be lower: Example projects will generally be built against a particular version, and not regularly linted or updated. Hopefully this distinction allows us to accept more examples without worrying about the maintenance burden of constant updates.
|
||||
|
||||
Feel free to submit projects to this directory via PR!
|
||||
5
projects/meilisearch-searchbar/.gitignore
vendored
5
projects/meilisearch-searchbar/.gitignore
vendored
@@ -1,5 +0,0 @@
|
||||
/target
|
||||
meilisearch
|
||||
data.ms
|
||||
dumps
|
||||
Cargo.lock
|
||||
@@ -1,61 +0,0 @@
|
||||
[package]
|
||||
name = "meilisearch_searchbar"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
leptos = {version = "0.6.5",features = ["nightly"]}
|
||||
leptos_axum = { version = "0.6.5", optional = true}
|
||||
meilisearch-sdk = { version = "0.24.3", optional = true}
|
||||
axum = {version = "0.7.4", optional = true}
|
||||
leptos_meta = {version = "0.6.5",features = ["nightly"]}
|
||||
leptos_router = {version = "0.6.5",features = ["nightly"]}
|
||||
console_log = "1.0.0"
|
||||
console_error_panic_hook = "0.1.7"
|
||||
log = "0.4.20"
|
||||
tower = {verison= "0.4.13", optional=true}
|
||||
tower-http = {version = "0.5.1", optional = true, features = ["fs"]}
|
||||
simple_logger = {version = "4.3.3", optional = true}
|
||||
tokio = { version = "1", features = ["full"], optional = true }
|
||||
lazy_static = { version = "1.4.0", optional = true }
|
||||
serde = "1.0.196"
|
||||
serde_json = "1.0.113"
|
||||
csv = {version = "1.3.0", optional=true}
|
||||
|
||||
[features]
|
||||
default = ["ssr"]
|
||||
hydrate = ["leptos/hydrate","leptos_meta/hydrate","leptos_router/hydrate"]
|
||||
ssr = [
|
||||
"tokio",
|
||||
"lazy_static",
|
||||
"simple_logger",
|
||||
"dep:meilisearch-sdk",
|
||||
"dep:axum",
|
||||
"leptos/ssr",
|
||||
"leptos_meta/ssr",
|
||||
"leptos_router/ssr",
|
||||
"tower",
|
||||
"tower-http",
|
||||
"leptos_axum",
|
||||
"csv",
|
||||
]
|
||||
lazy_static = ["dep:lazy_static"]
|
||||
|
||||
[package.metadata.leptos]
|
||||
output-name = "meilisearch_searchbar"
|
||||
site-root = "target/site"
|
||||
site-pkg-dir = "pkg"
|
||||
assets-dir = "public"
|
||||
site-addr = "127.0.0.1:3000"
|
||||
reload-port = 3001
|
||||
browserquery = "defaults"
|
||||
watch = false
|
||||
env = "DEV"
|
||||
bin-features = ["ssr"]
|
||||
bin-default-features = false
|
||||
lib-features = ["hydrate"]
|
||||
lib-default-features = false
|
||||
@@ -1,4 +0,0 @@
|
||||
[tasks.ci]
|
||||
description = "Continuous Integration task"
|
||||
command = "cargo"
|
||||
args = ["test"]
|
||||
@@ -1,28 +0,0 @@
|
||||
# Meilisearch Searchbar
|
||||
|
||||
This show how to integrate meilisearch with a leptos app, including a search bar and showing the results to the user.
|
||||
<br><br>
|
||||
We'll run meilisearch locally, as opposed to using their cloud service.
|
||||
<br><br>
|
||||
To get started install meilisearch into this example's root.
|
||||
|
||||
```sh
|
||||
curl -L https://install.meilisearch.com | sh
|
||||
```
|
||||
|
||||
Run it.
|
||||
|
||||
```sh
|
||||
./meilisearch
|
||||
```
|
||||
|
||||
Then set the environment variable and serve the app. I've included the address of my own local meilisearch server.
|
||||
I didn't provide a password to meilisearch during my setup, and I didn't provide one in my environment variables either.
|
||||
```sh
|
||||
MEILISEARCH_URL=http://localhost:7700 && cargo leptos serve
|
||||
```
|
||||
|
||||
Navigate to 127.0.0.1:3000 and start typing in popular American company names. (Boeing, Pepsi, etc)
|
||||
|
||||
## Thoughts, Feedback, Criticism, Comments?
|
||||
Send me any of the above, I'm @sjud on leptos discord. I'm always looking to improve and make these projects more helpful for the community. So please let me know how I can do that. Thanks!
|
||||
@@ -1,504 +0,0 @@
|
||||
name,last,high,low,absolute_change,percent_change,vol
|
||||
"Boeing","209.16","211.41","207.91",-0.06,-0.03,4310000
|
||||
"General Motors","38.56","38.97","38.45",-0.09,-0.23,11720000
|
||||
"Chevron","151.02","155.31","150.99",-3.04,-1.97,8040000
|
||||
"Citigroup","53.98","54.44","53.53",-0.31,-0.57,11750000
|
||||
"Bank of America","33.05","33.25","32.83",-0.07,-0.2,30560000
|
||||
"AT&T","16.83","16.88","16.57",0.01,0.06,40000000
|
||||
"Caterpillar","316.89","322.33","315.57",-5.11,-1.59,2780000
|
||||
"Intel","43.31","43.52","42.40",0.81,1.91,43560000
|
||||
"Microsoft","420.55","420.82","415.09",6.44,1.56,21300000
|
||||
"Ford Motor","12.68","12.92","12.64",-0.15,-1.17,44810000
|
||||
"eBay","42.43","42.69","41.79",0.41,0.98,4340000
|
||||
"Walt Disney","108.37","110.14","107.69",-2.17,-1.96,19100000
|
||||
"Dow","53.99","54.12","53.56",0.11,0.2,3730000
|
||||
"Cisco","50.10","50.26","49.63",0.15,0.31,21620000
|
||||
"Deere&Company","381.32","385.30","380.46",-4.51,-1.17,1410000
|
||||
"FedEx","242.59","242.82","240.14",0.84,0.35,1720000
|
||||
"General Mills","62.34","63.86","62.09",-1.73,-2.69,4070000
|
||||
"Corning","32.04","32.05","31.58",0.31,0.98,2760000
|
||||
"Goldman Sachs","384.21","386.13","382.58",-0.83,-0.22,1620000
|
||||
"JPMorgan","174.96","175.10","173.67",0.16,0.09,4270000
|
||||
"Kimberly-Clark","119.81","120.47","119.12",-0.46,-0.38,1570000
|
||||
"Kraft Heinz","35.97","36.38","35.80",-0.5,-1.37,8020000
|
||||
"Coca-Cola","59.56","59.58","59.03",-0.27,-0.45,12020000
|
||||
"McDonald’s","289.41","292.49","288.94",-2.52,-0.86,3140000
|
||||
"Eli Lilly","739.51","745.68","733.61",3.83,0.52,2410000
|
||||
"Oracle","116.60","117.34","115.75",-0.08,-0.07,4990000
|
||||
"Merck&Co","125.43","126.69","125.04",-1.18,-0.93,5890000
|
||||
"Motorola","330.98","333.00","323.23",2.63,0.8,1180000
|
||||
"3M","92.89","93.30","92.39",-0.31,-0.33,3620000
|
||||
"Vertex","422.91","425.96","419.51",-0.15,-0.04,1100000
|
||||
"Monster Beverage","55.66","56.57","55.35",-0.83,-1.47,3760000
|
||||
"Fifth Third","33.65","33.74","33.02",0.26,0.78,4030000
|
||||
"Cintas","618.22","620.32","614.07",1.06,0.17,248630
|
||||
"Autodesk","266.68","269.53","262.85",5.17,1.98,1730000
|
||||
"Gilead","73.67","74.11","72.81",-0.13,-0.18,10150000
|
||||
"Alphabet A","149.00","149.44","146.18",3.09,2.12,26030000
|
||||
"Fiserv","144.23","144.34","142.74",0.68,0.47,1730000
|
||||
"Adobe","627.21","628.07","615.80",11.35,1.84,1950000
|
||||
"Qualcomm","151.00","153.40","148.35",2.82,1.9,11310000
|
||||
"Warner Bros Discovery","9.64","9.89","9.57",-0.19,-1.93,22450000
|
||||
"Applied Materials","185.84","186.15","178.62",11.95,6.87,9240000
|
||||
"Steel Dynamics","124.99","125.66","124.21",0.15,0.12,1120000
|
||||
"Cadence Design","311.94","313.11","308.82",4.58,1.49,1300000
|
||||
"Microchip","85.44","86.00","84.67",1.09,1.29,4750000
|
||||
"Wynn Resorts","105.60","106.89","104.26",-0.51,-0.48,2400000
|
||||
"Intuitive Surgical","388.22","389.92","383.05",1.28,0.33,1100000
|
||||
"Nasdaq Inc","57.25","57.35","56.65",0.49,0.86,1250000
|
||||
"Henry Schein","73.72","75.18","73.43",-1.18,-1.58,1330000
|
||||
"Paychex","123.03","123.25","121.84",0.28,0.23,1680000
|
||||
"VeriSign","198.38","203.00","197.08",-2.64,-1.31,1470000
|
||||
"Apple","188.85","189.99","188.00",0.77,0.41,43180000
|
||||
"Fastenal","70.02","70.06","69.16",0.76,1.1,2610000
|
||||
"Dentsply","32.79","33.16","32.73",-0.37,-1.12,3230000
|
||||
"Zions","40.09","40.41","39.45",0.2,0.5,2070000
|
||||
"Northern Trust","79.64","79.73","78.25",1.17,1.49,1120000
|
||||
"CH Robinson","74.67","74.85","73.59",0.01,0.01,775730
|
||||
"PACCAR","106.01","106.08","104.96",0.4,0.38,1400000
|
||||
"Amazon.com","174.45","175.00","170.58",4.61,2.71,52940000
|
||||
"Ross Stores","145.87","146.42","145.20",-0.19,-0.13,1260000
|
||||
"NetApp","89.85","90.33","88.78",0.93,1.05,1360000
|
||||
"Garmin","123.21","123.70","121.90",0.89,0.73,580350
|
||||
"Costco","723.40","725.53","720.12",-0.76,-0.1,1370000
|
||||
"Lam Research","911.58","913.82","874.86",47.22,5.46,1820000
|
||||
"Intuit","658.16","662.83","654.69",5.09,0.78,923900
|
||||
"Expedia","131.11","132.80","126.05",-28.36,-17.78,18410000
|
||||
"Cognizant A","77.10","78.57","76.87",-1.2,-1.53,5250000
|
||||
"Akamai","128.32","129.16","127.04",1.54,1.21,1690000
|
||||
"KLA Corp","649.80","651.26","628.55",31.31,5.06,1240000
|
||||
"Juniper","37.03","37.06","36.93",0.08,0.22,2540000
|
||||
"Amgen","291.12","295.00","289.72",-3.73,-1.27,3270000
|
||||
"Expeditors Washington","127.39","127.39","125.52",0.21,0.17,837390
|
||||
"Electronic Arts","140.61","140.98","137.00",1.76,1.27,1950000
|
||||
"T Rowe","106.33","109.83","105.90",-2.58,-2.37,2420000
|
||||
"Biogen","240.98","241.36","238.90",0.68,0.28,665370
|
||||
"Charles Schwab","63.37","63.41","62.35",0.9,1.44,4530000
|
||||
"Huntington Bancshares","12.41","12.48","12.19",0.09,0.73,13750000
|
||||
"Gen Digital","21.35","21.39","20.94",0.48,2.3,5700000
|
||||
"NVIDIA","721.33","721.85","702.12",24.92,3.58,42810000
|
||||
"Starbucks","97.30","97.99","96.31",0.71,0.74,9300000
|
||||
"Cincinnati Financial","108.89","109.48","107.12",1.29,1.2,610810
|
||||
"Axon Enterprise","270.98","271.39","268.44",1.98,0.74,191750
|
||||
"Hologic","73.44","74.14","73.09",0.01,0.01,1460000
|
||||
"Comcast","42.07","42.28","41.22",0.82,1.99,26670000
|
||||
"Medtronic","84.97","86.15","84.46",-1.21,-1.4,7820000
|
||||
"Dover","160.46","160.93","159.36",0.35,0.22,999650
|
||||
"Northrop Grumman","454.99","455.56","450.52",3.77,0.84,752290
|
||||
"MGM","46.74","46.86","46.21",0.31,0.67,3840000
|
||||
"Mastercard","457.74","458.98","456.37",-0.52,-0.11,2050000
|
||||
"General Dynamics","270.19","271.36","269.05",1.19,0.44,728860
|
||||
"DTE Energy","104.43","104.67","103.14",0.2,0.19,885020
|
||||
"Analog Devices","195.02","195.53","193.45",0.96,0.49,3150000
|
||||
"VF","15.30","15.50","15.04",-0.05,-0.33,7200000
|
||||
"Cardinal Health","104.94","105.42","103.28",2.2,2.15,1990000
|
||||
"Xcel Energy","58.17","58.20","57.67",0.17,0.29,2320000
|
||||
"DR Horton","144.93","145.31","142.95",0.34,0.24,1400000
|
||||
"IPG","30.76","31.71","30.60",-1.04,-3.27,6450000
|
||||
"Lockheed Martin","426.42","428.00","424.47",-0.58,-0.14,887810
|
||||
"Waters","322.90","327.57","320.82",-3.79,-1.16,397410
|
||||
"Accenture","371.63","372.48","367.95",3.15,0.85,1420000
|
||||
"Dominion Energy","44.70","44.72","43.92",0.52,1.18,2710000
|
||||
"Exxon Mobil","101.75","104.84","101.70",-2.22,-2.14,16690000
|
||||
"Cigna","334.85","335.83","330.67",2.56,0.77,1300000
|
||||
"Public Service Enterprise","58.41","58.62","57.83",0.21,0.36,1360000
|
||||
"NiSource","25.24","25.26","24.96",0.18,0.72,2330000
|
||||
"Zimmer Biomet","122.78","125.31","121.19",-0.26,-0.21,3110000
|
||||
"CSX","36.89","37.22","36.74",-0.18,-0.49,7940000
|
||||
"ICE","135.52","135.69","132.92",1.4,1.04,3850000
|
||||
"Southwest Airlines","32.50","32.64","31.80",0.17,0.53,8060000
|
||||
"Illinois Tool Works","255.71","255.77","253.63",1.2,0.47,655100
|
||||
"Darden Restaurants","167.65","168.34","167.16",-0.53,-0.32,549580
|
||||
"Truist Financial Corp","35.83","36.07","34.88",0.32,0.9,9970000
|
||||
"Halliburton","34.50","35.15","34.43",-0.53,-1.51,4550000
|
||||
"Prologis","132.45","132.77","130.45",0.79,0.6,2780000
|
||||
"McCormick&Co","64.64","65.94","64.33",-1.18,-1.79,1390000
|
||||
"Host Hotels Resorts","19.58","19.62","19.32",0.03,0.15,4010000
|
||||
"Estee Lauder","143.33","145.23","140.61",2.56,1.82,2340000
|
||||
"International Paper","35.26","35.32","34.63",0.37,1.06,3130000
|
||||
"Emerson","103.19","103.32","102.04",0.81,0.79,3340000
|
||||
"Clorox","153.12","155.46","152.44",-1.1,-0.71,753850
|
||||
"ConocoPhillips","111.11","114.26","111.02",-2.79,-2.45,5070000
|
||||
"Colgate-Palmolive","83.46","84.26","83.18",-0.8,-0.95,3460000
|
||||
"Pinnacle West","67.02","67.02","66.18",0.63,0.95,944540
|
||||
"Regions Financial","17.99","18.10","17.72",0.1,0.56,9480000
|
||||
"CenterPoint Energy","27.53","27.60","27.30",0.1,0.36,2090000
|
||||
"MetLife","67.49","67.67","66.40",0.74,1.11,4590000
|
||||
"Exelon","33.84","33.90","33.35",0.09,0.27,6090000
|
||||
"Baxter","39.55","40.52","38.79",-0.9,-2.24,4580000
|
||||
"Occidental","57.46","58.34","57.24",-0.59,-1.02,7450000
|
||||
"Southern","66.91","67.20","66.50",-0.03,-0.04,3250000
|
||||
"Tapestry","42.01","42.80","41.27",-0.98,-2.28,6310000
|
||||
"Lennar","153.03","153.80","151.32",-0.26,-0.17,1370000
|
||||
"Campbell Soup","42.00","42.91","41.72",-1.1,-2.55,2910000
|
||||
"State Street","72.81","72.98","72.11",0.43,0.59,1270000
|
||||
"Progressive","182.52","184.00","182.30",-0.44,-0.24,1710000
|
||||
"Vulcan Materials","240.05","240.10","237.40",1.61,0.68,1020000
|
||||
"Parker-Hannifin","521.42","521.50","513.99",5.91,1.15,472760
|
||||
"Genuine Parts","143.21","143.21","141.43",0.9,0.63,742180
|
||||
"CBRE A","86.54","86.64","84.77",0.58,0.67,1230000
|
||||
"DuPont De Nemours","67.66","67.72","66.57",0.56,0.83,3220000
|
||||
"Sherwin-Williams","311.77","312.99","309.39",-0.38,-0.12,885490
|
||||
"Pfizer","27.55","27.59","27.38",-0.01,-0.05,24950000
|
||||
"Wells Fargo&Co","48.05","48.35","47.47",-0.3,-0.62,13910000
|
||||
"Walmart","169.27","169.73","168.92",-0.1,-0.06,3930000
|
||||
"Edison","64.69","64.96","64.34",-0.03,-0.05,1470000
|
||||
"Snap-On","262.24","268.14","261.30",-3.79,-1.42,459630
|
||||
"Equifax","249.23","253.48","246.07",-2.83,-1.12,828980
|
||||
"McKesson","501.35","504.31","494.50",7.12,1.44,1030000
|
||||
"Entergy","97.94","98.02","96.80",0.54,0.55,917720
|
||||
"CMS Energy","56.06","56.11","55.61",0.31,0.55,1290000
|
||||
"Ameriprise Financial","396.45","398.15","392.95",1.62,0.41,235380
|
||||
"AIG","69.11","69.23","68.06",0.7,1.03,3020000
|
||||
"Ralph Lauren A","175.04","175.40","169.60",3.19,1.86,1730000
|
||||
"Bath & Body Works","44.74","44.78","43.79",0.37,0.83,1500000
|
||||
"IFF","79.93","80.30","78.72",-0.58,-0.72,3130000
|
||||
"WW Grainger","959.38","961.91","946.13",11.31,1.19,194930
|
||||
"Constellation Brands A","242.37","244.51","241.65",-0.68,-0.28,1170000
|
||||
"American Tower","194.41","194.49","191.64",0.77,0.4,1710000
|
||||
"Philip Morris","89.12","89.43","88.55",0.11,0.12,4300000
|
||||
"Fidelity National Info","61.78","62.11","61.40",0.34,0.55,2680000
|
||||
"Altria","40.10","40.15","39.88",0.01,0.02,8110000
|
||||
"Ball","59.16","59.26","58.21",0.02,0.03,1350000
|
||||
"Hartford","90.80","90.91","89.31",1.07,1.19,1510000
|
||||
"Hershey Co","195.39","201.79","194.68",-6.92,-3.42,2950000
|
||||
"Morgan Stanley","85.88","86.03","85.32",0.23,0.27,4620000
|
||||
"PNC Financial","147.76","148.38","146.68",-0.17,-0.11,1120000
|
||||
"Waste Management","188.87","189.78","187.56",-0.62,-0.33,1570000
|
||||
"Cencora Inc","230.69","231.60","228.77",0.37,0.16,1370000
|
||||
"Assurant","174.48","175.06","171.86",-0.09,-0.05,220360
|
||||
"Kroger","45.41","45.54","45.10",-0.03,-0.07,3120000
|
||||
"Molson Coors Brewing B","60.23","60.24","59.37",-0.04,-0.06,2060000
|
||||
"Home Depot","363.09","364.43","360.80",-0.63,-0.17,1760000
|
||||
"Becton Dickinson","243.66","244.05","240.37",2.95,1.23,2040000
|
||||
"JM Smucker","127.90","130.43","127.67",-3.19,-2.43,894090
|
||||
"Best Buy","75.58","75.68","74.76",0.09,0.12,1410000
|
||||
"Archer-Daniels-Midland","53.07","53.26","52.34",0.37,0.7,4250000
|
||||
"Brown Forman","56.59","56.94","56.31",-0.34,-0.6,847500
|
||||
"IBM","186.33","187.18","183.86",1.97,1.07,4970000
|
||||
"Union Pacific","249.45","249.55","246.51",0.63,0.25,1860000
|
||||
"Micron","85.56","85.62","83.96",0.68,0.8,12070000
|
||||
"Avery Dennison","204.92","205.15","202.01",1.95,0.96,409860
|
||||
"Marathon Oil","22.45","22.87","22.37",-0.25,-1.1,8040000
|
||||
"CF Industries","78.08","78.51","76.67",1.57,2.05,1780000
|
||||
"APA Corp","29.87","30.69","29.80",-0.6,-1.97,5240000
|
||||
"Duke Energy","91.69","92.72","91.63",-0.96,-1.04,3900000
|
||||
"KeyCorp","13.88","13.97","13.64",0.01,0.11,13200000
|
||||
"Laboratory America","222.58","223.60","222.18",-0.22,-0.1,376300
|
||||
"Boston Properties","64.18","65.36","63.60",-0.89,-1.37,1240000
|
||||
"Western Digital","56.82","57.35","56.25",-0.3,-0.53,5200000
|
||||
"PPG Industries","139.58","139.61","137.46",0.95,0.69,949590
|
||||
"S&P Global","438.02","441.04","431.33",1.39,0.32,1770000
|
||||
"Williams","34.03","34.26","33.85",-0.01,-0.01,5830000
|
||||
"Elevance Health","506.07","506.82","500.18",3.92,0.78,700780
|
||||
"Jacobs Engineering","145.54","145.54","143.12",2.37,1.66,737440
|
||||
"Eastman Chemical","82.32","82.83","81.90",-0.67,-0.81,622510
|
||||
"Verizon","39.72","40.09","39.26",-0.19,-0.49,15090000
|
||||
"Nucor","186.52","187.10","185.18",0.23,0.12,1170000
|
||||
"Omnicom","84.58","87.09","84.45",-2.05,-2.37,1550000
|
||||
"AvalonBay","174.62","174.63","173.20",0.09,0.05,573430
|
||||
"Marriott Int","247.02","250.75","245.45",-2.56,-1.03,1370000
|
||||
"Ingersoll Rand","85.89","86.51","85.27",0.51,0.6,3670000
|
||||
"Bristol-Myers Squibb","49.80","49.83","48.49",1.09,2.24,13400000
|
||||
"American Electric Power","76.66","76.73","75.57",0.72,0.95,2010000
|
||||
"Thermo Fisher Scientific","550.82","554.13","548.29",-0.07,-0.01,1160000
|
||||
"Newmont Goldcorp","32.79","33.22","32.54",-0.55,-1.65,10450000
|
||||
"Public Storage","284.04","286.34","280.59",-0.86,-0.3,544300
|
||||
"Travelers","214.50","214.99","212.04",0.69,0.32,793950
|
||||
"Stanley Black Decker","88.93","89.45","88.56",-0.34,-0.38,778810
|
||||
"Franklin Resources","27.09","27.12","26.58",0.26,0.97,2210000
|
||||
"Humana","370.16","371.16","366.30",2.36,0.64,1110000
|
||||
"Paramount Global B","12.90","13.17","12.84",-0.11,-0.85,9380000
|
||||
"Chubb","247.20","247.26","243.32",2.86,1.17,1370000
|
||||
"J&J","156.74","157.20","155.71",0.34,0.22,6280000
|
||||
"Tyson Foods","52.58","53.83","52.15",-1.39,-2.58,3100000
|
||||
"Target","146.51","147.57","146.32",-0.89,-0.6,2750000
|
||||
"Jabil Circuit","139.72","140.26","136.05",3.8,2.79,1270000
|
||||
"American Express","212.40","214.24","210.42",1.19,0.56,4100000
|
||||
"Masco","72.61","74.20","72.17",-0.71,-0.97,3640000
|
||||
"Stryker","341.85","344.33","337.63",2.82,0.83,1370000
|
||||
"Discover","109.19","109.44","108.03",0.35,0.32,1050000
|
||||
"Prudential Financial","105.58","107.65","105.00",-3.03,-2.79,2000000
|
||||
"Abbott Labs","111.78","112.63","111.19",-0.65,-0.58,5560000
|
||||
"General Electric","139.27","139.42","138.21",0.22,0.16,2900000
|
||||
"Quest Diagnostics","126.73","127.60","125.92",0.19,0.15,473100
|
||||
"United Parcel Service","146.20","147.83","145.91",-1.72,-1.16,2280000
|
||||
"CVS Health Corp","76.32","76.35","74.46",1.24,1.65,7350000
|
||||
"PPL","25.87","25.89","25.54",0.21,0.82,5330000
|
||||
"Robert Half","81.15","81.62","80.07",0.6,0.74,1010000
|
||||
"Simon Property","146.94","147.37","144.06",2.84,1.97,1790000
|
||||
"Johnson Controls","55.51","55.72","55.10",0.4,0.72,4240000
|
||||
"Cummins","251.84","251.91","248.73",1.92,0.77,572600
|
||||
"Allstate","160.06","160.59","158.53",-1.69,-1.04,1280000
|
||||
"Sempra Energy","69.67","70.03","69.28",-0.17,-0.24,1220000
|
||||
"Devon Energy","41.59","42.58","41.35",-0.82,-1.93,7220000
|
||||
"Conagra Brands","27.39","27.99","27.08",-0.7,-2.51,5110000
|
||||
"TJX","98.73","99.07","98.01",0.37,0.38,3420000
|
||||
"Whirlpool","109.00","110.43","108.64",-1.19,-1.08,669950
|
||||
"FirstEnergy","37.31","37.54","36.00",1.52,4.26,9590000
|
||||
"Globe Life","125.91","125.98","123.99",0.96,0.77,474680
|
||||
"Rtx Corp","90.52","91.61","90.33",-0.52,-0.57,5870000
|
||||
"PulteGroup","103.09","103.93","102.15",-0.17,-0.16,1090000
|
||||
"Valero Energy","143.08","143.27","141.16",1.28,0.9,3460000
|
||||
"Boston Scientific","65.49","65.60","64.85",0.47,0.72,6750000
|
||||
"Capital One Financial","135.17","135.50","133.35",0.39,0.29,1330000
|
||||
"PG E","16.25","16.39","16.18",0.01,0.03,18190000
|
||||
"Norfolk Southern","254.77","256.36","253.69",0.72,0.28,900100
|
||||
"Aflac","78.20","78.36","77.56",0.1,0.12,1500000
|
||||
"Equity Residential","58.86","59.28","58.65",-0.34,-0.57,1440000
|
||||
"Air Products","219.79","219.93","216.50",-0.12,-0.05,2170000
|
||||
"Principal Financial","78.20","78.47","76.82",0.44,0.57,828190
|
||||
"Texas Instruments","162.40","162.47","160.63",2.19,1.37,3820000
|
||||
"HP Inc","28.42","28.52","28.19",0.13,0.46,4110000
|
||||
"Honeywell","194.84","195.23","192.83",1.38,0.71,3570000
|
||||
"AMD","172.48","175.10","168.66",3.13,1.85,55790000
|
||||
"M&T Bank","133.40","133.51","130.09",1.78,1.35,1000000
|
||||
"Mosaic","29.91","30.49","29.82",-0.17,-0.58,5290000
|
||||
"Revvity","103.74","104.26","102.86",0.49,0.47,483210
|
||||
"Las Vegas Sands","53.62","53.85","53.09",0.01,0.01,3320000
|
||||
"Freeport-McMoran","37.31","37.91","37.26",-0.81,-2.12,14230000
|
||||
"AutoZone","2680.21","2743.53","2680.00",-51.45,-1.88,195110
|
||||
"Sysco","79.57","79.63","79.02",0.25,0.32,2120000
|
||||
"Ameren","68.67","68.83","67.59",0.76,1.11,1840000
|
||||
"Eaton","277.95","278.58","273.00",4.74,1.73,1530000
|
||||
"Salesforce Inc","291.27","295.24","291.07",-0.68,-0.23,3730000
|
||||
"Consolidated Edison","89.05","89.14","88.32",0.38,0.43,1400000
|
||||
"The AES","16.46","16.48","16.14",0.26,1.6,5390000
|
||||
"Textron","87.18","88.00","87.00",-0.41,-0.47,958370
|
||||
"U.S. Bancorp","40.18","40.39","39.77",-0.19,-0.47,8700000
|
||||
"Comerica","51.34","51.84","50.14",0.27,0.53,1370000
|
||||
"Visa A","276.40","277.18","274.09",0.62,0.22,2850000
|
||||
"Baker Hughes","29.06","29.46","28.83",-0.26,-0.89,7090000
|
||||
"Hess","142.04","147.65","142.02",-4.23,-2.89,4550000
|
||||
"Yum! Brands","130.27","130.41","129.32",-0.13,-0.1,1920000
|
||||
"Marsh McLennan","197.88","197.92","195.94",1.08,0.55,800330
|
||||
"Kellanova","53.48","54.74","53.12",-1.46,-2.65,3240000
|
||||
"Kimco Realty","20.10","20.10","19.65",0.08,0.4,6400000
|
||||
"Ecolab","202.67","203.62","200.50",-0.22,-0.11,972500
|
||||
"EOG Resources","111.05","113.75","110.67",-2.01,-1.78,2470000
|
||||
"Aon","312.47","312.55","306.67",5.29,1.72,753950
|
||||
"Hasbro","50.59","51.10","50.23",-0.09,-0.18,1320000
|
||||
"Bank of NY Mellon","55.21","55.36","54.83",0.1,0.18,2440000
|
||||
"Schlumberger","47.07","47.85","46.91",-0.72,-1.51,8170000
|
||||
"Walgreens Boots","22.24","22.63","22.16",-0.3,-1.33,8340000
|
||||
"Rockwell Automation","283.61","284.58","278.77",4.9,1.76,1490000
|
||||
"PepsiCo","167.67","171.39","166.97",-6.18,-3.55,12240000
|
||||
"UnitedHealth","518.11","520.39","516.34",-1.98,-0.38,2600000
|
||||
"Teradyne","102.31","102.42","98.86",3.84,3.9,1640000
|
||||
"Danaher","242.88","247.25","242.88",-2.99,-1.22,2030000
|
||||
"Seagate","89.41","89.47","87.36",1.73,1.97,1520000
|
||||
"Agilent Technologies","133.38","135.15","132.77",-0.69,-0.51,864180
|
||||
"Delta Air Lines","40.51","40.87","39.96",0.15,0.38,7570000
|
||||
"Moody’s","404.99","405.32","396.40",6.99,1.76,920590
|
||||
"Nike","104.50","104.93","103.33",0.73,0.7,4430000
|
||||
"Procter&Gamble","157.40","158.34","156.96",-1.24,-0.78,5860000
|
||||
"Weyerhaeuser","33.28","33.28","32.97",0.27,0.82,2300000
|
||||
"ADP","249.99","250.99","248.89",-1.09,-0.43,1190000
|
||||
"Keurig Dr Pepper","31.15","31.49","30.94",-0.34,-1.08,5120000
|
||||
"Lowe’s","222.27","222.31","219.17",1.88,0.85,1070000
|
||||
"United Airlines Holdings","42.33","43.03","41.60",0.71,1.71,9110000
|
||||
"Netflix","561.32","566.00","558.10",2.79,0.5,3020000
|
||||
"News Corp","27.21","27.34","26.88",0.2,0.74,874170
|
||||
"Equinix","855.76","856.82","844.90",0.43,0.05,354810
|
||||
"Booking","3758.18","3761.75","3663.01",-82.04,-2.14,395700
|
||||
"O’Reilly Automotive","1025.82","1041.33","1023.58",4.99,0.49,484720
|
||||
"BlackRock","796.68","800.80","792.23",3.48,0.44,426020
|
||||
"CME Group","205.09","205.60","203.61",1.09,0.53,1420000
|
||||
"Illumina","137.84","147.70","135.30",-5.49,-3.83,3470000
|
||||
"JB Hunt","215.58","215.90","211.95",2.2,1.03,495810
|
||||
"Loews","72.74","72.75","71.66",0.72,1,475990
|
||||
"NextEra Energy","56.56","56.63","55.72",0.27,0.48,7840000
|
||||
"First Solar","151.50","153.01","144.00",8.33,5.82,2730000
|
||||
"Viatris","11.68","11.69","11.45",0.12,1.04,6170000
|
||||
"F5 Networks","186.61","187.21","184.44",1.38,0.74,304830
|
||||
"Edwards Lifesciences","85.02","86.68","84.89",-0.78,-0.91,2830000
|
||||
"News Corp A","26.04","26.18","25.70",0.2,0.77,3940000
|
||||
"Amphenol","105.28","105.41","104.55",0.42,0.4,1250000
|
||||
"Berkshire Hathaway B","398.33","398.33","395.85",0.84,0.21,1920000
|
||||
"Coterra Energy","24.30","24.52","24.20",-0.2,-0.82,4840000
|
||||
"CarMax","74.79","74.86","72.90",1.49,2.03,1560000
|
||||
"Chipotle Mexican Grill","2636.06","2659.11","2615.93",15.58,0.59,191430
|
||||
"DaVita","109.87","111.27","109.73",-0.95,-0.86,677110
|
||||
"EQT","34.32","34.81","34.21",-0.43,-1.24,3190000
|
||||
"FMC","51.76","52.41","50.63",-0.28,-0.54,3270000
|
||||
"L3Harris Technologies","209.84","210.11","207.87",0.54,0.26,517540
|
||||
"Healthpeak Properties","17.35","17.80","17.07",-0.64,-3.56,13020000
|
||||
"Welltower","87.64","87.68","86.23",0.67,0.76,1720000
|
||||
"Hormel Foods","29.07","29.33","28.97",-0.41,-1.37,3560000
|
||||
"Invesco","15.89","15.95","15.68",-0.01,-0.09,2870000
|
||||
"Iron Mountain","68.63","68.94","68.18",0.07,0.1,642430
|
||||
"Eversource Energy","54.95","55.27","53.88",0.88,1.63,3160000
|
||||
"NRG","52.37","52.56","51.98",0.02,0.04,1720000
|
||||
"ONEOK","69.03","69.49","68.71",0.07,0.09,2080000
|
||||
"Pioneer Natural","227.15","233.37","226.85",-4.61,-1.99,1520000
|
||||
"Republic Services","173.49","175.07","172.79",-1.15,-0.66,929990
|
||||
"Roper Technologies","550.26","550.77","545.11",4.92,0.9,370800
|
||||
"Ventas","45.52","45.68","44.99",0,0,1630000
|
||||
"WEC Energy","77.57","77.74","76.95",0.17,0.22,2060000
|
||||
"Blackstone","127.68","128.63","125.99",-0.16,-0.13,2640000
|
||||
"Marathon Petroleum","169.97","170.69","168.73",0.29,0.17,2130000
|
||||
"Broadcom","1283.44","1285.65","1249.08",8.68,0.68,2550000
|
||||
"NXP","233.55","233.66","228.32",5.72,2.51,2340000
|
||||
"Tesla","193.57","194.12","189.49",4.01,2.12,83610000
|
||||
"Take-Two","154.91","158.11","152.23",-14.69,-8.66,6580000
|
||||
"Dollar Tree","139.50","140.73","139.17",-1.4,-0.99,2290000
|
||||
"Align","296.37","298.54","291.53",1.37,0.46,803120
|
||||
"ANSYS","342.28","346.64","341.89",-3.05,-0.88,834790
|
||||
"Builders FirstSource","185.38","186.54","182.89",0.13,0.07,1040000
|
||||
"Charter Communications","291.15","293.40","285.01",8.55,3.03,2050000
|
||||
"CoStar","83.13","83.45","80.51",1.36,1.66,4010000
|
||||
"DexCom","120.47","124.99","120.29",-6.58,-5.18,5550000
|
||||
"Fortinet","70.44","70.86","68.20",2.59,3.82,7090000
|
||||
"IDEXX Labs","572.21","578.35","565.52",-1.4,-0.24,312340
|
||||
"Incyte","57.66","57.96","57.09",0.3,0.52,1510000
|
||||
"Jack Henry&Associates","175.93","176.10","174.01",1.88,1.08,448190
|
||||
"MarketAxesss","223.32","226.60","220.29",-0.87,-0.39,280200
|
||||
"Monolithic","752.31","761.50","737.22",15.24,2.07,654900
|
||||
"Nordson","263.63","263.94","260.81",1.76,0.67,143780
|
||||
"ON Semiconductor","80.80","81.59","79.71",0.09,0.11,6140000
|
||||
"PTC","183.10","183.69","181.60",1.56,0.86,527660
|
||||
"Insulet","192.44","197.46","191.92",-4.2,-2.14,736300
|
||||
"Pool","386.65","391.01","384.42",-0.69,-0.18,211450
|
||||
"Bio-Techne","67.95","68.19","66.79",0.05,0.07,883500
|
||||
"Zebra","253.09","253.73","248.36",5.97,2.42,324810
|
||||
"BorgWarner","31.80","32.00","31.29",0.32,1.03,2860000
|
||||
"T-Mobile US","162.19","162.64","160.28",1.26,0.78,4280000
|
||||
"Quanta Services","210.03","211.00","206.43",2.26,1.09,656270
|
||||
"Leidos","113.52","114.23","112.99",0.25,0.22,621380
|
||||
"TE Connectivity","144.05","144.45","142.74",0.94,0.66,821920
|
||||
"Mid-America Apartment","124.53","124.95","123.37",0.05,0.04,1060000
|
||||
"Charles River Laboratories","222.21","224.61","217.13",3.44,1.57,522620
|
||||
"Huntington Ingalls Industries","274.05","274.32","271.02",1.92,0.71,188460
|
||||
"Mettler-Toledo","1175.31","1233.99","1169.94",-49.66,-4.05,289160
|
||||
"Federal Realty","101.14","102.03","99.94",-0.92,-0.9,855900
|
||||
"Live Nation Entertainment","89.54","90.50","87.93",1.54,1.75,3140000
|
||||
"Martin Marietta Materials","527.15","527.15","522.10",1.74,0.33,274340
|
||||
"FactSet Research","477.65","477.65","470.01",7.59,1.61,153500
|
||||
"Raymond James Financial","114.90","114.96","112.04",2.8,2.5,927470
|
||||
"Bio-Rad Labs","325.31","327.48","322.62",-0.8,-0.25,99820
|
||||
"Digital","147.23","147.94","145.54",0.17,0.12,1200000
|
||||
"Essex Property","229.86","230.36","228.46",0.52,0.23,269920
|
||||
"Fair Isaac","1322.98","1336.39","1317.44",1.54,0.12,94330
|
||||
"Cooper","376.60","376.95","370.49",2.95,0.79,160050
|
||||
"Molina Healthcare","388.67","390.00","378.05",7.18,1.88,460830
|
||||
"Everest","353.74","355.03","348.46",-0.82,-0.23,685340
|
||||
"Regency Centers","61.32","62.09","60.01",-0.82,-1.32,2270000
|
||||
"Dollar General","135.20","135.91","134.16",-0.45,-0.33,1850000
|
||||
"Transdigm","1118.35","1139.98","1116.11",-10.22,-0.91,279970
|
||||
"Atmos Energy","113.08","113.50","112.59",0.15,0.13,532110
|
||||
"Brown&Brown","81.00","81.01","79.75",1.05,1.32,991410
|
||||
"Domino’s Pizza Inc","424.98","427.55","424.45",-1.6,-0.38,339630
|
||||
"HCA","306.41","307.51","305.57",0.95,0.31,753540
|
||||
"Hubbell","363.13","363.36","357.50",4.92,1.37,266750
|
||||
"Rollins","43.48","44.12","43.19",-0.24,-0.56,1640000
|
||||
"STERIS","224.28","224.57","218.97",4.02,1.83,600580
|
||||
"ResMed","184.65","185.95","182.27",0.9,0.49,729020
|
||||
"MSCI","592.30","594.24","584.88",6.8,1.16,272690
|
||||
"NVR","7441.0","7476.6","7364.2",-45.7,-0.61,14930
|
||||
"Carnival Corp","15.30","15.74","14.96",-0.39,-2.49,45420000
|
||||
"West Pharmaceutical Services","409.79","412.67","408.30",-1.11,-0.27,269440
|
||||
"Teledyne Technologies","433.82","434.27","428.00",3.15,0.73,140650
|
||||
"Tyler Technologies","441.04","442.39","433.11",5.89,1.35,139190
|
||||
"Targa Resources","87.07","88.63","87.06",-0.83,-0.94,1310000
|
||||
"Meta Platforms","468.11","473.59","467.46",-1.89,-0.4,17910000
|
||||
"Alexandria RE","116.20","118.18","114.80",-1.7,-1.44,1260000
|
||||
"Teleflex","252.04","252.30","248.59",0.72,0.29,148180
|
||||
"Westinghouse Air Brake","136.68","137.56","136.15",-0.05,-0.04,1300000
|
||||
"Evergy","49.08","49.27","48.40",0.46,0.95,2230000
|
||||
"Willis Towers Watson","271.86","272.99","269.98",1.75,0.65,462240
|
||||
"Caesars","44.50","45.17","44.23",0.25,0.56,2900000
|
||||
"Enphase","122.47","124.55","117.30",5.59,4.78,5270000
|
||||
"Aptiv","82.02","82.39","80.85",0.73,0.9,2930000
|
||||
"Crown Castle","108.40","108.53","106.76",0.9,0.84,2640000
|
||||
"EPAM Systems","286.27","291.35","286.07",-0.9,-0.31,640890
|
||||
"Pentair","74.48","74.76","73.88",0.04,0.05,1390000
|
||||
"Mondelez","73.17","74.46","72.83",-1.59,-2.13,7300000
|
||||
"Skyworks","105.05","105.58","104.04",0.46,0.44,1500000
|
||||
"Tractor Supply","235.08","235.19","231.34",3.25,1.4,958700
|
||||
"Lululemon Athletica","470.24","471.26","458.78",-2.74,-0.58,1110000
|
||||
"Regeneron Pharma","953.42","957.51","945.85",6.99,0.74,500720
|
||||
"United Rentals","650.35","653.08","643.93",3.35,0.52,363440
|
||||
"Kinder Morgan","16.61","16.72","16.53",-0.03,-0.15,7420000
|
||||
"Albemarle","115.74","116.19","113.13",1.41,1.23,2310000
|
||||
"Centene","77.32","77.36","75.89",0.82,1.07,1930000
|
||||
"Phillips 66","145.66","147.78","145.35",-1.16,-0.79,2450000
|
||||
"Xylem","124.30","124.39","122.06",1.92,1.57,1550000
|
||||
"UDR","35.37","35.67","35.26",-0.12,-0.34,2340000
|
||||
"SBA Communications","217.45","218.13","214.00",1.25,0.58,946720
|
||||
"Gartner","463.63","465.02","456.59",7.45,1.63,334900
|
||||
"IDEX","228.11","228.28","225.29",2.28,1.01,422760
|
||||
"Universal Health Services","162.37","162.80","161.27",0.41,0.25,264750
|
||||
"LKQ","47.94","48.11","47.43",0.4,0.84,904460
|
||||
"Broadridge","198.98","199.86","198.50",-0.02,-0.01,607820
|
||||
"Extra Space Storage","143.36","144.18","142.39",-0.11,-0.08,694810
|
||||
"Camden Property","93.45","94.10","93.25",-0.5,-0.53,615980
|
||||
"Mohawk Industries","110.06","111.80","101.83",0.46,0.42,1980000
|
||||
"American Water Works","122.22","122.62","121.07",0.39,0.32,718930
|
||||
"Alliant Energy","47.93","47.99","47.33",0.45,0.95,1460000
|
||||
"Celanese","149.00","149.06","147.30",0.1,0.07,425180
|
||||
"Bunge","88.45","88.66","86.81",1.95,2.25,2580000
|
||||
"Ametek","168.49","168.60","166.41",2.19,1.32,800310
|
||||
"WR Berkley","80.46","80.51","79.33",0.58,0.73,891180
|
||||
"LyondellBasell Industries","95.42","95.42","94.37",0.44,0.46,1380000
|
||||
"Royal Caribbean Cruises","116.99","121.00","115.58",-3.98,-3.29,4120000
|
||||
"FleetCor","273.21","275.53","266.43",8.09,3.05,770350
|
||||
"Packaging America","168.37","168.39","166.21",1.5,0.9,450830
|
||||
"Arthur J Gallagher","238.81","239.18","236.29",1.78,0.75,440910
|
||||
"Church&Dwight","98.82","100.08","98.16",-1.12,-1.12,989910
|
||||
"Generac","126.97","128.39","125.16",-0.17,-0.13,884720
|
||||
"Global Payments","136.00","137.09","134.91",-0.63,-0.46,1510000
|
||||
"Realty Income","52.75","53.25","52.28",-0.41,-0.77,5830000
|
||||
"AO Smith","80.55","80.80","79.98",0.3,0.37,537460
|
||||
"Arch Capital","83.46","83.52","81.59",0.7,0.85,1090000
|
||||
"Cboe Global","183.55","185.92","182.72",-0.61,-0.33,574360
|
||||
"Copart","50.91","51.15","50.65",-0.05,-0.1,3010000
|
||||
"Old Dominion Freight Line","435.33","437.88","428.67",0.17,0.04,784180
|
||||
"Synopsys","575.30","582.85","571.92",4.61,0.81,967450
|
||||
"Trimble","52.51","52.64","51.74",0.43,0.83,1510000
|
||||
"Ulta Beauty","522.63","524.34","517.16",3.51,0.68,480210
|
||||
"Verisk","250.61","251.47","248.18",1.35,0.54,691700
|
||||
"AbbVie","174.04","175.40","173.06",-0.75,-0.43,3400000
|
||||
"Diamondback","151.74","154.22","151.25",-1.74,-1.13,963550
|
||||
"Norwegian Cruise Line","16.41","17.54","16.35",-1.09,-6.23,21310000
|
||||
"Zoetis Inc","197.29","198.22","195.59",1.54,0.79,1860000
|
||||
"IQVIA Holdings","218.26","222.21","216.18",1.26,0.58,1020000
|
||||
"ServiceNow Inc","813.27","815.27","802.39",13.86,1.73,847820
|
||||
"Palo Alto Networks","376.90","380.84","369.00",9.88,2.69,3430000
|
||||
"CDW Corp","245.23","245.41","241.49",1.27,0.52,870860
|
||||
"Hilton Worldwide","192.17","194.02","191.68",-2.38,-1.22,1530000
|
||||
"American Airlines","14.88","15.18","14.71",-0.07,-0.47,26850000
|
||||
"Allegion PLC","131.91","132.95","130.45",1.39,1.07,760630
|
||||
"Alphabet C","150.22","150.70","147.43",3,2.04,21350000
|
||||
"Paycom Soft","190.02","197.53","187.47",-5.73,-2.93,1770000
|
||||
"Arista Networks","282.30","284.82","278.63",6.41,2.32,2950000
|
||||
"Synchrony Financial","38.72","39.04","38.27",-0.16,-0.41,2810000
|
||||
"Catalent Inc","56.73","56.95","56.10",0.18,0.32,3640000
|
||||
"Citizens Financial Group Inc","31.51","31.69","30.89",0.14,0.45,3170000
|
||||
"Keysight Technologies","161.53","162.50","161.04",0.35,0.22,639790
|
||||
"Qorvo Inc","112.32","113.79","112.21",-0.3,-0.27,963360
|
||||
"Etsy Inc","78.09","78.78","73.56",3.6,4.83,3170000
|
||||
"WestRock Co","42.49","42.78","42.23",-0.33,-0.77,1680000
|
||||
"PayPal","58.91","59.22","56.16",2.78,4.95,30500000
|
||||
"Hewlett Packard","15.48","15.55","15.37",-0.01,-0.1,6130000
|
||||
"Match Group","35.42","35.95","34.95",0.39,1.11,2910000
|
||||
"Fortive","82.69","82.72","81.87",0.45,0.55,899160
|
||||
"Lamb Weston Holdings","100.84","101.17","99.57",-0.04,-0.04,881030
|
||||
"Invitation Homes","33.06","33.10","32.54",0.37,1.13,2410000
|
||||
"VICI Properties","29.71","29.73","29.34",0.04,0.15,4090000
|
||||
"Dayforce","70.69","70.71","68.39",0.71,1.01,1280000
|
||||
"Moderna","87.41","93.36","86.41",-6.25,-6.67,7110000
|
||||
"Uber Tech","70.89","72.04","69.69",-0.72,-1.01,20300000
|
||||
"Fox Corp A","29.79","29.85","28.74",1.01,3.51,5670000
|
||||
"Fox Corp B","27.45","27.58","26.61",0.83,3.12,1740000
|
||||
"Corteva","53.59","53.91","52.88",0.35,0.66,2400000
|
||||
"Amcor PLC","9.10","9.14","8.99",-0.07,-0.71,7140000
|
||||
"Trane Technologies","275.46","275.49","269.20",5.52,2.04,910240
|
||||
"Otis Worldwide","91.09","91.09","90.29",0.22,0.24,1700000
|
||||
"Carrier Global","56.00","56.02","54.61",0.94,1.71,4660000
|
||||
"Howmet","58.59","59.36","58.56",-0.58,-0.98,2390000
|
||||
"Airbnb","147.60","148.68","145.18",-2.94,-1.96,4950000
|
||||
"Constellation Energy","132.17","132.51","130.00",1.45,1.11,827840
|
||||
"GE HealthCare","81.34","82.75","80.61",-0.72,-0.88,2700000
|
||||
"Kenvue","19.32","19.61","19.08",-0.01,-0.03,24460000
|
||||
"Veralto","82.17","83.55","81.99",-0.39,-0.47,1180000
|
||||
"Linde PLC","419.42","419.83","412.29",5.42,1.31,1310000
|
||||
|
@@ -1,45 +0,0 @@
|
||||
use axum::{
|
||||
body::Body,
|
||||
extract::State,
|
||||
http::{Request, Response, StatusCode, Uri},
|
||||
response::{IntoResponse, Response as AxumResponse},
|
||||
};
|
||||
use leptos::{view, LeptosOptions};
|
||||
use tower::ServiceExt;
|
||||
use tower_http::services::ServeDir;
|
||||
|
||||
pub async fn file_and_error_handler(
|
||||
uri: Uri,
|
||||
State(options): State<LeptosOptions>,
|
||||
req: Request<Body>,
|
||||
) -> AxumResponse {
|
||||
let root = options.site_root.clone();
|
||||
log::debug!("uri = {uri:?} root = {root} ");
|
||||
let res = get_static_file(uri.clone(), &root).await.unwrap();
|
||||
|
||||
if res.status() == StatusCode::OK {
|
||||
res.into_response()
|
||||
} else {
|
||||
let handler = leptos_axum::render_app_to_stream(
|
||||
options.to_owned(),
|
||||
|| view! {"Error! Error! Error!"},
|
||||
);
|
||||
handler(req).await.into_response()
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_static_file(uri: Uri, root: &str) -> Result<Response<Body>, (StatusCode, String)> {
|
||||
let req = Request::builder()
|
||||
.uri(uri.clone())
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
// `ServeDir` implements `tower::Service` so we can call it with `tower::ServiceExt::oneshot`
|
||||
// This path is relative to the cargo root
|
||||
match ServeDir::new(root).oneshot(req).await {
|
||||
Ok(res) => Ok(res.into_response()),
|
||||
Err(err) => Err((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Something went wrong: {}", err),
|
||||
)),
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
use leptos::*;
|
||||
use leptos_meta::*;
|
||||
use leptos_router::*;
|
||||
#[cfg(feature = "ssr")]
|
||||
pub mod fallback;
|
||||
|
||||
#[cfg(feature = "hydrate")]
|
||||
#[wasm_bindgen::prelude::wasm_bindgen]
|
||||
pub fn hydrate() {
|
||||
// initializes logging using the `log` crate
|
||||
_ = console_log::init_with_level(log::Level::Debug);
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
leptos::mount_to_body(App);
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn App() -> impl IntoView {
|
||||
provide_meta_context();
|
||||
// Provide this two our search components, they'll share a read and write handle to a Vec<StockRow>.
|
||||
let search_results = create_rw_signal(Vec::<StockRow>::new());
|
||||
provide_context(search_results);
|
||||
view! {
|
||||
<Link rel="shortcut icon" type_="image/ico" href="/favicon.ico"/>
|
||||
<Meta name="description" content="Leptos implementation of a Meilisearch backed Searchbar."/>
|
||||
<Router>
|
||||
<main>
|
||||
<Routes>
|
||||
<Route path="/" view=||view!{
|
||||
<SearchBar/>
|
||||
<SearchResults/>
|
||||
}/>
|
||||
</Routes>
|
||||
</main>
|
||||
</Router>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, serde::Deserialize, serde::Serialize, Debug)]
|
||||
pub struct StockRow {
|
||||
id: u32,
|
||||
name: String,
|
||||
last: String,
|
||||
high: String,
|
||||
low: String,
|
||||
absolute_change: f32,
|
||||
percentage_change: f32,
|
||||
volume: u64,
|
||||
}
|
||||
|
||||
#[leptos::server]
|
||||
pub async fn search_query(query: String) -> Result<Vec<StockRow>, ServerFnError> {
|
||||
use leptos_axum::extract;
|
||||
// Wow, so ergonomic!
|
||||
let axum::Extension::<meilisearch_sdk::Client>(client) = extract().await?;
|
||||
// Meilisearch has great defaults, lots of things are thought of for out of the box utility.
|
||||
// They limit the result length automatically (to 20), and have user friendly typo corrections and return similar words.
|
||||
let hits = client
|
||||
.get_index("stock_prices")
|
||||
.await
|
||||
.unwrap()
|
||||
.search()
|
||||
.with_query(query.as_str())
|
||||
.execute::<StockRow>()
|
||||
.await
|
||||
.map_err(|err| ServerFnError::new(err.to_string()))?
|
||||
.hits;
|
||||
|
||||
Ok(hits
|
||||
.into_iter()
|
||||
.map(|search_result| search_result.result)
|
||||
.collect())
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn SearchBar() -> impl IntoView {
|
||||
let write_search_results = expect_context::<RwSignal<Vec<StockRow>>>().write_only();
|
||||
let search_query = create_server_action::<SearchQuery>();
|
||||
create_effect(move |_| {
|
||||
if let Some(value) = search_query.value()() {
|
||||
match value {
|
||||
Ok(search_results) => {
|
||||
write_search_results.set(search_results);
|
||||
}
|
||||
Err(err) => {
|
||||
leptos::logging::log!("{err}")
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
view! {
|
||||
<div>
|
||||
<label for="search">Search</label>
|
||||
<input id="search" on:input=move|e|{
|
||||
let query = event_target_value(&e);
|
||||
search_query.dispatch(SearchQuery{query});
|
||||
}/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn SearchResults() -> impl IntoView {
|
||||
let read_search_results = expect_context::<RwSignal<Vec<StockRow>>>().read_only();
|
||||
view! {
|
||||
<ul>
|
||||
<For
|
||||
each=read_search_results
|
||||
key=|row| row.name.clone()
|
||||
children=move |StockRow{name,last,high,low,absolute_change,percentage_change,volume,..}: StockRow| {
|
||||
view! {
|
||||
<li>
|
||||
{format!("{name}; last: {last}; high: {high}; low: {low}; chg.: {absolute_change}; chg...:{percentage_change}; volume:{volume}")}
|
||||
</li>
|
||||
}
|
||||
}
|
||||
/>
|
||||
</ul>
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
#[cfg(feature = "ssr")]
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
use axum::{routing::get, Extension, Router};
|
||||
use leptos::get_configuration;
|
||||
use leptos_axum::{generate_route_list, LeptosRoutes};
|
||||
use meilisearch_searchbar::StockRow;
|
||||
use meilisearch_searchbar::{fallback::file_and_error_handler, *};
|
||||
|
||||
// simple_logger is a lightweight alternative to tracing, when you absolutely have to trace, use tracing.
|
||||
simple_logger::SimpleLogger::new()
|
||||
.with_level(log::LevelFilter::Debug)
|
||||
.init()
|
||||
.unwrap();
|
||||
|
||||
let mut rdr = csv::Reader::from_path("data_set.csv").unwrap();
|
||||
|
||||
// Our data set doesn't have a good id for the purposes of meilisearch, Name is unique but it's not formatted correctly because it may have spaces.
|
||||
let documents: Vec<StockRow> = rdr
|
||||
.records()
|
||||
.enumerate()
|
||||
.map(|(i, rec)| {
|
||||
// There's probably a better way to do this.
|
||||
let mut record = csv::StringRecord::new();
|
||||
record.push_field(&i.to_string());
|
||||
for field in rec.unwrap().iter() {
|
||||
record.push_field(field);
|
||||
}
|
||||
record
|
||||
.deserialize::<StockRow>(None)
|
||||
.expect(&format!("{:?}", record))
|
||||
})
|
||||
.collect();
|
||||
|
||||
// My own check. I know how long I expect it to be, if it's not this length something is wrong.
|
||||
assert_eq!(documents.len(), 503);
|
||||
|
||||
let client = meilisearch_sdk::Client::new(
|
||||
std::env::var("MEILISEARCH_URL").unwrap(),
|
||||
std::env::var("MEILISEARCH_API_KEY").ok(),
|
||||
);
|
||||
// An index is where the documents are stored.
|
||||
let task = client
|
||||
.create_index("stock_prices", Some("id"))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Meilisearch may take some time to execute the request so we are going to wait till it's completed
|
||||
client.wait_for_task(task, None, None).await.unwrap();
|
||||
|
||||
let task_2 = client
|
||||
.get_index("stock_prices")
|
||||
.await
|
||||
.unwrap()
|
||||
.add_documents(&documents, Some("id"))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
client.wait_for_task(task_2, None, None).await.unwrap();
|
||||
|
||||
drop(documents);
|
||||
|
||||
let conf = get_configuration(Some("Cargo.toml")).await.unwrap();
|
||||
let leptos_options = conf.leptos_options;
|
||||
let addr = leptos_options.site_addr;
|
||||
let routes = generate_route_list(App);
|
||||
|
||||
// build our application with a route
|
||||
let app = Router::new()
|
||||
.route("/favicon.ico", get(file_and_error_handler))
|
||||
.leptos_routes(&leptos_options, routes, App)
|
||||
.fallback(file_and_error_handler)
|
||||
.layer(Extension(client))
|
||||
.with_state(leptos_options);
|
||||
|
||||
// run our app with hyper
|
||||
// `axum::Server` is a re-export of `hyper::Server`
|
||||
println!("listening on {}", addr);
|
||||
let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
|
||||
axum::serve(listener, app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
3
projects/nginx-mpmc/.gitignore
vendored
3
projects/nginx-mpmc/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
/target
|
||||
*/target
|
||||
.vscode
|
||||
@@ -1,34 +0,0 @@
|
||||
# Nginx Multiple Server Multiple Client Example
|
||||
This example shows how multiple clients can communicate with multiple servers while being shared over a single domain i.e localhost:80 using nginx as a reverse proxy.
|
||||
|
||||
### How to run this example
|
||||
```sh
|
||||
./run.sh
|
||||
```
|
||||
Or
|
||||
|
||||
```sh
|
||||
./run_linux.sh
|
||||
```
|
||||
|
||||
<br>
|
||||
This will boot up nginx via it's docker image mapped to port 80, and the four servers. App-1, App-2, Shared-Server-1, Shared-Server-2.
|
||||
<br>
|
||||
App-1, And App-2 are SSR rendering leptos servers.
|
||||
<br>
|
||||
If you go to localhost (you'll get App-1), and localhost/app2 (you'll get app2).
|
||||
<br>
|
||||
The two shared servers can be communicated with via actions and local resources, or resources (if using CSR).
|
||||
<br>
|
||||
`create_resource` Won't work as expected, when trying to communicate to different servers. It will instead try to run the server function on the server you are serving your server side rendered content from. This will cause errors if your server function relies on state that is not present.
|
||||
<br>
|
||||
When you are done with this example, run
|
||||
|
||||
```sh
|
||||
./kill.sh
|
||||
```
|
||||
|
||||
Casting ctrl-c multiple times won't close all the open programs.
|
||||
|
||||
## Thoughts, Feedback, Criticism, Comments?
|
||||
Send me any of the above, I'm @sjud on leptos discord. I'm always looking to improve and make these projects more helpful for the community. So please let me know how I can do that. Thanks!
|
||||
13
projects/nginx-mpmc/app-1/.gitignore
vendored
13
projects/nginx-mpmc/app-1/.gitignore
vendored
@@ -1,13 +0,0 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
pkg
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# node e2e test tools and outputs
|
||||
node_modules/
|
||||
test-results/
|
||||
end2end/playwright-report/
|
||||
playwright/.cache/
|
||||
@@ -1,120 +0,0 @@
|
||||
[package]
|
||||
name = "app-1"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
console_error_panic_hook = "0.1"
|
||||
leptos_meta = { version = "0.6" }
|
||||
leptos_router = { version = "0.6" }
|
||||
tower = { version = "0.4", optional = true }
|
||||
tower-http = { version = "0.5", features = ["fs","trace"], optional = true }
|
||||
wasm-bindgen = "=0.2.89"
|
||||
thiserror = "1"
|
||||
tracing = { version = "0.1", optional = true }
|
||||
|
||||
http = "1"
|
||||
|
||||
axum = {version = "0.7",optional=true}
|
||||
leptos = "0.6"
|
||||
leptos_axum = {version = "0.6",optional=true}
|
||||
tokio = { version = "1", features = ["rt-multi-thread"], optional = true}
|
||||
shared-server = {path = "../shared-server",default-features = false}
|
||||
shared-server-2 = {path = "../shared-server-2",default-features = false}
|
||||
tracing-subscriber = {version="0.3.18",features=["env-filter"]}
|
||||
|
||||
# Defines a size-optimized profile for the WASM bundle in release mode
|
||||
[profile.wasm-release]
|
||||
inherits = "release"
|
||||
opt-level = 'z'
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
panic = "abort"
|
||||
|
||||
[features]
|
||||
hydrate = [
|
||||
"leptos/hydrate",
|
||||
"leptos_meta/hydrate",
|
||||
"leptos_router/hydrate",
|
||||
"shared-server/hydrate",
|
||||
"shared-server-2/hydrate"
|
||||
]
|
||||
ssr = [
|
||||
"shared-server/ssr",
|
||||
"shared-server-2/ssr",
|
||||
"dep:axum",
|
||||
"dep:tokio",
|
||||
"dep:tower",
|
||||
"dep:tower-http",
|
||||
"dep:leptos_axum",
|
||||
"leptos/ssr",
|
||||
"leptos_meta/ssr",
|
||||
"leptos_router/ssr",
|
||||
"dep:tracing",
|
||||
]
|
||||
|
||||
|
||||
|
||||
[package.metadata.leptos]
|
||||
# The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name
|
||||
output-name = "app-1"
|
||||
|
||||
# The site root folder is where cargo-leptos generate all output. WARNING: all content of this folder will be erased on a rebuild. Use it in your server setup.
|
||||
site-root = "target/site"
|
||||
|
||||
# The site-root relative folder where all compiled output (JS, WASM and CSS) is written
|
||||
# Defaults to pkg
|
||||
site-pkg-dir = "pkg"
|
||||
|
||||
# Assets source dir. All files found here will be copied and synchronized to site-root.
|
||||
# The assets-dir cannot have a sub directory with the same name/path as site-pkg-dir.
|
||||
#
|
||||
# Optional. Env: LEPTOS_ASSETS_DIR.
|
||||
assets-dir = "public"
|
||||
|
||||
# The IP and port (ex: 127.0.0.1:3000) where the server serves the content. Use it in your server setup.
|
||||
# we're listening inside of a docker container, so we need to set 0.0.0.0 to let it be accessed from outside the container.
|
||||
site-addr = "127.0.0.1:3000"
|
||||
|
||||
# The port to use for automatic reload monitoring
|
||||
reload-port = 3004
|
||||
|
||||
# [Optional] The source CSS file. If it ends with .sass or .scss then it will be compiled by dart-sass into CSS. The CSS is optimized by Lightning CSS before being written to <site-root>/<site-pkg>/app.css
|
||||
style-file = "style/main.scss"
|
||||
|
||||
# The browserlist query used for optimizing the CSS.
|
||||
browserquery = "defaults"
|
||||
|
||||
# Set by cargo-leptos watch when building with that tool. Controls whether autoreload JS will be included in the head
|
||||
watch = false
|
||||
|
||||
# The environment Leptos will run in, usually either "DEV" or "PROD"
|
||||
env = "DEV"
|
||||
|
||||
# The features to use when compiling the bin target
|
||||
#
|
||||
# Optional. Can be over-ridden with the command line parameter --bin-features
|
||||
bin-features = ["ssr"]
|
||||
|
||||
# If the --no-default-features flag should be used when compiling the bin target
|
||||
#
|
||||
# Optional. Defaults to false.
|
||||
bin-default-features = false
|
||||
|
||||
# The features to use when compiling the lib target
|
||||
#
|
||||
# Optional. Can be over-ridden with the command line parameter --lib-features
|
||||
lib-features = ["hydrate"]
|
||||
|
||||
# If the --no-default-features flag should be used when compiling the lib target
|
||||
#
|
||||
# Optional. Defaults to false.
|
||||
lib-default-features = false
|
||||
|
||||
# The profile to use for the lib target when compiling for release
|
||||
#
|
||||
# Optional. Defaults to "release".
|
||||
lib-profile-release = "wasm-release"
|
||||
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,86 +0,0 @@
|
||||
<picture>
|
||||
<source srcset="https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_Solid_White.svg" media="(prefers-color-scheme: dark)">
|
||||
<img src="https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_RGB.svg" alt="Leptos Logo">
|
||||
</picture>
|
||||
|
||||
# Leptos Axum Starter Template
|
||||
|
||||
This is a template for use with the [Leptos](https://github.com/leptos-rs/leptos) web framework and the [cargo-leptos](https://github.com/akesson/cargo-leptos) tool using [Axum](https://github.com/tokio-rs/axum).
|
||||
|
||||
## Creating your template repo
|
||||
|
||||
If you don't have `cargo-leptos` installed you can install it with
|
||||
|
||||
```bash
|
||||
cargo install cargo-leptos
|
||||
```
|
||||
|
||||
Then run
|
||||
```bash
|
||||
cargo leptos new --git leptos-rs/start-axum
|
||||
```
|
||||
|
||||
to generate a new project template.
|
||||
|
||||
```bash
|
||||
cd app-1
|
||||
```
|
||||
|
||||
to go to your newly created project.
|
||||
Feel free to explore the project structure, but the best place to start with your application code is in `src/app.rs`.
|
||||
Addtionally, Cargo.toml may need updating as new versions of the dependencies are released, especially if things are not working after a `cargo update`.
|
||||
|
||||
## Running your project
|
||||
|
||||
```bash
|
||||
cargo leptos watch
|
||||
```
|
||||
|
||||
## Installing Additional Tools
|
||||
|
||||
By default, `cargo-leptos` uses `nightly` Rust, `cargo-generate`, and `sass`. If you run into any trouble, you may need to install one or more of these tools.
|
||||
|
||||
1. `rustup toolchain install nightly --allow-downgrade` - make sure you have Rust nightly
|
||||
2. `rustup target add wasm32-unknown-unknown` - add the ability to compile Rust to WebAssembly
|
||||
3. `cargo install cargo-generate` - install `cargo-generate` binary (should be installed automatically in future)
|
||||
4. `npm install -g sass` - install `dart-sass` (should be optional in future
|
||||
|
||||
## Compiling for Release
|
||||
```bash
|
||||
cargo leptos build --release
|
||||
```
|
||||
|
||||
Will generate your server binary in target/server/release and your site package in target/site
|
||||
|
||||
## Testing Your Project
|
||||
```bash
|
||||
cargo leptos end-to-end
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo leptos end-to-end --release
|
||||
```
|
||||
|
||||
Cargo-leptos uses Playwright as the end-to-end test tool.
|
||||
Tests are located in end2end/tests directory.
|
||||
|
||||
## Executing a Server on a Remote Machine Without the Toolchain
|
||||
After running a `cargo leptos build --release` the minimum files needed are:
|
||||
|
||||
1. The server binary located in `target/server/release`
|
||||
2. The `site` directory and all files within located in `target/site`
|
||||
|
||||
Copy these files to your remote server. The directory structure should be:
|
||||
```text
|
||||
app-1
|
||||
site/
|
||||
```
|
||||
Set the following environment variables (updating for your project as needed):
|
||||
```text
|
||||
LEPTOS_OUTPUT_NAME="app-1"
|
||||
LEPTOS_SITE_ROOT="site"
|
||||
LEPTOS_SITE_PKG_DIR="pkg"
|
||||
LEPTOS_SITE_ADDR="127.0.0.1:3000"
|
||||
LEPTOS_RELOAD_PORT="3001"
|
||||
```
|
||||
Finally, run the server binary.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
@@ -1,79 +0,0 @@
|
||||
use crate::error_template::{AppError, ErrorTemplate};
|
||||
use leptos::*;
|
||||
use leptos_meta::*;
|
||||
use leptos_router::*;
|
||||
|
||||
#[component]
|
||||
pub fn App() -> impl IntoView {
|
||||
// Provides context that manages stylesheets, titles, meta tags, etc.
|
||||
provide_meta_context();
|
||||
|
||||
view! {
|
||||
|
||||
|
||||
// injects a stylesheet into the document <head>
|
||||
// id=leptos means cargo-leptos will hot-reload this stylesheet
|
||||
<Stylesheet id="leptos" href="/pkg/app-1.css"/>
|
||||
|
||||
// sets the document title
|
||||
<Title text="Welcome to Leptos"/>
|
||||
|
||||
// content for this welcome page
|
||||
<Router fallback=|| {
|
||||
let mut outside_errors = Errors::default();
|
||||
outside_errors.insert_with_default_key(AppError::NotFound);
|
||||
view! {
|
||||
<ErrorTemplate outside_errors/>
|
||||
}
|
||||
.into_view()
|
||||
}>
|
||||
<main>
|
||||
<Routes>
|
||||
<Route path="" view=HomePage/>
|
||||
</Routes>
|
||||
</main>
|
||||
</Router>
|
||||
}
|
||||
}
|
||||
|
||||
/// Renders the home page of your application.
|
||||
#[component]
|
||||
fn HomePage() -> impl IntoView {
|
||||
use shared_server::SharedServerFunction;
|
||||
use shared_server_2::SharedServerFunction2;
|
||||
|
||||
// A local resource will wait for the client to load before attempting to initialize.
|
||||
let hello_1 = create_local_resource(move || (), |_| shared_server::shared_server_function());
|
||||
// this won't work : let hello_1 = create_resource(move || (), |_| shared_server::shared_server_function());
|
||||
// A resource is initialized on the rendering server when using SSR.
|
||||
|
||||
let hello_1_action = Action::<SharedServerFunction,_>::server();
|
||||
let hello_2_action = Action::<SharedServerFunction2,_>::server();
|
||||
|
||||
let value_1 = create_rw_signal(String::from("waiting for update from shared server."));
|
||||
let value_2 = create_rw_signal(String::from("waiting for update from shared server 2."));
|
||||
|
||||
//let hello_2 = create_resource(move || (), shared_server_2::shared_server_function);
|
||||
create_effect(move|_|{if let Some(Ok(msg)) = hello_1_action.value().get(){value_1.set(msg)}});
|
||||
create_effect(move|_|{if let Some(Ok(msg)) = hello_2_action.value().get(){value_2.set(msg)}});
|
||||
|
||||
view! {
|
||||
<h1> App 1</h1>
|
||||
<div>Suspense</div>
|
||||
<Suspense fallback=move || view! { <p>"Loading (Suspense Fallback)..."</p> }>
|
||||
{move || {
|
||||
hello_1.get().map(|data| match data {
|
||||
Err(_) => view! { <pre>"Error"</pre> }.into_view(),
|
||||
Ok(hello) => hello.into_view(),
|
||||
})
|
||||
}
|
||||
}
|
||||
</Suspense>
|
||||
<div> action response from server 1 </div>
|
||||
<button on:click=move|_|hello_1_action.dispatch(SharedServerFunction{})>request from shared server 1</button>
|
||||
{move || value_1.get()}
|
||||
<div> action response from server 2 </div>
|
||||
<button on:click=move|_|hello_2_action.dispatch(SharedServerFunction2{})>request from shared server 2</button>
|
||||
{move || value_2.get()}
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
use http::status::StatusCode;
|
||||
use leptos::*;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
pub enum AppError {
|
||||
#[error("Not Found")]
|
||||
NotFound,
|
||||
}
|
||||
|
||||
impl AppError {
|
||||
pub fn status_code(&self) -> StatusCode {
|
||||
match self {
|
||||
AppError::NotFound => StatusCode::NOT_FOUND,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A basic function to display errors served by the error boundaries.
|
||||
// Feel free to do more complicated things here than just displaying the error.
|
||||
#[component]
|
||||
pub fn ErrorTemplate(
|
||||
#[prop(optional)] outside_errors: Option<Errors>,
|
||||
#[prop(optional)] errors: Option<RwSignal<Errors>>,
|
||||
) -> impl IntoView {
|
||||
let errors = match outside_errors {
|
||||
Some(e) => create_rw_signal(e),
|
||||
None => match errors {
|
||||
Some(e) => e,
|
||||
None => panic!("No Errors found and we expected errors!"),
|
||||
},
|
||||
};
|
||||
// Get Errors from Signal
|
||||
let errors = errors.get_untracked();
|
||||
|
||||
// Downcast lets us take a type that implements `std::error::Error`
|
||||
let errors: Vec<AppError> = errors
|
||||
.into_iter()
|
||||
.filter_map(|(_k, v)| v.downcast_ref::<AppError>().cloned())
|
||||
.collect();
|
||||
println!("Errors: {errors:#?}");
|
||||
|
||||
// Only the response code for the first error is actually sent from the server
|
||||
// this may be customized by the specific application
|
||||
#[cfg(feature = "ssr")]
|
||||
{
|
||||
use leptos_axum::ResponseOptions;
|
||||
let response = use_context::<ResponseOptions>();
|
||||
if let Some(response) = response {
|
||||
response.set_status(errors[0].status_code());
|
||||
}
|
||||
}
|
||||
|
||||
view! {
|
||||
<h1>{if errors.len() > 1 {"Errors"} else {"Error"}}</h1>
|
||||
<For
|
||||
// a function that returns the items we're iterating over; a signal is fine
|
||||
each= move || {errors.clone().into_iter().enumerate()}
|
||||
// a unique key for each item as a reference
|
||||
key=|(index, _error)| *index
|
||||
// renders each item to a view
|
||||
children=move |error| {
|
||||
let error_string = error.1.to_string();
|
||||
let error_code= error.1.status_code();
|
||||
view! {
|
||||
<h2>{error_code.to_string()}</h2>
|
||||
<p>"Error: " {error_string}</p>
|
||||
}
|
||||
}
|
||||
/>
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
use axum::{
|
||||
body::Body,
|
||||
extract::State,
|
||||
response::IntoResponse,
|
||||
http::{Request, Response, StatusCode, Uri},
|
||||
};
|
||||
use axum::response::Response as AxumResponse;
|
||||
use tower::ServiceExt;
|
||||
use tower_http::services::ServeDir;
|
||||
use leptos::*;
|
||||
use crate::app::App;
|
||||
|
||||
pub async fn file_and_error_handler(uri: Uri, State(options): State<LeptosOptions>, req: Request<Body>) -> AxumResponse {
|
||||
let root = options.site_root.clone();
|
||||
tracing::debug!("APP 1");
|
||||
let res = get_static_file(uri.clone(), &root).await.unwrap();
|
||||
|
||||
if res.status() == StatusCode::OK {
|
||||
res.into_response()
|
||||
} else {
|
||||
let handler = leptos_axum::render_app_to_stream(options.to_owned(), App);
|
||||
handler(req).await.into_response()
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_static_file(
|
||||
uri: Uri,
|
||||
root: &str,
|
||||
) -> Result<Response<Body>, (StatusCode, String)> {
|
||||
let req = Request::builder()
|
||||
.uri(uri.clone())
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
// `ServeDir` implements `tower::Service` so we can call it with `tower::ServiceExt::oneshot`
|
||||
// This path is relative to the cargo root
|
||||
match ServeDir::new(root).oneshot(req).await {
|
||||
Ok(res) => Ok(res.into_response()),
|
||||
Err(err) => Err((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("Something went wrong: {err}"),
|
||||
)),
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
pub mod app;
|
||||
pub mod error_template;
|
||||
#[cfg(feature = "ssr")]
|
||||
pub mod fileserv;
|
||||
|
||||
#[cfg(feature = "hydrate")]
|
||||
#[wasm_bindgen::prelude::wasm_bindgen]
|
||||
pub fn hydrate() {
|
||||
use crate::app::*;
|
||||
console_error_panic_hook::set_once();
|
||||
leptos::mount_to_body(App);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
#[cfg(feature = "ssr")]
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
use axum::Router;
|
||||
use leptos::*;
|
||||
use leptos_axum::{generate_route_list, LeptosRoutes};
|
||||
use app_1::app::*;
|
||||
use app_1::fileserv::file_and_error_handler;
|
||||
use axum::routing::post;
|
||||
|
||||
tracing_subscriber::fmt()
|
||||
.pretty()
|
||||
.with_thread_names(true)
|
||||
// enable everything
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
// sets this to be the default, global collector for this application.
|
||||
.init();
|
||||
|
||||
// Setting get_configuration(None) means we'll be using cargo-leptos's env values
|
||||
// For deployment these variables are:
|
||||
// <https://github.com/leptos-rs/start-axum#executing-a-server-on-a-remote-machine-without-the-toolchain>
|
||||
// Alternately a file can be specified such as Some("Cargo.toml")
|
||||
// The file would need to be included with the executable when moved to deployment
|
||||
let conf = get_configuration(Some("Cargo.toml")).await.unwrap();
|
||||
let leptos_options = conf.leptos_options;
|
||||
let addr = leptos_options.site_addr;
|
||||
let routes = generate_route_list(App);
|
||||
|
||||
// build our application with a route
|
||||
let app = Router::new()
|
||||
.route("/api_app1/*fn_name", post(leptos_axum::handle_server_fns))
|
||||
.leptos_routes(&leptos_options, routes, App)
|
||||
.fallback(file_and_error_handler)
|
||||
.layer(tower_http::trace::TraceLayer::new_for_http())
|
||||
.with_state(leptos_options);
|
||||
|
||||
let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
|
||||
logging::log!("listening on http://{}", &addr);
|
||||
axum::serve(listener, app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
pub fn main() {
|
||||
// no client-side main function
|
||||
// unless we want this to work with e.g., Trunk for a purely client-side app
|
||||
// see lib.rs for hydration function instead
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
13
projects/nginx-mpmc/app-2/.gitignore
vendored
13
projects/nginx-mpmc/app-2/.gitignore
vendored
@@ -1,13 +0,0 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
pkg
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# node e2e test tools and outputs
|
||||
node_modules/
|
||||
test-results/
|
||||
end2end/playwright-report/
|
||||
playwright/.cache/
|
||||
@@ -1,115 +0,0 @@
|
||||
[package]
|
||||
name = "app-2"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
console_error_panic_hook = "0.1"
|
||||
leptos_meta = { version = "0.6" }
|
||||
leptos_router = { version = "0.6" }
|
||||
tower = { version = "0.4", optional = true }
|
||||
tower-http = { version = "0.5", features = ["fs"], optional = true }
|
||||
wasm-bindgen = "=0.2.89"
|
||||
thiserror = "1"
|
||||
tracing = { version = "0.1", optional = true }
|
||||
http = "1"
|
||||
|
||||
axum = {version = "0.7",optional=true}
|
||||
leptos = "0.6"
|
||||
leptos_axum = {version = "0.6",optional=true}
|
||||
tokio = { version = "1", features = ["rt-multi-thread"], optional = true}
|
||||
shared-server = {path = "../shared-server",default-features = false}
|
||||
shared-server-2 = {path = "../shared-server-2",default-features = false}
|
||||
|
||||
# Defines a size-optimized profile for the WASM bundle in release mode
|
||||
[profile.wasm-release]
|
||||
inherits = "release"
|
||||
opt-level = 'z'
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
panic = "abort"
|
||||
|
||||
[features]
|
||||
hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate","shared-server/hydrate","shared-server-2/hydrate"]
|
||||
ssr = [
|
||||
"shared-server/ssr",
|
||||
"shared-server-2/ssr",
|
||||
"dep:axum",
|
||||
"dep:tokio",
|
||||
"dep:tower",
|
||||
"dep:tower-http",
|
||||
"dep:leptos_axum",
|
||||
"leptos/ssr",
|
||||
"leptos_meta/ssr",
|
||||
"leptos_router/ssr",
|
||||
"dep:tracing",
|
||||
]
|
||||
|
||||
|
||||
[package.metadata.leptos]
|
||||
# The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name
|
||||
output-name = "app-2"
|
||||
|
||||
# The site root folder is where cargo-leptos generate all output. WARNING: all content of this folder will be erased on a rebuild. Use it in your server setup.
|
||||
site-root = "target/site"
|
||||
|
||||
#
|
||||
#
|
||||
### WE CHANGED THIS IN THIS EXAMPLE
|
||||
#
|
||||
#
|
||||
site-pkg-dir = "pkg2"
|
||||
|
||||
|
||||
# Assets source dir. All files found here will be copied and synchronized to site-root.
|
||||
# The assets-dir cannot have a sub directory with the same name/path as site-pkg-dir.
|
||||
#
|
||||
# Optional. Env: LEPTOS_ASSETS_DIR.
|
||||
assets-dir = "public"
|
||||
|
||||
# [Optional] The source CSS file. If it ends with .sass or .scss then it will be compiled by dart-sass into CSS. The CSS is optimized by Lightning CSS before being written to <site-root>/<site-pkg>/app.css
|
||||
style-file = "style/main.scss"
|
||||
|
||||
# The IP and port (ex: 127.0.0.1:3000) where the server serves the content. Use it in your server setup.
|
||||
site-addr = "127.0.0.1:3001"
|
||||
|
||||
# The port to use for automatic reload monitoring
|
||||
reload-port = 3005
|
||||
|
||||
|
||||
# The browserlist query used for optimizing the CSS.
|
||||
browserquery = "defaults"
|
||||
|
||||
# Set by cargo-leptos watch when building with that tool. Controls whether autoreload JS will be included in the head
|
||||
watch = false
|
||||
|
||||
# The environment Leptos will run in, usually either "DEV" or "PROD"
|
||||
env = "DEV"
|
||||
|
||||
# The features to use when compiling the bin target
|
||||
#
|
||||
# Optional. Can be over-ridden with the command line parameter --bin-features
|
||||
bin-features = ["ssr"]
|
||||
|
||||
# If the --no-default-features flag should be used when compiling the bin target
|
||||
#
|
||||
# Optional. Defaults to false.
|
||||
bin-default-features = false
|
||||
|
||||
# The features to use when compiling the lib target
|
||||
#
|
||||
# Optional. Can be over-ridden with the command line parameter --lib-features
|
||||
lib-features = ["hydrate"]
|
||||
|
||||
# If the --no-default-features flag should be used when compiling the lib target
|
||||
#
|
||||
# Optional. Defaults to false.
|
||||
lib-default-features = false
|
||||
|
||||
# The profile to use for the lib target when compiling for release
|
||||
#
|
||||
# Optional. Defaults to "release".
|
||||
lib-profile-release = "wasm-release"
|
||||
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user