diff --git a/examples/guestbook-solid-js/README.md b/examples/guestbook-solid-js/README.md new file mode 100644 index 0000000..ecef389 --- /dev/null +++ b/examples/guestbook-solid-js/README.md @@ -0,0 +1,3 @@ +# Solid JS + TypeScript + Vite + SQLSync + +This template provides a minimal setup to get SQLSync working with Solid JS and Vite. diff --git a/examples/guestbook-solid-js/index.html b/examples/guestbook-solid-js/index.html new file mode 100644 index 0000000..74ce165 --- /dev/null +++ b/examples/guestbook-solid-js/index.html @@ -0,0 +1,15 @@ + + + + + + + SQLSync + Vite + Solid JS + TS + + + +
if nothing renders, open the console
+ + + + \ No newline at end of file diff --git a/examples/guestbook-solid-js/package.json b/examples/guestbook-solid-js/package.json new file mode 100644 index 0000000..ced4a85 --- /dev/null +++ b/examples/guestbook-solid-js/package.json @@ -0,0 +1,24 @@ +{ + "name": "guestbook-react", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@orbitinghail/sqlsync-solid-js": "workspace:*", + "@orbitinghail/sqlsync-worker": "workspace:*", + "uuid": "^9.0.1", + "solid-js": "^1.8.7" + }, + "devDependencies": { + "@types/uuid": "^9.0.6", + "vite-plugin-solid": "^2.7.0", + "typescript": "^5.2.2", + "vite": "^4.5.0", + "vitest": "^0.34.6" + } +} diff --git a/examples/guestbook-solid-js/src/doctype.ts b/examples/guestbook-solid-js/src/doctype.ts new file mode 100644 index 0000000..82dda55 --- /dev/null +++ b/examples/guestbook-solid-js/src/doctype.ts @@ -0,0 +1,29 @@ +import { createDocHooks } from "@orbitinghail/sqlsync-solid-js"; +import { DocType, serializeMutationAsJSON } from "@orbitinghail/sqlsync-worker"; + +const REDUCER_URL = new URL( + "../../../target/wasm32-unknown-unknown/release/reducer_guestbook.wasm", + import.meta.url, +); + +// Must match the Mutation type in the Rust Reducer code +export type Mutation = + | { + tag: "InitSchema"; + } + | { + tag: "AddMessage"; + id: string; + msg: string; + } + | { + tag: "DeleteMessage"; + id: string; + }; + +export const TaskDocType: DocType = { + reducerUrl: REDUCER_URL, + serializeMutation: serializeMutationAsJSON, +}; + +export const { useMutate, useQuery, useSetConnectionEnabled } = createDocHooks(() => TaskDocType); diff --git a/examples/guestbook-solid-js/src/main.tsx b/examples/guestbook-solid-js/src/main.tsx new file mode 100644 index 0000000..856a5f5 --- /dev/null +++ b/examples/guestbook-solid-js/src/main.tsx @@ -0,0 +1,114 @@ +import { SQLSyncProvider } from "@orbitinghail/sqlsync-solid-js"; +import { journalIdFromString, sql } from "@orbitinghail/sqlsync-worker"; + +// this example uses the uuid library (`npm install uuid`) +import { JSX } from "solid-js/jsx-runtime"; +import { v4 as uuidv4 } from "uuid"; + +// You'll need to configure your build system to make these entrypoints +// available as urls. Vite does this automatically via the `?url` and `?worker&url` suffix. +import sqlSyncWasmUrl from "@orbitinghail/sqlsync-worker/sqlsync.wasm?url"; +import workerUrl from "@orbitinghail/sqlsync-worker/worker.ts?worker&url"; + +import { createEffect, createSignal } from "solid-js"; +import { For, render } from "solid-js/web"; +import { useMutate, useQuery } from "./doctype"; + +// Create a DOC_ID to use, each DOC_ID will correspond to a different SQLite +// database. We use a static doc id so we can play with cross-tab sync. +const DOC_ID = journalIdFromString("VM7fC4gKxa52pbdtrgd9G9"); + +// Use SQLSync hooks in your app +export function App() { + // we will use the standard useState hook to handle the message input box + const [msg, setMsg] = createSignal(""); + + // create a mutate function for our document + const mutate = useMutate(DOC_ID); + + // initialize the schema; eventually this will be handled by SQLSync automatically + createEffect(() => { + mutate({ tag: "InitSchema" }).catch((err) => { + console.error("Failed to init schema", err); + }); + }); + + // create a callback which knows how to trigger the add message mutation + const handleSubmit: JSX.EventHandler = (e) => { + // Prevent the browser from reloading the page + e.preventDefault(); + + // create a unique message id + const id = crypto.randomUUID ? crypto.randomUUID() : uuidv4(); + + // don't add empty messages + if (msg().trim() !== "") { + mutate({ tag: "AddMessage", id, msg: msg() }).catch((err) => { + console.error("Failed to add message", err); + }); + // clear the message + setMsg(""); + } + }; + + // create a callback to delete a message + const handleDelete = (id: string) => { + mutate({ tag: "DeleteMessage", id }).catch((err) => { + console.error("Failed to delete message", err); + }); + }; + + // finally, query SQLSync for all the messages, sorted by created_at + const queryState = useQuery<{ id: string; msg: string }>( + () => DOC_ID, + () => sql` + select id, msg from messages + order by created_at + `, + ); + + const rows = () => queryState().rows ?? []; + + return ( +
+

Guestbook:

+
    + + {(row) => { + return ( +
  • + {row.msg} + +
  • + ); + }} +
    +
+

Leave a message:

+
+ + +
+
+ ); +} + +// Configure the SQLSync provider near the top of the React tree +render( + () => ( + + + + ), + // biome-ignore lint/style/noNonNullAssertion: we know this element exists + document.getElementById("root")!, +); diff --git a/examples/guestbook-solid-js/tsconfig.json b/examples/guestbook-solid-js/tsconfig.json new file mode 100644 index 0000000..d5f246b --- /dev/null +++ b/examples/guestbook-solid-js/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "ES2021.WeakRef", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + "types": ["vite/client"], + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/examples/guestbook-solid-js/tsconfig.node.json b/examples/guestbook-solid-js/tsconfig.node.json new file mode 100644 index 0000000..42872c5 --- /dev/null +++ b/examples/guestbook-solid-js/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/examples/guestbook-solid-js/vite.config.ts b/examples/guestbook-solid-js/vite.config.ts new file mode 100644 index 0000000..e76f7d8 --- /dev/null +++ b/examples/guestbook-solid-js/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import solid from "vite-plugin-solid"; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [solid()], +}); diff --git a/justfile b/justfile index 83a3164..e10180e 100644 --- a/justfile +++ b/justfile @@ -44,6 +44,9 @@ wasm-examples-reducer-guestbook: example-guestbook-react: wasm-examples-reducer-guestbook cd examples/guestbook-react && pnpm dev +example-guestbook-solid-js: wasm-examples-reducer-guestbook + cd examples/guestbook-solid-js && pnpm dev + test-end-to-end-local rng_seed="": wasm-task-reducer RUST_BACKTRACE=1 cargo run --example end-to-end-local {{rng_seed}} @@ -59,6 +62,9 @@ node_modules: package-sqlsync-react: cd lib/sqlsync-react && pnpm build +package-sqlsync-solid-js: + cd lib/sqlsync-solid-js && pnpm build + package-sqlsync-worker target='release': #!/usr/bin/env bash if [[ '{{target}}' = 'release' ]]; then diff --git a/lib/sqlsync-react/tsconfig.json b/lib/sqlsync-react/tsconfig.json index 56a3e59..7592ab3 100644 --- a/lib/sqlsync-react/tsconfig.json +++ b/lib/sqlsync-react/tsconfig.json @@ -3,8 +3,7 @@ "target": "esnext", "module": "esnext", "moduleResolution": "Bundler", - "baseUrl": ".", - "lib": ["ES6", "DOM", "ES2021.WeakRef"], + "lib": ["ES6", "DOM", "DOM.Iterable", "ES2021.WeakRef"], /* Compiling */ "allowJs": true, diff --git a/lib/sqlsync-solid-js/package.json b/lib/sqlsync-solid-js/package.json new file mode 100644 index 0000000..3a1ea76 --- /dev/null +++ b/lib/sqlsync-solid-js/package.json @@ -0,0 +1,65 @@ +{ + "name": "@orbitinghail/sqlsync-solid-js", + "version": "0.2.0", + "description": "SQLSync is a collaborative offline-first wrapper around SQLite. It is designed to synchronize web application state between users, devices, and the edge.", + "homepage": "https://sqlsync.dev", + "license": "Apache-2.0", + "keywords": [ + "sqlsync", + "sql", + "database", + "sqlite", + "offline-first", + "local-first", + "solid-js" + ], + "repository": { + "type": "git", + "url": "https://github.com/orbitinghail/sqlsync" + }, + "files": [ + "dist", + "src" + ], + "type": "module", + "types": "./src/index.ts", + "main": "./src/index.ts", + "exports": { + ".": { + "import": "./src/index.ts", + "default": "./src/index.ts", + "types": "./src/index.ts" + } + }, + "publishConfig": { + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.js", + "default": "./dist/index.js", + "types": "./dist/index.d.ts" + } + } + }, + "scripts": { + "build": "rollup --config" + }, + "devDependencies": { + "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-typescript": "^11.1.5", + "@types/node": "^20.8.8", + "babel-preset-solid": "^1.8.8", + "@orbitinghail/sqlsync-worker": "workspace:^", + "rollup": "^3.29.4", + "typescript": "^5.2.2" + }, + "dependencies": { + "fast-equals": "^5.0.1" + }, + "peerDependencies": { + "solid-js": "^1.8.7", + "@orbitinghail/sqlsync-worker": "workspace:^" + } +} diff --git a/lib/sqlsync-solid-js/rollup.config.js b/lib/sqlsync-solid-js/rollup.config.js new file mode 100644 index 0000000..a034c62 --- /dev/null +++ b/lib/sqlsync-solid-js/rollup.config.js @@ -0,0 +1,23 @@ +import babel from "@rollup/plugin-babel"; +import { nodeResolve } from "@rollup/plugin-node-resolve"; +import typescript from "@rollup/plugin-typescript"; + +export default { + input: "src/index.ts", + output: { + dir: "dist", + format: "es", + sourcemap: true, + }, + external: ["solid-js", "@orbitinghail/sqlsync-worker"], + plugins: [ + typescript(), + nodeResolve(), + babel({ + extensions: [".ts", ".tsx"], + babelHelpers: "bundled", + presets: ["solid", "@babel/preset-typescript"], + exclude: [/node_modules\//], + }), + ], +}; diff --git a/lib/sqlsync-solid-js/src/context.tsx b/lib/sqlsync-solid-js/src/context.tsx new file mode 100644 index 0000000..c5eadf8 --- /dev/null +++ b/lib/sqlsync-solid-js/src/context.tsx @@ -0,0 +1,34 @@ +import { SQLSync } from "@orbitinghail/sqlsync-worker"; +import { ParentComponent, createContext, createSignal, onCleanup } from "solid-js"; + +export const SQLSyncContext = createContext<[() => SQLSync | null, (sqlSync: SQLSync) => void]>([ + () => null, + () => {}, +]); + +interface Props { + workerUrl: string | URL; + wasmUrl: string | URL; + coordinatorUrl?: string | URL; +} + +export const createSqlSync = (props: Props): SQLSync => { + return new SQLSync(props.workerUrl, props.wasmUrl, props.coordinatorUrl); +}; + +export const SQLSyncProvider: ParentComponent = (props) => { + const [sqlSync, setSQLSync] = createSignal(createSqlSync(props)); + + onCleanup(() => { + const s = sqlSync(); + if (s) { + s.close(); + } + }); + + return ( + + {props.children} + + ); +}; diff --git a/lib/sqlsync-solid-js/src/hooks.ts b/lib/sqlsync-solid-js/src/hooks.ts new file mode 100644 index 0000000..244a5aa --- /dev/null +++ b/lib/sqlsync-solid-js/src/hooks.ts @@ -0,0 +1,126 @@ +import { + ConnectionStatus, + DocId, + DocType, + ParameterizedQuery, + QuerySubscription, + Row, + SQLSync, + normalizeQuery, + pendingPromise, +} from "@orbitinghail/sqlsync-worker"; +import { Accessor, createEffect, createSignal, onCleanup, useContext } from "solid-js"; +import { SQLSyncContext } from "./context"; + +export function useSQLSync(): Accessor { + const [sqlSync] = useContext(SQLSyncContext); + return () => { + const value = sqlSync(); + if (!value) { + throw new Error( + "could not find sqlsync context value; please ensure the component is wrapped in a ", + ); + } + return value; + }; +} + +type MutateFn = (mutation: M) => Promise; +type UseMutateFn = (docId: DocId) => MutateFn; + +type UseQueryFn = ( + docId: Accessor, + query: Accessor, +) => Accessor>; + +type SetConnectionEnabledFn = (enabled: boolean) => Promise; +type UseSetConnectionEnabledFn = (docId: DocId) => SetConnectionEnabledFn; + +export interface DocHooks { + useMutate: UseMutateFn; + useQuery: UseQueryFn; + useSetConnectionEnabled: UseSetConnectionEnabledFn; +} + +export function createDocHooks(docType: Accessor>): DocHooks { + const useMutate = (docId: DocId): MutateFn => { + const sqlsync = useSQLSync(); + return (mutation: M) => sqlsync().mutate(docId, docType(), mutation); + }; + + const useQueryWrapper = ( + docId: Accessor, + query: Accessor, + ) => { + return useQuery(docType, docId, query); + }; + + const useSetConnectionEnabledWrapper = (docId: DocId) => { + const sqlsync = useSQLSync(); + return (enabled: boolean) => sqlsync().setConnectionEnabled(docId, docType(), enabled); + }; + + return { + useMutate, + useQuery: useQueryWrapper, + useSetConnectionEnabled: useSetConnectionEnabledWrapper, + }; +} + +export type QueryState = + | { state: "pending"; rows?: R[] } + | { state: "success"; rows: R[] } + | { state: "error"; error: Error; rows?: R[] }; + +export function useQuery( + docType: Accessor>, + docId: Accessor, + rawQuery: Accessor, +): Accessor> { + const sqlsync = useSQLSync(); + const [state, setState] = createSignal>({ state: "pending" }); + + createEffect(() => { + const query = normalizeQuery(rawQuery()); + + const [unsubPromise, unsubResolve] = pendingPromise<() => void>(); + + const subscription: QuerySubscription = { + handleRows: (rows: Row[]) => setState({ state: "success", rows: rows as R[] }), + handleErr: (err: string) => + setState((s) => ({ + state: "error", + error: new Error(err), + rows: s.rows, + })), + }; + + sqlsync() + .subscribe(docId(), docType(), query, subscription) + .then(unsubResolve) + .catch((err: Error) => { + console.error("sqlsync: error subscribing", err); + setState({ state: "error", error: err }); + }); + + onCleanup(() => { + unsubPromise + .then((unsub) => unsub()) + .catch((err) => { + console.error("sqlsync: error unsubscribing", err); + }); + }); + }); + + return state; +} + +export const useConnectionStatus = (): Accessor => { + const sqlsync = useSQLSync(); + const [status, setStatus] = createSignal(sqlsync().connectionStatus); + createEffect(() => { + const cleanup = sqlsync().addConnectionStatusListener(setStatus); + onCleanup(cleanup); + }); + return status; +}; diff --git a/lib/sqlsync-solid-js/src/index.ts b/lib/sqlsync-solid-js/src/index.ts new file mode 100644 index 0000000..f91277f --- /dev/null +++ b/lib/sqlsync-solid-js/src/index.ts @@ -0,0 +1,6 @@ +import { SQLSyncProvider } from "./context"; +import { createDocHooks, useConnectionStatus } from "./hooks"; + +export { SQLSyncProvider, createDocHooks, useConnectionStatus }; + +// eof: this file only exports diff --git a/lib/sqlsync-solid-js/tsconfig.json b/lib/sqlsync-solid-js/tsconfig.json new file mode 100644 index 0000000..a039b54 --- /dev/null +++ b/lib/sqlsync-solid-js/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "moduleResolution": "Bundler", + "lib": [ + "ES6", + "DOM", + "DOM.Iterable", + "ES2021.WeakRef" + ], + "jsx": "preserve", + "jsxImportSource": "solid-js", + /* Bundler mode */ + "allowJs": true, + "outDir": "dist", + "declaration": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 95f1734..ae3c864 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,38 +132,38 @@ importers: version: 5.2.2 vite: specifier: ^5.0.8 - version: 5.0.10 + version: 5.0.10(@types/node@20.8.8) - examples/simple-counter-react: + examples/guestbook-solid-js: dependencies: - '@orbitinghail/sqlsync-react': + '@orbitinghail/sqlsync-solid-js': specifier: workspace:* - version: link:../../lib/sqlsync-react + version: link:../../lib/sqlsync-solid-js '@orbitinghail/sqlsync-worker': specifier: workspace:* version: link:../../lib/sqlsync-worker - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) + solid-js: + specifier: ^1.8.7 + version: 1.8.8 + uuid: + specifier: ^9.0.1 + version: 9.0.1 devDependencies: - '@types/react': - specifier: ^18.2.43 - version: 18.2.46 - '@types/react-dom': - specifier: ^18.2.17 - version: 18.2.18 - '@vitejs/plugin-react': - specifier: ^4.2.1 - version: 4.2.1(vite@5.0.10) + '@types/uuid': + specifier: ^9.0.6 + version: 9.0.6 typescript: specifier: ^5.2.2 - version: 5.2.2 + version: 5.3.3 vite: - specifier: ^5.0.8 - version: 5.0.10 + specifier: ^4.5.0 + version: 4.5.0 + vite-plugin-solid: + specifier: ^2.7.0 + version: 2.8.0(solid-js@1.8.8)(vite@4.5.0) + vitest: + specifier: ^0.34.6 + version: 0.34.6 lib/sqlsync-react: dependencies: @@ -202,6 +202,40 @@ importers: specifier: ^5.2.2 version: 5.2.2 + lib/sqlsync-solid-js: + dependencies: + fast-equals: + specifier: ^5.0.1 + version: 5.0.1 + solid-js: + specifier: ^1.8.7 + version: 1.8.8 + devDependencies: + '@orbitinghail/sqlsync-worker': + specifier: workspace:^ + version: link:../sqlsync-worker + '@rollup/plugin-babel': + specifier: ^6.0.4 + version: 6.0.4(@babel/core@7.23.7)(rollup@3.29.4) + '@rollup/plugin-node-resolve': + specifier: ^15.2.3 + version: 15.2.3(rollup@3.29.4) + '@rollup/plugin-typescript': + specifier: ^11.1.5 + version: 11.1.5(rollup@3.29.4)(tslib@2.6.2)(typescript@5.2.2) + '@types/node': + specifier: ^20.8.8 + version: 20.8.8 + babel-preset-solid: + specifier: ^1.8.8 + version: 1.8.8(@babel/core@7.23.7) + rollup: + specifier: ^3.29.4 + version: 3.29.4 + typescript: + specifier: ^5.2.2 + version: 5.2.2 + lib/sqlsync-worker: dependencies: '@scure/base': @@ -332,6 +366,13 @@ packages: jsesc: 2.5.2 dev: true + /@babel/helper-annotate-as-pure@7.22.5: + resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + /@babel/helper-compilation-targets@7.22.15: resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} engines: {node: '>=6.9.0'} @@ -354,6 +395,24 @@ packages: semver: 6.3.1 dev: true + /@babel/helper-create-class-features-plugin@7.23.7(@babel/core@7.23.7): + resolution: {integrity: sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.7) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + semver: 6.3.1 + dev: true + /@babel/helper-environment-visitor@7.22.20: resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} @@ -374,6 +433,20 @@ packages: '@babel/types': 7.23.4 dev: true + /@babel/helper-member-expression-to-functions@7.23.0: + resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/helper-module-imports@7.18.6: + resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + /@babel/helper-module-imports@7.22.15: resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} @@ -409,11 +482,30 @@ packages: '@babel/helper-validator-identifier': 7.22.20 dev: true + /@babel/helper-optimise-call-expression@7.22.5: + resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + /@babel/helper-plugin-utils@7.22.5: resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} engines: {node: '>=6.9.0'} dev: true + /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.7): + resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + dev: true + /@babel/helper-simple-access@7.22.5: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} @@ -421,6 +513,13 @@ packages: '@babel/types': 7.23.4 dev: true + /@babel/helper-skip-transparent-expression-wrappers@7.22.5: + resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: true + /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} @@ -504,6 +603,38 @@ packages: '@babel/types': 7.23.6 dev: true + /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-simple-access': 7.22.5 + dev: true + /@babel/plugin-transform-react-jsx-self@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==} engines: {node: '>=6.9.0'} @@ -544,6 +675,33 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true + /@babel/plugin-transform-typescript@7.23.6(@babel/core@7.23.7): + resolution: {integrity: sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.23.7) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.7) + dev: true + + /@babel/preset-typescript@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-typescript': 7.23.6(@babel/core@7.23.7) + dev: true + /@babel/runtime@7.23.2: resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} engines: {node: '>=6.9.0'} @@ -1400,6 +1558,13 @@ packages: resolution: {integrity: sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==} dev: false + /@jest/schemas@29.6.3: + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.27.8 + dev: true + /@jridgewell/gen-mapping@0.3.3: resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} engines: {node: '>=6.0.0'} @@ -1510,6 +1675,25 @@ packages: engines: {node: '>=14.0.0'} dev: false + /@rollup/plugin-babel@6.0.4(@babel/core@7.23.7)(rollup@3.29.4): + resolution: {integrity: sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@types/babel__core': ^7.1.9 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + '@types/babel__core': + optional: true + rollup: + optional: true + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-module-imports': 7.22.15 + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) + rollup: 3.29.4 + dev: true + /@rollup/plugin-commonjs@25.0.7(rollup@3.29.4): resolution: {integrity: sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==} engines: {node: '>=14.0.0'} @@ -1559,7 +1743,7 @@ packages: tslib: optional: true dependencies: - '@rollup/pluginutils': 5.0.5(rollup@3.29.4) + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) resolve: 1.22.8 rollup: 3.29.4 tslib: 2.6.2 @@ -1581,6 +1765,21 @@ packages: rollup: 3.29.4 dev: true + /@rollup/pluginutils@5.1.0(rollup@3.29.4): + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.3 + estree-walker: 2.0.2 + picomatch: 2.3.1 + rollup: 3.29.4 + dev: true + /@rollup/rollup-android-arm-eabi@4.9.2: resolution: {integrity: sha512-RKzxFxBHq9ysZ83fn8Iduv3A283K7zPPYuhL/z9CQuyFrjwpErJx0h4aeb/bnJ+q29GRLgJpY66ceQ/Wcsn3wA==} cpu: [arm] @@ -1689,6 +1888,10 @@ packages: resolution: {integrity: sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==} dev: false + /@sinclair/typebox@0.27.8: + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + dev: true + /@tabler/icons-react@2.39.0(react@18.2.0): resolution: {integrity: sha512-MyUK1jqtmHPZBnDXqIc1Y5OnfoqG+tGaSB1/gcl0mlY462fJ5f3QB0ZIZzAHMAGYb6K2iJSdFIFavhcgpDDZ7Q==} peerDependencies: @@ -1742,6 +1945,16 @@ packages: '@babel/types': 7.23.4 dev: true + /@types/chai-subset@1.3.5: + resolution: {integrity: sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==} + dependencies: + '@types/chai': 4.3.11 + dev: true + + /@types/chai@4.3.11: + resolution: {integrity: sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==} + dev: true + /@types/estree@1.0.3: resolution: {integrity: sha512-CS2rOaoQ/eAgAfcTfq6amKG7bsN+EMcgGY4FAFQdvSj2y1ixvOZTUA9mOtCai7E1SYu283XNw7urKK30nP3wkQ==} dev: true @@ -1824,11 +2037,49 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.7) '@types/babel__core': 7.20.5 react-refresh: 0.14.0 - vite: 5.0.10 + vite: 5.0.10(@types/node@20.8.8) transitivePeerDependencies: - supports-color dev: true + /@vitest/expect@0.34.6: + resolution: {integrity: sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==} + dependencies: + '@vitest/spy': 0.34.6 + '@vitest/utils': 0.34.6 + chai: 4.3.10 + dev: true + + /@vitest/runner@0.34.6: + resolution: {integrity: sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==} + dependencies: + '@vitest/utils': 0.34.6 + p-limit: 4.0.0 + pathe: 1.1.1 + dev: true + + /@vitest/snapshot@0.34.6: + resolution: {integrity: sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==} + dependencies: + magic-string: 0.30.5 + pathe: 1.1.1 + pretty-format: 29.7.0 + dev: true + + /@vitest/spy@0.34.6: + resolution: {integrity: sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==} + dependencies: + tinyspy: 2.2.0 + dev: true + + /@vitest/utils@0.34.6: + resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==} + dependencies: + diff-sequences: 29.6.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + dev: true + /acorn-walk@8.2.0: resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} engines: {node: '>=0.4.0'} @@ -1847,6 +2098,11 @@ packages: color-convert: 1.9.3 dev: true + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + /anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -1868,6 +2124,10 @@ packages: printable-characters: 1.0.42 dev: true + /assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true + /autoprefixer@10.4.16(postcss@8.4.31): resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==} engines: {node: ^10 || ^12 || >=14} @@ -1884,6 +2144,28 @@ packages: postcss-value-parser: 4.2.0 dev: true + /babel-plugin-jsx-dom-expressions@0.37.11(@babel/core@7.23.7): + resolution: {integrity: sha512-0NaWy4sFsE0AWlucvL/myEiZ851BgjeLwhtctOFmyVCK6fPXqQHQUBB5SrrrmvOiw/BZCmMe8dOy7JL3FSyTtQ==} + peerDependencies: + '@babel/core': ^7.20.12 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-module-imports': 7.18.6 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.7) + '@babel/types': 7.23.6 + html-entities: 2.3.3 + validate-html-nesting: 1.2.2 + dev: true + + /babel-preset-solid@1.8.8(@babel/core@7.23.7): + resolution: {integrity: sha512-m+sFxzriUgMiyUPz/oWxU+N6PwY2bVsZVlc4Jxx+5XhDt5lGE/meg+ZL/kLgSAZ75YuU9AJZr444Un1bO0vhJQ==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + babel-plugin-jsx-dom-expressions: 0.37.11(@babel/core@7.23.7) + dev: true + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true @@ -1941,6 +2223,11 @@ packages: engines: {node: '>=6'} dev: true + /cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + dev: true + /camelcase-css@2.0.1: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} @@ -1963,6 +2250,19 @@ packages: - supports-color dev: true + /chai@4.3.10: + resolution: {integrity: sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.3 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: true + /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -1972,6 +2272,12 @@ packages: supports-color: 5.5.0 dev: true + /check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + dependencies: + get-func-name: 2.0.2 + dev: true + /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -2040,6 +2346,13 @@ packages: ms: 2.1.2 dev: true + /deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + dependencies: + type-detect: 4.0.8 + dev: true + /deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} @@ -2049,6 +2362,11 @@ packages: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} dev: false + /diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + /electron-to-chromium@1.4.565: resolution: {integrity: sha512-XbMoT6yIvg2xzcbs5hCADi0dXBh4//En3oFXmtPX+jiyyiCTiM9DGFT2SLottjpEs9Z8Mh8SqahbR96MaHfuSg==} dev: true @@ -2238,6 +2556,10 @@ packages: engines: {node: '>=6.9.0'} dev: true + /get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + dev: true + /get-nonce@1.0.1: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} @@ -2298,6 +2620,10 @@ packages: engines: {node: '>=12.0.0'} dev: false + /html-entities@2.3.3: + resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} + dev: true + /inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: @@ -2362,6 +2688,11 @@ packages: '@types/estree': 1.0.3 dev: true + /is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + dev: true + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2377,11 +2708,20 @@ packages: hasBin: true dev: true + /jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: true + /klona@2.0.6: resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} engines: {node: '>= 8'} dev: false + /local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + engines: {node: '>=14'} + dev: true + /loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -2389,6 +2729,12 @@ packages: js-tokens: 4.0.0 dev: false + /loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + dependencies: + get-func-name: 2.0.2 + dev: true + /lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} dependencies: @@ -2408,6 +2754,13 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /merge-anything@5.1.7: + resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==} + engines: {node: '>=12.13'} + dependencies: + is-what: 4.1.16 + dev: true + /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -2456,6 +2809,15 @@ packages: brace-expansion: 2.0.1 dev: true + /mlly@1.4.2: + resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==} + dependencies: + acorn: 8.10.0 + pathe: 1.1.1 + pkg-types: 1.0.3 + ufo: 1.3.2 + dev: true + /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true @@ -2511,6 +2873,13 @@ packages: wrappy: 1.0.2 dev: true + /p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + yocto-queue: 1.0.0 + dev: true + /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true @@ -2519,6 +2888,14 @@ packages: resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} dev: true + /pathe@1.1.1: + resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} + dev: true + + /pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} dev: true @@ -2528,6 +2905,14 @@ packages: engines: {node: '>=8.6'} dev: true + /pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + dependencies: + jsonc-parser: 3.2.0 + mlly: 1.4.2 + pathe: 1.1.1 + dev: true + /postcss-js@4.0.1(postcss@8.4.31): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} @@ -2610,6 +2995,15 @@ packages: source-map-js: 1.0.2 dev: true + /pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.2.0 + dev: true + /printable-characters@1.0.42: resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} dev: true @@ -2653,6 +3047,10 @@ packages: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: false + /react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + dev: true + /react-number-format@5.3.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-qpYcQLauIeEhCZUZY9jXZnnroOtdy3jYaS1zQ3M1Sr6r/KMOBEIGNIb7eKT19g2N1wbYgFgvDzs19hw5TrB8XQ==} peerDependencies: @@ -2878,6 +3276,31 @@ packages: hasBin: true dev: true + /seroval@1.0.2: + resolution: {integrity: sha512-buswWxRzf65ZGUk8MAf3qVtBJHbe5gq6hZyPeqlJCKEIl/tEhUZze0YJg7vB7tFRGgPeneRaP083OB/vDiYLvA==} + engines: {node: '>=10'} + + /siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + dev: true + + /solid-js@1.8.8: + resolution: {integrity: sha512-9CtL5xWTYX1WWjQKqht3Tl0AJzgz4YWVQk8hoscO9TzRCgzlpAauEOexXa6bPG30W+fWLnFVE7XUiAzQFNeUKw==} + dependencies: + csstype: 3.1.2 + seroval: 1.0.2 + + /solid-refresh@0.5.3(solid-js@1.8.8): + resolution: {integrity: sha512-Otg5it5sjOdZbQZJnvo99TEBAr6J7PQ5AubZLNU6szZzg3RQQ5MX04oteBIIGDs0y2Qv8aXKm9e44V8z+UnFdw==} + peerDependencies: + solid-js: ^1.3 + dependencies: + '@babel/generator': 7.23.6 + '@babel/helper-module-imports': 7.22.15 + '@babel/types': 7.23.6 + solid-js: 1.8.8 + dev: true + /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -2900,6 +3323,10 @@ packages: deprecated: Please use @jridgewell/sourcemap-codec instead dev: true + /stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + dev: true + /stacktracey@2.1.8: resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} dependencies: @@ -2907,11 +3334,21 @@ packages: get-source: 2.0.12 dev: true + /std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + dev: true + /stoppable@1.1.0: resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} engines: {node: '>=4', npm: '>=6'} dev: true + /strip-literal@1.3.0: + resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} + dependencies: + acorn: 8.10.0 + dev: true + /sugarss@4.0.1(postcss@8.4.31): resolution: {integrity: sha512-WCjS5NfuVJjkQzK10s8WOBY+hhDxxNt/N6ZaGwxFZ+wN3/lKKFSaaKUNecULcTTvE4urLcKaZFQD8vO0mOZujw==} engines: {node: '>=12.0'} @@ -2937,6 +3374,20 @@ packages: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} dev: false + /tinybench@2.5.1: + resolution: {integrity: sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==} + dev: true + + /tinypool@0.7.0: + resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy@2.2.0: + resolution: {integrity: sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==} + engines: {node: '>=14.0.0'} + dev: true + /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -2952,6 +3403,11 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + /type-fest@3.13.1: resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} engines: {node: '>=14.16'} @@ -2963,6 +3419,16 @@ packages: hasBin: true dev: true + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /ufo@1.3.2: + resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} + dev: true + /undici-types@5.25.3: resolution: {integrity: sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==} dev: true @@ -3071,6 +3537,86 @@ packages: hasBin: true dev: false + /validate-html-nesting@1.2.2: + resolution: {integrity: sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==} + dev: true + + /vite-node@0.34.6(@types/node@20.8.8): + resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} + engines: {node: '>=v14.18.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + mlly: 1.4.2 + pathe: 1.1.1 + picocolors: 1.0.0 + vite: 5.0.10(@types/node@20.8.8) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /vite-plugin-solid@2.8.0(solid-js@1.8.8)(vite@4.5.0): + resolution: {integrity: sha512-n5FAm7ZmTl94VWUoiJCgG7bouF2NlC9CA1wY/qbVnkFbYDWk++bFWyNoU48aLJ+lMtzNeYzJypJXOHzFKxL9xA==} + peerDependencies: + solid-js: ^1.7.2 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/preset-typescript': 7.23.3(@babel/core@7.23.7) + '@types/babel__core': 7.20.5 + babel-preset-solid: 1.8.8(@babel/core@7.23.7) + merge-anything: 5.1.7 + solid-js: 1.8.8 + solid-refresh: 0.5.3(solid-js@1.8.8) + vite: 4.5.0 + vitefu: 0.2.5(vite@4.5.0) + transitivePeerDependencies: + - supports-color + dev: true + + /vite@4.5.0: + resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.18.20 + postcss: 8.4.32 + rollup: 3.29.4 + optionalDependencies: + fsevents: 2.3.3 + dev: true + /vite@4.5.0(@types/node@20.8.8): resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -3107,7 +3653,7 @@ packages: fsevents: 2.3.3 dev: true - /vite@5.0.10: + /vite@5.0.10(@types/node@20.8.8): resolution: {integrity: sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -3135,6 +3681,7 @@ packages: terser: optional: true dependencies: + '@types/node': 20.8.8 esbuild: 0.19.11 postcss: 8.4.32 rollup: 4.9.2 @@ -3142,6 +3689,91 @@ packages: fsevents: 2.3.3 dev: true + /vitefu@0.2.5(vite@4.5.0): + resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + vite: + optional: true + dependencies: + vite: 4.5.0 + dev: true + + /vitest@0.34.6: + resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==} + engines: {node: '>=v14.18.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + dependencies: + '@types/chai': 4.3.11 + '@types/chai-subset': 1.3.5 + '@types/node': 20.8.8 + '@vitest/expect': 0.34.6 + '@vitest/runner': 0.34.6 + '@vitest/snapshot': 0.34.6 + '@vitest/spy': 0.34.6 + '@vitest/utils': 0.34.6 + acorn: 8.10.0 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.10 + debug: 4.3.4 + local-pkg: 0.4.3 + magic-string: 0.30.5 + pathe: 1.1.1 + picocolors: 1.0.0 + std-env: 3.7.0 + strip-literal: 1.3.0 + tinybench: 2.5.1 + tinypool: 0.7.0 + vite: 5.0.10(@types/node@20.8.8) + vite-node: 0.34.6(@types/node@20.8.8) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + dev: true + /workerd@1.20231016.0: resolution: {integrity: sha512-v2GDb5XitSqgub/xm7EWHVAlAK4snxQu3itdMQxXstGtUG9hl79fQbXS/8fNFbmms2R2bAxUwSv47q8k5T5Erw==} engines: {node: '>=16'} @@ -3206,6 +3838,11 @@ packages: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} dev: true + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: true + /youch@3.3.2: resolution: {integrity: sha512-9cwz/z7abtcHOIuH45nzmUFCZbyJA1nLqlirKvyNRx4wDMhqsBaifAJzBej7L4fsVPjFxYq3NK3GAcfvZsydFw==} dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index b393bd5..ef64e81 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,5 +2,7 @@ packages: - "demo/cloudflare-backend" - "demo/frontend" - "lib/sqlsync-react" + - "lib/sqlsync-solid-js" - "lib/sqlsync-worker" - "examples/guestbook-react" + - "examples/guestbook-solid-js"