From 524e0c72bca43fac86f6daab8b186466d9bb21ec Mon Sep 17 00:00:00 2001 From: manuelJung Date: Thu, 28 Mar 2024 22:09:24 +0100 Subject: [PATCH] Svelte shop (#12) * init api * created product-slider * created stores * renamed to svelte-shop --- .../.gitignore | 0 .../.npmrc | 0 .../README.md | 0 .../package.json | 3 +- .../src/app.d.ts | 0 .../src/app.html | 0 .../src/lib/components/ProductSlider.svelte | 32 +++++++++ .../src/lib/index.ts | 0 .../src/lib/stores/account.ts | 66 +++++++++++++++++ .../src/lib/stores/channel.ts | 24 +++++++ .../src/lib/stores/products.ts | 67 ++++++++++++++++++ .../src/routes/+page.svelte | 8 +++ .../src/routes/api/account/+server.ts | 10 +++ .../src/routes/api/account/login/+server.ts | 37 ++++++++++ .../routes/api/account/register/+server.ts | 42 +++++++++++ .../src/routes/api/account/update/+server.ts | 35 +++++++++ .../src/routes/api/cart/+server.ts | 10 +++ .../src/routes/api/cart/add-item/+server.ts | 38 ++++++++++ .../routes/api/cart/delete-item/+server.ts | 28 ++++++++ .../api/cart/set-item-amount/+server.ts | 38 ++++++++++ .../src/routes/api/products/+server.ts | 42 +++++++++++ .../svelte-example-shop/src/server-state.ts | 56 +++++++++++++++ .../svelte-example-shop/src/stores/cart.ts | 53 ++++++++++++++ .../src/stores/counter.ts | 0 .../src/stores/todos.ts | 2 - .../static/favicon.png | Bin .../svelte.config.js | 0 .../tsconfig.json | 0 .../vite.config.ts | 0 .../src/routes/+page.svelte | 40 ----------- yarn.lock | 24 +++++++ 31 files changed, 612 insertions(+), 43 deletions(-) rename packages/{svelte-example-todo => svelte-example-shop}/.gitignore (100%) rename packages/{svelte-example-todo => svelte-example-shop}/.npmrc (100%) rename packages/{svelte-example-todo => svelte-example-shop}/README.md (100%) rename packages/{svelte-example-todo => svelte-example-shop}/package.json (93%) rename packages/{svelte-example-todo => svelte-example-shop}/src/app.d.ts (100%) rename packages/{svelte-example-todo => svelte-example-shop}/src/app.html (100%) create mode 100644 packages/svelte-example-shop/src/lib/components/ProductSlider.svelte rename packages/{svelte-example-todo => svelte-example-shop}/src/lib/index.ts (100%) create mode 100644 packages/svelte-example-shop/src/lib/stores/account.ts create mode 100644 packages/svelte-example-shop/src/lib/stores/channel.ts create mode 100644 packages/svelte-example-shop/src/lib/stores/products.ts create mode 100644 packages/svelte-example-shop/src/routes/+page.svelte create mode 100644 packages/svelte-example-shop/src/routes/api/account/+server.ts create mode 100644 packages/svelte-example-shop/src/routes/api/account/login/+server.ts create mode 100644 packages/svelte-example-shop/src/routes/api/account/register/+server.ts create mode 100644 packages/svelte-example-shop/src/routes/api/account/update/+server.ts create mode 100644 packages/svelte-example-shop/src/routes/api/cart/+server.ts create mode 100644 packages/svelte-example-shop/src/routes/api/cart/add-item/+server.ts create mode 100644 packages/svelte-example-shop/src/routes/api/cart/delete-item/+server.ts create mode 100644 packages/svelte-example-shop/src/routes/api/cart/set-item-amount/+server.ts create mode 100644 packages/svelte-example-shop/src/routes/api/products/+server.ts create mode 100644 packages/svelte-example-shop/src/server-state.ts create mode 100644 packages/svelte-example-shop/src/stores/cart.ts rename packages/{svelte-example-todo => svelte-example-shop}/src/stores/counter.ts (100%) rename packages/{svelte-example-todo => svelte-example-shop}/src/stores/todos.ts (96%) rename packages/{svelte-example-todo => svelte-example-shop}/static/favicon.png (100%) rename packages/{svelte-example-todo => svelte-example-shop}/svelte.config.js (100%) rename packages/{svelte-example-todo => svelte-example-shop}/tsconfig.json (100%) rename packages/{svelte-example-todo => svelte-example-shop}/vite.config.ts (100%) delete mode 100644 packages/svelte-example-todo/src/routes/+page.svelte diff --git a/packages/svelte-example-todo/.gitignore b/packages/svelte-example-shop/.gitignore similarity index 100% rename from packages/svelte-example-todo/.gitignore rename to packages/svelte-example-shop/.gitignore diff --git a/packages/svelte-example-todo/.npmrc b/packages/svelte-example-shop/.npmrc similarity index 100% rename from packages/svelte-example-todo/.npmrc rename to packages/svelte-example-shop/.npmrc diff --git a/packages/svelte-example-todo/README.md b/packages/svelte-example-shop/README.md similarity index 100% rename from packages/svelte-example-todo/README.md rename to packages/svelte-example-shop/README.md diff --git a/packages/svelte-example-todo/package.json b/packages/svelte-example-shop/package.json similarity index 93% rename from packages/svelte-example-todo/package.json rename to packages/svelte-example-shop/package.json index aea4faf..081c4c2 100644 --- a/packages/svelte-example-todo/package.json +++ b/packages/svelte-example-shop/package.json @@ -22,6 +22,7 @@ }, "type": "module", "dependencies": { - "immer": "^10.0.4" + "immer": "^10.0.4", + "validate": "^5.2.0" } } diff --git a/packages/svelte-example-todo/src/app.d.ts b/packages/svelte-example-shop/src/app.d.ts similarity index 100% rename from packages/svelte-example-todo/src/app.d.ts rename to packages/svelte-example-shop/src/app.d.ts diff --git a/packages/svelte-example-todo/src/app.html b/packages/svelte-example-shop/src/app.html similarity index 100% rename from packages/svelte-example-todo/src/app.html rename to packages/svelte-example-shop/src/app.html diff --git a/packages/svelte-example-shop/src/lib/components/ProductSlider.svelte b/packages/svelte-example-shop/src/lib/components/ProductSlider.svelte new file mode 100644 index 0000000..adeedca --- /dev/null +++ b/packages/svelte-example-shop/src/lib/components/ProductSlider.svelte @@ -0,0 +1,32 @@ + + +
+ {#each $hits as hit} +
+

{hit.name}

+

{hit.price}€

+
+ {/each} +
+ + + \ No newline at end of file diff --git a/packages/svelte-example-todo/src/lib/index.ts b/packages/svelte-example-shop/src/lib/index.ts similarity index 100% rename from packages/svelte-example-todo/src/lib/index.ts rename to packages/svelte-example-shop/src/lib/index.ts diff --git a/packages/svelte-example-shop/src/lib/stores/account.ts b/packages/svelte-example-shop/src/lib/stores/account.ts new file mode 100644 index 0000000..c33b4a8 --- /dev/null +++ b/packages/svelte-example-shop/src/lib/stores/account.ts @@ -0,0 +1,66 @@ +import createStore from "@rlx/svelte"; +import { Customer } from "../../server-state"; + +declare global { + interface RlxStores { + account: ReturnType + } +} + +export default function createAccountStore () { + const store = createStore({ + name: 'account', + persist: true, + state: { + user: null as Customer | null, + initialFetched: false, + fetchError: null as string | null, + isLoggingIn: false, + }, + actions: { + /** comment */ + initialFetch: () => ({ + triggerOnMount: true, + fetcher: () => fetch('/api/account'), + mapResponse: r => ({ user: r, initialFetched: true }), + }), + login: (email: string, password: string) => ({ + fetcher: () => fetch('/api/account/login', { email, password }), + concurrency: 'FIRST', + mappings: { data: 'user', isFetching: 'isLoggingIn'} + }), + logout: () => ({ + fetcher: () => fetch('/api/account/logout').then(r => r.json()), + concurrency: 'FIRST', + optimisticData: () => ({ user: null }), + }), + register: (email: string, password: string) => ({ + fetcher: () => fetch('/api/account/register', { email, password }), + concurrency: 'FIRST', + mappings: { data: 'user' } + }), + updateUser: (user:{name:string}) => ({ + fetcher: () => fetch('/api/account/update', user), + optimisticData: (state) => ({ user: {...state.user, ...user} }), + concurrency: 'LAST', + mappings: { data: 'user' } + }), + } + }) + + store.addRule({ + id: 'log-user', + target: 'account/login/request', + consequence: ({action, store}) => store.actions.initialFetch() + }) + + return store +} + +function fetch(url: string, body:any=null) { + return window.fetch(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body) + }).then(r => r.json()) +} \ No newline at end of file diff --git a/packages/svelte-example-shop/src/lib/stores/channel.ts b/packages/svelte-example-shop/src/lib/stores/channel.ts new file mode 100644 index 0000000..ea32199 --- /dev/null +++ b/packages/svelte-example-shop/src/lib/stores/channel.ts @@ -0,0 +1,24 @@ +import createStore from "@rlx/svelte"; + +export type Channel = 'b2b' | 'b2c' + +export default function createChannelStore() { + const store = createStore({ + name: 'channel', + persist: true, + state: { + data: 'b2b' as Channel + }, + actions: { + set: (channel: Channel) => state => ({data:channel}) + } + }) + + store.addRule({ + id: 'log-set', + target: ['account/login/success', 'account/initialFetch/success'], + consequence: ({store}) => store.actions.set('b2b') + }) + + return store +} \ No newline at end of file diff --git a/packages/svelte-example-shop/src/lib/stores/products.ts b/packages/svelte-example-shop/src/lib/stores/products.ts new file mode 100644 index 0000000..b347ec4 --- /dev/null +++ b/packages/svelte-example-shop/src/lib/stores/products.ts @@ -0,0 +1,67 @@ +import createStore from "@rlx/svelte" +import type { Product } from "../../server-state" + +export type FilterValues = { + search: string + color: string +} + +declare global { + interface RlxStores { + products: ReturnType + } +} + +export default function createProductStore(name:string, filterValues: Partial = {}) { + const store = createStore({ + name: 'products', + key: name, + state: { + data: [] as Product[], + isFetching: false, + fetchError: null as string | null, + filterValues: { + search: '', + color: '', + ...filterValues + } satisfies FilterValues as FilterValues + }, + actions: { + fetch: () => ({ + triggerOnMount: true, + concurrency: 'SWITCH', + fetcher: state => fetchProducts(state.filterValues), + mapResponse: (response, state) => ({ + ...state, + data: response.hits, + isFetching: false, + }) + }), + /** my comment */ + setFilterValue: (key: keyof FilterValues, value: string) => state => ({ + filterValues: { + ...state.filterValues, + [key]: value + } + }) + } + }) + + store.addRule({ + id: 'trigger-fetch', + target: '/setFilterValue', + consequence: (args) => args.store.actions.fetch() + }) + + return store +} + +async function fetchProducts(filterValues: FilterValues) { + const url = new URL('/api/products', window.location.href) + + const body = JSON.stringify(filterValues) + + return fetch(url, {method: 'POST', body}).then(res => res.json()) as Promise<{ + hits: Product[] + }> +} \ No newline at end of file diff --git a/packages/svelte-example-shop/src/routes/+page.svelte b/packages/svelte-example-shop/src/routes/+page.svelte new file mode 100644 index 0000000..c40ce31 --- /dev/null +++ b/packages/svelte-example-shop/src/routes/+page.svelte @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/packages/svelte-example-shop/src/routes/api/account/+server.ts b/packages/svelte-example-shop/src/routes/api/account/+server.ts new file mode 100644 index 0000000..4f4a96e --- /dev/null +++ b/packages/svelte-example-shop/src/routes/api/account/+server.ts @@ -0,0 +1,10 @@ +import serverState, { type Customer } from '../../../server-state.js'; +import Schema from 'validate' + +/** @type {import('./$types').RequestHandler} */ +export async function POST (params) { + + const customer = serverState.customers.find(c => c.email === serverState.currentCustomerId) ?? null + + return new Response(JSON.stringify(customer)) +} \ No newline at end of file diff --git a/packages/svelte-example-shop/src/routes/api/account/login/+server.ts b/packages/svelte-example-shop/src/routes/api/account/login/+server.ts new file mode 100644 index 0000000..9848cf6 --- /dev/null +++ b/packages/svelte-example-shop/src/routes/api/account/login/+server.ts @@ -0,0 +1,37 @@ +import serverState, { type Customer } from '../../../../server-state.js'; +import Schema from 'validate' + +const schema = new Schema({ + email: { + type: 'string', + required: true + }, + password: { + type: 'string', + required: true + } +}) + +/** @type {import('./$types').RequestHandler} */ +export async function POST (params) { + const body = await params.request.json() as { + email: string + password: string + } + + const errors = schema.validate(body) + if (errors.length) { + return new Response(JSON.stringify(errors), { status: 400 }) + } + + const customer = serverState.customers.find(c => c.email === body.email) + + if (!customer) { + return new Response(JSON.stringify({error: 'Customer does not exist'}), { status: 400 }) + } + + serverState.customers.push(customer) + serverState.currentCustomerId = customer.id + + return new Response(JSON.stringify(customer)) +} \ No newline at end of file diff --git a/packages/svelte-example-shop/src/routes/api/account/register/+server.ts b/packages/svelte-example-shop/src/routes/api/account/register/+server.ts new file mode 100644 index 0000000..358f05a --- /dev/null +++ b/packages/svelte-example-shop/src/routes/api/account/register/+server.ts @@ -0,0 +1,42 @@ +import serverState, { type Customer } from '../../../../server-state.js'; +import Schema from 'validate' + +const schema = new Schema({ + email: { + type: 'string', + required: true + }, + password: { + type: 'string', + required: true + } +}) + +/** @type {import('./$types').RequestHandler} */ +export async function POST (params) { + const body = await params.request.json() as { + email: string + password: string + } + + const errors = schema.validate(body) + if (errors.length) { + return new Response(JSON.stringify(errors), { status: 400 }) + } + + if (serverState.customers.find(c => c.email === body.email)) { + return new Response(JSON.stringify({error: 'Customer already exists'}), { status: 400 }) + } + + const customer:Customer = { + email: body.email, + password: body.password, + id: Math.random().toString(36).substring(7), + name: 'INITIAL' + } + + serverState.customers.push(customer) + serverState.currentCustomerId = customer.id + + return new Response(JSON.stringify(customer)) +} \ No newline at end of file diff --git a/packages/svelte-example-shop/src/routes/api/account/update/+server.ts b/packages/svelte-example-shop/src/routes/api/account/update/+server.ts new file mode 100644 index 0000000..a2a72f4 --- /dev/null +++ b/packages/svelte-example-shop/src/routes/api/account/update/+server.ts @@ -0,0 +1,35 @@ +import serverState, { type Customer } from '../../../../server-state.js'; +import Schema from 'validate' + +const schema = new Schema({ + name: { + type: 'string', + required: false + }, +}) + +/** @type {import('./$types').RequestHandler} */ +export async function POST (params) { + const body = await params.request.json() as { + name?: string + } + + const errors = schema.validate(body) + if (errors.length) { + return new Response(JSON.stringify(errors), { status: 400 }) + } + + if(serverState.currentCustomerId === null) { + return new Response(JSON.stringify({error: 'Not logged in'}), { status: 401 }) + } + + const customer = serverState.customers.find(c => c.id === serverState.currentCustomerId) + + if (!customer) { + return new Response(JSON.stringify({error: 'Customer does not exist'}), { status: 400 }) + } + + if(body.name) customer.name = body.name + + return new Response(JSON.stringify(customer)) +} \ No newline at end of file diff --git a/packages/svelte-example-shop/src/routes/api/cart/+server.ts b/packages/svelte-example-shop/src/routes/api/cart/+server.ts new file mode 100644 index 0000000..dfe248f --- /dev/null +++ b/packages/svelte-example-shop/src/routes/api/cart/+server.ts @@ -0,0 +1,10 @@ +import serverState, { type Customer } from '../../../server-state.js'; +import Schema from 'validate' + +/** @type {import('./$types').RequestHandler} */ +export async function POST (params) { + + const cart = serverState.cart + + return new Response(JSON.stringify(cart)) +} \ No newline at end of file diff --git a/packages/svelte-example-shop/src/routes/api/cart/add-item/+server.ts b/packages/svelte-example-shop/src/routes/api/cart/add-item/+server.ts new file mode 100644 index 0000000..3ea59c1 --- /dev/null +++ b/packages/svelte-example-shop/src/routes/api/cart/add-item/+server.ts @@ -0,0 +1,38 @@ +import serverState from '../../../../server-state.js'; +import Schema from 'validate' + +const schema = new Schema({ + productID: { + type: 'string', + required: true + }, + amount: { + type: 'number', + required: true + } +}) + +/** @type {import('./$types').RequestHandler} */ +export async function POST (params) { + const body = await params.request.json() as { productID: string, amount: number } + + const errors = schema.validate(body) + if (errors.length) { + return new Response(JSON.stringify(errors), { status: 400 }) + } + + if (serverState.cart.find(item => item.productID === body.productID)) { + serverState.cart = serverState.cart.map(item => { + if (item.productID === body.productID) { + item.amount += body.amount + } + return item + }) + } + else { + serverState.cart.push(body) + } + + + return new Response(JSON.stringify(serverState.cart)) +} \ No newline at end of file diff --git a/packages/svelte-example-shop/src/routes/api/cart/delete-item/+server.ts b/packages/svelte-example-shop/src/routes/api/cart/delete-item/+server.ts new file mode 100644 index 0000000..02176d7 --- /dev/null +++ b/packages/svelte-example-shop/src/routes/api/cart/delete-item/+server.ts @@ -0,0 +1,28 @@ +import serverState from '../../../../server-state.js'; +import Schema from 'validate' + +const schema = new Schema({ + productID: { + type: 'string', + required: true + }, +}) + +/** @type {import('./$types').RequestHandler} */ +export async function POST (params) { + const body = await params.request.json() as { productID: string } + + const errors = schema.validate(body) + if (errors.length) { + return new Response(JSON.stringify(errors), { status: 400 }) + } + + const prevLength = serverState.cart.length + serverState.cart = serverState.cart.filter(item => item.productID !== body.productID) + + if (prevLength === serverState.cart.length) { + return new Response(JSON.stringify({error: 'Product not found in cart'}), { status: 400 }) + } + + return new Response(JSON.stringify(serverState.cart)) +} \ No newline at end of file diff --git a/packages/svelte-example-shop/src/routes/api/cart/set-item-amount/+server.ts b/packages/svelte-example-shop/src/routes/api/cart/set-item-amount/+server.ts new file mode 100644 index 0000000..f71e589 --- /dev/null +++ b/packages/svelte-example-shop/src/routes/api/cart/set-item-amount/+server.ts @@ -0,0 +1,38 @@ +import serverState from '../../../../server-state.js'; +import Schema from 'validate' + +const schema = new Schema({ + productID: { + type: 'string', + required: true + }, + amount: { + type: 'number', + required: true + } +}) + +/** @type {import('./$types').RequestHandler} */ +export async function POST (params) { + const body = await params.request.json() as { productID: string, amount: number } + + const errors = schema.validate(body) + if (errors.length) { + return new Response(JSON.stringify(errors), { status: 400 }) + } + + if (serverState.cart.find(item => item.productID === body.productID)) { + serverState.cart = serverState.cart.map(item => { + if (item.productID === body.productID) { + item.amount = body.amount + } + return item + }) + } + else { + return new Response(JSON.stringify({error: 'Product not found in cart'}), { status: 400 }) + } + + + return new Response(JSON.stringify(serverState.cart)) +} \ No newline at end of file diff --git a/packages/svelte-example-shop/src/routes/api/products/+server.ts b/packages/svelte-example-shop/src/routes/api/products/+server.ts new file mode 100644 index 0000000..5b3399d --- /dev/null +++ b/packages/svelte-example-shop/src/routes/api/products/+server.ts @@ -0,0 +1,42 @@ +import Schema from 'validate'; +import serverState from '../../../server-state.js'; + +const schema = new Schema({ + color: { + type: 'string', + required: false + }, + search: { + type: 'string', + required: false + }, + containerID: { + type: 'string', + required: false + } +}) + +/** @type {import('./$types').RequestHandler} */ +export async function fallback (params) { + const body = await params.request.json() as { + color?: string + search?: string + containerID?: string + } + + const errors = schema.validate(body) + if (errors.length) { + return new Response(JSON.stringify(errors), { status: 400 }) + } + + const products = serverState.products.filter(product => { + if (body.color && product.color !== body.color) return false + if (body.search && !product.name.includes(body.search)) return false + if (body.containerID && product.containerID !== body.containerID) return false + return true + }) + + return new Response(JSON.stringify({ + hits: products + })) +} \ No newline at end of file diff --git a/packages/svelte-example-shop/src/server-state.ts b/packages/svelte-example-shop/src/server-state.ts new file mode 100644 index 0000000..c980ef7 --- /dev/null +++ b/packages/svelte-example-shop/src/server-state.ts @@ -0,0 +1,56 @@ + +const serverState:ServerState = { + currentCustomerId: null, + customers: [], + cart: [], + products: [ + { + id: '1', + containerID: '1', + name: 'Shirt', + price: 20, + color: 'blue', + size: 42 + }, + { + id: '2', + containerID: '2', + name: 'Pants', + price: 30, + color: 'black', + size: 32 + } + ] +} + + +export default serverState + + +export type ServerState = { + products: Product[] + customers: Customer[] + cart: Cart + currentCustomerId: string | null +} + +export type Cart = { + productID: string + amount: number +}[] + +export type Customer = { + id: string + name: string + email: string + password: string +} + +export type Product = { + id: string + containerID: string + name: string + price: number + color: string + size: number +} \ No newline at end of file diff --git a/packages/svelte-example-shop/src/stores/cart.ts b/packages/svelte-example-shop/src/stores/cart.ts new file mode 100644 index 0000000..6a2f172 --- /dev/null +++ b/packages/svelte-example-shop/src/stores/cart.ts @@ -0,0 +1,53 @@ +import createStore from "@rlx/svelte"; + +export default function createCartStore () { + const store = createStore({ + name: 'cart', + persist: true, + state: { + items: [] as string[], + initiallyFetched: false, + fetchError: null as string | null, + isUpdating: false, + updateError: null as string | null, + }, + actions: { + initialFetch: () => ({ + triggerOnMount: true, + fetcher: () => fetch('/api/cart'), + mapResponse: r => ({ items: r.items, initiallyFetched: true }), + }), + addItem: (productID: string, amount:number) => ({ + fetcher: () => fetch('/api/cart/add', { productID, amount }), + mappings: { data: 'items', isFetching: 'isUpdating', fetchError: 'updateError' }, + concurrency: 'FIRST', + }), + removeItem: (productID: string) => ({ + fetcher: () => fetch('/api/cart/remove', { productID }), + mappings: { data: 'items', isFetching: 'isUpdating', fetchError: 'updateError' }, + concurrency: 'FIRST', + }), + setItemAmount: (productID: string, amount:number) => ({ + fetcher: () => fetch('/api/cart/set', { productID, amount }), + mappings: { data: 'items', isFetching: 'isUpdating', fetchError: 'updateError' }, + concurrency: 'FIRST', + }), + } + }) + + store.addRule({ + id: 'log-user', + target: 'account/login/success', + consequence: ({action, store}) => store.actions.initialFetch() + }) + + return store +} + +function fetch(url: string, body:any=null) { + return window.fetch(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body) + }).then(r => r.json()) +} \ No newline at end of file diff --git a/packages/svelte-example-todo/src/stores/counter.ts b/packages/svelte-example-shop/src/stores/counter.ts similarity index 100% rename from packages/svelte-example-todo/src/stores/counter.ts rename to packages/svelte-example-shop/src/stores/counter.ts diff --git a/packages/svelte-example-todo/src/stores/todos.ts b/packages/svelte-example-shop/src/stores/todos.ts similarity index 96% rename from packages/svelte-example-todo/src/stores/todos.ts rename to packages/svelte-example-shop/src/stores/todos.ts index 45c5918..dcc96bb 100644 --- a/packages/svelte-example-todo/src/stores/todos.ts +++ b/packages/svelte-example-shop/src/stores/todos.ts @@ -42,14 +42,12 @@ export default function createTodoStore () { }) store.addRule({ - // @ts-expect-error id: 'log-add', target: 'todos/add', consequence: ({action}) => console.log(action) }) store.addRule({ - // @ts-expect-error id: 'log-remove', target: 'todos/remove', consequence: ({action}) => console.log(action) diff --git a/packages/svelte-example-todo/static/favicon.png b/packages/svelte-example-shop/static/favicon.png similarity index 100% rename from packages/svelte-example-todo/static/favicon.png rename to packages/svelte-example-shop/static/favicon.png diff --git a/packages/svelte-example-todo/svelte.config.js b/packages/svelte-example-shop/svelte.config.js similarity index 100% rename from packages/svelte-example-todo/svelte.config.js rename to packages/svelte-example-shop/svelte.config.js diff --git a/packages/svelte-example-todo/tsconfig.json b/packages/svelte-example-shop/tsconfig.json similarity index 100% rename from packages/svelte-example-todo/tsconfig.json rename to packages/svelte-example-shop/tsconfig.json diff --git a/packages/svelte-example-todo/vite.config.ts b/packages/svelte-example-shop/vite.config.ts similarity index 100% rename from packages/svelte-example-todo/vite.config.ts rename to packages/svelte-example-shop/vite.config.ts diff --git a/packages/svelte-example-todo/src/routes/+page.svelte b/packages/svelte-example-todo/src/routes/+page.svelte deleted file mode 100644 index dd17d6d..0000000 --- a/packages/svelte-example-todo/src/routes/+page.svelte +++ /dev/null @@ -1,40 +0,0 @@ - - - - - -

Add Todo

- -
todoStore.actions.add(newTodo)}> - - -
- -
- -{#each $todos as todo} -
- todoStore.actions.toggle(todo.id)} - /> - {todo.text} - -
- {#if todo.completed} - Completed - {/if} - -{/each} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index e9d9f01..d6ddd3b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -312,6 +312,11 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@eivifj/dot@^1.0.1": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@eivifj/dot/-/dot-1.0.3.tgz#b3a6d9662cd84ff4105e0f05620d1045e9d0d9fc" + integrity sha512-UE2x9N7XD/1qqtXA+4CZPD1RQAlM0lEdXdy09CJ/wNR+mgGKqwLRH4BGGfOAWwwz06pIT3c2tC4gvXbntGAeMA== + "@esbuild/aix-ppc64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" @@ -1492,6 +1497,11 @@ color-name@~1.1.4: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +component-type@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-type/-/component-type-1.2.1.tgz#8a47901700238e4fc32269771230226f24b415a9" + integrity sha512-Kgy+2+Uwr75vAi6ChWXgHuLvd+QLD7ssgpaRq2zCvt80ptvAfMc/hijcJxXkBa2wMlEZcJvC2H8Ubo+A9ATHIg== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" @@ -3371,6 +3381,11 @@ type-fest@^0.21.3: resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== +typecast@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/typecast/-/typecast-0.0.1.tgz#fffb75dcb6bdf1def8e293b6b6e893d6c1ed19de" + integrity sha512-L2f5OCLKsJdCjSyN0d5O6CkNxhiC8EQ2XlXnHpWZVNfF+mj2OTaXhAVnP0/7SY/sxO1DHZpOFMpIuGlFUZEGNA== + typescript@^5.0.0, typescript@^5.0.3: version "5.4.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372" @@ -3403,6 +3418,15 @@ v8-to-istanbul@^9.0.1: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" +validate@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/validate/-/validate-5.2.0.tgz#fe7355c1644092b67dd07731ad5716cb99f689a5" + integrity sha512-pVADd6GfDT7bALYvvzhfHnfmxCDem2bG7lGY3mwHzY7ktMH/SaczoF+eKkGokQEdGKozkJvyuOiSfQEHXp4zIA== + dependencies: + "@eivifj/dot" "^1.0.1" + component-type "1.2.1" + typecast "0.0.1" + vite@^5.0.11, vite@^5.0.3: version "5.1.6" resolved "https://registry.yarnpkg.com/vite/-/vite-5.1.6.tgz#706dae5fab9e97f57578469eef1405fc483943e4"