├── .nvmrc
├── .gitignore
├── src
├── index.js
├── styles.css
└── App.js
├── craco.config.js
├── README.md
├── package.json
├── LICENSE
└── public
└── index.html
/.nvmrc:
--------------------------------------------------------------------------------
1 | 16
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vscode/
3 | node_modules/
4 | build
5 | .DS_Store
6 | *.tgz
7 | my-app*
8 | template/src/__tests__/__snapshots__/
9 | lerna-debug.log
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 | /.changelog
14 | .npm/
15 | yarn.lock
16 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 |
4 | import App from "./App";
5 |
6 | const rootElement = document.getElementById("root");
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | rootElement
12 | );
13 |
--------------------------------------------------------------------------------
/src/styles.css:
--------------------------------------------------------------------------------
1 | .App {
2 | font-family: sans-serif;
3 | font-size: 1.5em;
4 | }
5 |
6 | textarea {
7 | font-size: 1.1em;
8 | width: 70%;
9 | display: block;
10 | margin: auto;
11 | }
12 |
13 | table {
14 | border: 1px solid #1c6ea4;
15 | background-color: #eeeeee;
16 | width: 40%;
17 | margin: 1.5em auto;
18 | text-align: left;
19 | border-collapse: collapse;
20 | text-align: right;
21 | }
22 |
23 | thead {
24 | font-weight: bold;
25 | text-align: center;
26 | border: 2px solid #999;
27 | }
28 |
29 | th,
30 | td {
31 | border: 1px solid #aaa;
32 | }
33 |
34 | .error {
35 | color: #922;
36 | }
37 |
--------------------------------------------------------------------------------
/craco.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | webpack: {
3 | configure: (webpackConfig) => {
4 | // Add the following lines to handle 'crypto' and 'fs' dependencies
5 | webpackConfig.resolve.fallback = {
6 | fs: require.resolve("browserify-fs"), // or 'empty' if you prefer an empty module
7 | crypto: require.resolve('crypto-browserify'),
8 | stream: require.resolve('stream-browserify'),
9 | };
10 |
11 | // Add the 'module' configuration for handling .wasm files
12 | webpackConfig.module.rules.push({
13 | test: /\.wasm$/,
14 | type: 'javascript/auto',
15 | });
16 |
17 | return webpackConfig;
18 | },
19 | },
20 | };
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # demonstration of [react](https://reactjs.org/) + [sql.js](https://github.com/sql-js/sql.js)
2 |
3 | This is a template repository demonstrating the use of sql.js with create-react-app.
4 |
5 | The only differences with a traditional create-react-app application are :
6 | - The usage of [craco](https://github.com/gsoft-inc/craco) to allow providing a custom [webpack](https://webpack.js.org/) configuration
7 | - a small custom webpack configuration in [`craco.config.js`](./craco.config.js) to copy the wasm module from sql.js to the distributed assets
8 |
9 | Note that you should make sure your server serves `.wasm` files with the right mimetype, that is: `application/wasm`. Otherwise, you'll see the following error: `TypeError: Response has unsupported MIME type`
10 |
11 | See [`src/App.js`](./src/App.js) for the code.
12 |
13 | ### [view the live demo](https://react-sqljs-demo.ophir.dev/)
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-sqljs-demo",
3 | "version": "1.0.0",
4 | "description": "sql.js + react example starter project",
5 | "keywords": [
6 | "react",
7 | "starter"
8 | ],
9 | "main": "src/index.js",
10 | "license": "MIT",
11 | "dependencies": {
12 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
13 | "browserify-fs": "^1.0.0",
14 | "crypto-browserify": "^3.12.0",
15 | "react": "^17.0.2",
16 | "react-dom": "^17.0.2",
17 | "sql.js": "^1.6.2",
18 | "stream-browserify": "^3.0.0"
19 | },
20 | "devDependencies": {
21 | "@craco/craco": "^5.9.0",
22 | "react-scripts": "^5.0.1",
23 | "typescript": "^4.5.5"
24 | },
25 | "scripts": {
26 | "start": "craco start",
27 | "build": "craco build",
28 | "test": "craco test --env=jsdom",
29 | "eject": "craco eject"
30 | },
31 | "browserslist": [
32 | ">0.2%",
33 | "not dead",
34 | "not ie <= 11",
35 | "not op_mini all"
36 | ]
37 | }
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 SQL.JS
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
23 | React App
24 |
25 |
26 |
27 |
30 |
31 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import "./styles.css";
3 | import initSqlJs from "sql.js";
4 |
5 | // Required to let webpack 4 know it needs to copy the wasm file to our assets
6 | import sqlWasm from "!!file-loader?name=sql-wasm-[contenthash].wasm!sql.js/dist/sql-wasm.wasm";
7 |
8 | export default function App() {
9 | const [db, setDb] = useState(null);
10 | const [error, setError] = useState(null);
11 |
12 | useEffect(async () => {
13 | // sql.js needs to fetch its wasm file, so we cannot immediately instantiate the database
14 | // without any configuration, initSqlJs will fetch the wasm files directly from the same path as the js
15 | // see ../craco.config.js
16 | try {
17 | const SQL = await initSqlJs({ locateFile: () => sqlWasm });
18 | setDb(new SQL.Database());
19 | } catch (err) {
20 | setError(err);
21 | }
22 | }, []);
23 |
24 | if (error) return
{error.toString()}
;
25 | else if (!db) return
Loading...
;
26 | else return ;
27 | }
28 |
29 | /**
30 | * A simple SQL read-eval-print-loop
31 | * @param {{db: import("sql.js").Database}} props
32 | */
33 | function SQLRepl({ db }) {
34 | const [error, setError] = useState(null);
35 | const [results, setResults] = useState([]);
36 |
37 | function exec(sql) {
38 | try {
39 | // The sql is executed synchronously on the UI thread.
40 | // You may want to use a web worker here instead
41 | setResults(db.exec(sql)); // an array of objects is returned
42 | setError(null);
43 | } catch (err) {
44 | // exec throws an error when the SQL statement is invalid
45 | setError(err);
46 | setResults([]);
47 | }
48 | }
49 |
50 | return (
51 |
52 |
React SQL interpreter
53 |
54 |
58 |
59 |
{(error || "").toString()}
60 |
61 |
62 | {
63 | // results contains one object per select statement in the query
64 | results.map(({ columns, values }, i) => (
65 |
66 | ))
67 | }
68 |
69 |
70 | );
71 | }
72 |
73 | /**
74 | * Renders a single value of the array returned by db.exec(...) as a table
75 | * @param {import("sql.js").QueryExecResult} props
76 | */
77 | function ResultsTable({ columns, values }) {
78 | return (
79 |
80 |
81 |
82 | {columns.map((columnName, i) => (
83 |
{columnName}
84 | ))}
85 |
86 |
87 |
88 |
89 | {
90 | // values is an array of arrays representing the results of the query
91 | values.map((row, i) => (
92 |