-
Notifications
You must be signed in to change notification settings - Fork 174
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(examples): Update Linearlite to use the Proxy and new types (#590)
This updates linearlite to use the Proxy and new types. Of the new times we are using `timestamp` and 'uuid'. The only difference between the files from the starter and their copies in this example is that they have been renamed from `*.js` to `*.cjs`. This example has `"type": "module"` set in `package.json`, by renaming the scripts to `*.cjs` they continue to work unmodified. Without this they would have to be converted to ESM with "import" rather than "require" syntax. `builder.cjs` is included in the project but not used to build the app, it uses Vite. It is inspected for port definitions by other scripts from the starter and so cannot be deleted without modifying them.
- Loading branch information
Showing
29 changed files
with
4,295 additions
and
1,971 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 |
---|---|---|
@@ -1,4 +1,6 @@ | ||
# Docker images for the local stack | ||
export POSTGRESQL_IMAGE=postgres:14-alpine | ||
export APP_NAME=linearlite | ||
export ELECTRIC_PORT=5133 | ||
export ELECTRIC_PROXY_PORT=65432 | ||
export ELECTRIC_IMAGE=electricsql/electric:latest | ||
export APP_NAME=linearlite |
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 |
---|---|---|
@@ -1,42 +1,45 @@ | ||
version: '3.8' | ||
version: "3.8" | ||
name: "${APP_NAME:-electric}" | ||
|
||
configs: | ||
postgres_config: | ||
file: './postgres/postgres.conf' | ||
file: "./postgres/postgres.conf" | ||
|
||
volumes: | ||
pg_data: | ||
|
||
services: | ||
postgres: | ||
image: '${POSTGRESQL_IMAGE:-postgres:14-alpine}' | ||
image: "${POSTGRESQL_IMAGE:-postgres:14-alpine}" | ||
environment: | ||
POSTGRES_DB: ${APP_NAME:-electric} | ||
POSTGRES_USER: postgres | ||
POSTGRES_PASSWORD: password | ||
POSTGRES_PASSWORD: pg_password | ||
command: | ||
- -c | ||
- config_file=/etc/postgresql.conf | ||
configs: | ||
- source: postgres_config | ||
target: /etc/postgresql.conf | ||
healthcheck: | ||
test: ['CMD-SHELL', 'pg_isready -U postgres'] | ||
test: ["CMD-SHELL", "pg_isready -U postgres"] | ||
extra_hosts: | ||
- 'host.docker.internal:host-gateway' | ||
- "host.docker.internal:host-gateway" | ||
ports: | ||
- 5432 | ||
volumes: | ||
- pg_data:/var/lib/postgresql/data | ||
|
||
electric: | ||
image: '${ELECTRIC_IMAGE:-electricsql/electric:latest}' | ||
image: "${ELECTRIC_IMAGE:-electricsql/electric:latest}" | ||
init: true | ||
environment: | ||
DATABASE_URL: postgresql://postgres:password@postgres:5432/${APP_NAME:-electric} | ||
DATABASE_URL: postgresql://postgres:pg_password@postgres:5432/${APP_NAME:-electric} | ||
PG_PROXY_PASSWORD: proxy_password | ||
LOGICAL_PUBLISHER_HOST: electric | ||
AUTH_MODE: insecure | ||
ports: | ||
- 5133:5133 | ||
- ${ELECTRIC_PORT:-5133}:5133 | ||
- ${ELECTRIC_PROXY_PORT:-65432}:65432 | ||
depends_on: | ||
- postgres |
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,16 @@ | ||
const { dockerCompose } = require('../util/util.cjs') | ||
const process = require('process') | ||
|
||
const cliArguments = process.argv.slice(2) | ||
|
||
dockerCompose('up', cliArguments, (code) => { | ||
if (code !== 0) { | ||
console.error( | ||
'\x1b[31m', | ||
'Failed to start the Electric backend. Check the output from `docker compose` above.\n' + | ||
'If the error message mentions a port already being allocated or address being already in use,\n' + | ||
'execute `yarn ports:configure` to run Electric on another port.', | ||
'\x1b[0m' | ||
) | ||
} | ||
}) |
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,81 @@ | ||
const shell = require('shelljs') | ||
|
||
let db = process.env.DATABASE_URL | ||
let electricPort = process.env.ELECTRIC_PORT ?? 5133 | ||
let electricProxyPort = process.env.ELECTRIC_PROXY_PORT ?? 65432 | ||
|
||
let args = process.argv.slice(2) | ||
|
||
while (args.length > 0) { | ||
// There are arguments to parse | ||
const flag = args[0] | ||
const value = args[1] | ||
|
||
args = args.slice(2) | ||
|
||
const checkValue = () => { | ||
if (typeof value === 'undefined') { | ||
error(`Missing value for option '${flag}'.`) | ||
} | ||
} | ||
|
||
switch (flag) { | ||
case '-db': | ||
checkValue() | ||
db = value | ||
break | ||
case '--electric-port': | ||
checkValue() | ||
electricPort = parsePort(value) | ||
break | ||
case '--electric-proxy-port': | ||
checkValue() | ||
electricProxyPort = parsePort(value) | ||
break | ||
default: | ||
error(`Unrecognized option: '${flag}'.`) | ||
} | ||
} | ||
|
||
function parsePort(port) { | ||
// checks that the number is between 0 and 65535 | ||
const portRegex = /^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/ | ||
if (!portRegex.test(port)) { | ||
error(`Invalid port '${port}. Port should be between 0 and 65535.'`) | ||
} | ||
return port | ||
} | ||
|
||
if (db === undefined) { | ||
console.error(`Database URL is not provided. Please provide one using the DATABASE_URL environment variable.`) | ||
process.exit(1) | ||
} | ||
|
||
const electric = process.env.ELECTRIC_IMAGE ?? "electricsql/electric:latest" | ||
|
||
// 5433 is the logical publisher port | ||
// it is exposed because PG must be able to connect to Electric | ||
const res = shell.exec( | ||
`docker run \ | ||
-e "DATABASE_URL=${db}" \ | ||
-e "LOGICAL_PUBLISHER_HOST=localhost" \ | ||
-e "AUTH_MODE=insecure" \ | ||
-p ${electricPort}:5133 \ | ||
-p ${electricProxyPort}:65432 \ | ||
-p 5433:5433 ${electric}` | ||
) | ||
|
||
if (res.code !== 0 && res.stderr.includes('port is already allocated')) { | ||
// inform the user that they should change ports | ||
console.error( | ||
'\x1b[31m', | ||
'Could not start Electric because the port seems to be taken.\n' + | ||
'To run Electric on another port execute `yarn ports:configure`', | ||
'\x1b[0m' | ||
) | ||
} | ||
|
||
function error(err) { | ||
console.error('\x1b[31m', err + '\nyarn electric:start [-db <Postgres connection url>] [--electric-port <port>] [--electric-proxy-port <port>]', '\x1b[0m') | ||
process.exit(1) | ||
} |
This file was deleted.
Oops, something went wrong.
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,99 @@ | ||
const { build, serve } = require('esbuild') | ||
|
||
const { createServer, request } = require('http') | ||
const { spawn } = require('child_process') | ||
|
||
const fs = require('fs-extra') | ||
const inlineImage = require('esbuild-plugin-inline-image') | ||
|
||
const shouldMinify = process.env.NODE_ENV === 'production' | ||
const shouldServe = process.env.SERVE === 'true' | ||
|
||
// https://github.com/evanw/esbuild/issues/802#issuecomment-819578182 | ||
const liveServer = (buildOpts) => { | ||
const clients = [] | ||
|
||
build( | ||
{ | ||
...buildOpts, | ||
banner: { js: ' (() => new EventSource("/esbuild").onmessage = () => location.reload())();' }, | ||
watch: { | ||
onRebuild(error, result) { | ||
clients.forEach((res) => res.write('data: update\n\n')) | ||
clients.length = 0 | ||
console.log(error ? error : '...') | ||
}, | ||
} | ||
} | ||
).catch(() => process.exit(1)) | ||
|
||
serve({servedir: 'dist' }, {}) | ||
.then((serveResult) => { | ||
createServer((req, res) => { | ||
const { url, method, headers } = req | ||
|
||
if (url === '/esbuild') | ||
return clients.push( | ||
res.writeHead(200, { | ||
'Content-Type': 'text/event-stream', | ||
'Cache-Control': 'no-cache', | ||
Connection: 'keep-alive', | ||
}) | ||
) | ||
|
||
const path = ~url.split('/').pop().indexOf('.') ? url : `/index.html` //for PWA with router | ||
req.pipe( | ||
request({ hostname: '0.0.0.0', port: serveResult.port, path, method, headers }, (prxRes) => { | ||
res.writeHead(prxRes.statusCode, prxRes.headers) | ||
prxRes.pipe(res, { end: true }) | ||
}), | ||
{ end: true } | ||
) | ||
}).listen(3001) | ||
|
||
setTimeout(() => { | ||
const op = { darwin: ['open'], linux: ['xdg-open'], win32: ['cmd', '/c', 'start'] } | ||
const ptf = process.platform | ||
const url = "http://localhost:3001" | ||
if (clients.length === 0) spawn(op[ptf][0], [...[op[ptf].slice(1)], url]) | ||
console.info(`Your app is running at ${url}`) | ||
}, 500) // open the default browser only if it is not opened yet | ||
}) | ||
} | ||
|
||
/** | ||
* ESBuild Params | ||
* @link https://esbuild.github.io/api/#build-api | ||
*/ | ||
let buildParams = { | ||
color: true, | ||
entryPoints: ["src/index.tsx"], | ||
loader: { ".ts": "tsx" }, | ||
outdir: "dist", | ||
minify: shouldMinify, | ||
format: "cjs", | ||
bundle: true, | ||
sourcemap: true, | ||
logLevel: "error", | ||
incremental: true, | ||
define: { | ||
__DEBUG_MODE__: JSON.stringify(process.env.DEBUG_MODE === 'true'), | ||
__ELECTRIC_URL__: JSON.stringify(process.env.ELECTRIC_URL ?? 'ws://localhost:5133'), | ||
}, | ||
external: ["fs", "path"], | ||
plugins: [inlineImage()], | ||
}; | ||
|
||
(async () => { | ||
fs.removeSync("dist"); | ||
fs.copySync("public", "dist"); | ||
|
||
if (shouldServe) { | ||
liveServer(buildParams) | ||
} | ||
else { | ||
await build(buildParams) | ||
|
||
process.exit(0) | ||
} | ||
})(); |
Oops, something went wrong.