-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
1,180 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Solid JS + TypeScript + Vite + SQLSync | ||
|
||
This template provides a minimal setup to get SQLSync working with Solid JS and Vite. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>SQLSync + Vite + Solid JS + TS</title> | ||
</head> | ||
|
||
<body> | ||
<div id="root">if nothing renders, open the console</div> | ||
<script type="module" src="/src/main.tsx"></script> | ||
</body> | ||
|
||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Mutation> = { | ||
reducerUrl: REDUCER_URL, | ||
serializeMutation: serializeMutationAsJSON, | ||
}; | ||
|
||
export const { useMutate, useQuery, useSetConnectionEnabled } = createDocHooks(() => TaskDocType); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<HTMLFormElement, SubmitEvent> = (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 ( | ||
<div> | ||
<h1>Guestbook:</h1> | ||
<ul> | ||
<For each={rows()}> | ||
{(row) => { | ||
return ( | ||
<li> | ||
{row.msg} | ||
<button | ||
type="button" | ||
onClick={() => handleDelete(row.id)} | ||
style={{ "margin-left": "40px" }} | ||
> | ||
remove msg | ||
</button> | ||
</li> | ||
); | ||
}} | ||
</For> | ||
</ul> | ||
<h3>Leave a message:</h3> | ||
<form onSubmit={handleSubmit}> | ||
<label> | ||
Msg: | ||
<input type="text" name="msg" value={msg()} onChange={(e) => setMsg(e.target.value)} /> | ||
</label> | ||
<input type="submit" value="Submit" /> | ||
</form> | ||
</div> | ||
); | ||
} | ||
|
||
// Configure the SQLSync provider near the top of the React tree | ||
render( | ||
() => ( | ||
<SQLSyncProvider wasmUrl={sqlSyncWasmUrl} workerUrl={workerUrl}> | ||
<App /> | ||
</SQLSyncProvider> | ||
), | ||
// biome-ignore lint/style/noNonNullAssertion: we know this element exists | ||
document.getElementById("root")!, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" }] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"compilerOptions": { | ||
"composite": true, | ||
"skipLibCheck": true, | ||
"module": "ESNext", | ||
"moduleResolution": "bundler", | ||
"allowSyntheticDefaultImports": true | ||
}, | ||
"include": ["vite.config.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { defineConfig } from "vite"; | ||
import solid from "vite-plugin-solid"; | ||
|
||
// https://vitejs.dev/config/ | ||
export default defineConfig({ | ||
plugins: [solid()], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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:^" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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\//], | ||
}), | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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> = (props) => { | ||
const [sqlSync, setSQLSync] = createSignal<SQLSync>(createSqlSync(props)); | ||
|
||
onCleanup(() => { | ||
const s = sqlSync(); | ||
if (s) { | ||
s.close(); | ||
} | ||
}); | ||
|
||
return ( | ||
<SQLSyncContext.Provider value={[sqlSync, setSQLSync]}> | ||
{props.children} | ||
</SQLSyncContext.Provider> | ||
); | ||
}; |
Oops, something went wrong.