Skip to main content

2 posts tagged with "Development"

Development documentation for FaynoSync

View All Tags

How to Setup Auto Update for Electron App

ยท 4 min read

Today, we'll explore how to create a simple Electron app and add auto-update functionality using faynoSync. Let's make your app smarter with automatic version checking and updates!


Prerequisites ๐Ÿ“‹โ€‹

Before we begin, make sure you have:

  • A running faynoSync instance
  • Published versions 0.0.1 and 0.0.2 of your app
  • Created an app in faynoSync named "myapp"
  • Created a channel in faynoSync named "nightly"
  • Created a platform in faynoSync named (darwin/linux/windows)
  • Created a architecture in faynoSync named (amd64/arm64)

Let's Get Started! ๐Ÿš€โ€‹

1. Initialize Your Projectโ€‹

First, let's create a new project with the following package.json:

{
"name": "myapp",
"version": "0.0.1",
"description": "Hello world app for testing faynoSync",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"keywords": [],
"author": "Example Author",
"license": "ISC",
"dependencies": {
"node-fetch": "2.6.9"
},
"devDependencies": {
"electron": ">=23.3.13"
},
"engines": {
"npm": ">=8.19.3",
"node": ">=18.13.0"
}
}

2. Create Basic Filesโ€‹

index.htmlโ€‹

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title id="title"></title>
</head>
<body>
<h1 id="label">Hello, world!</h1>
</body>
</html>

config.jsโ€‹

const packageJson = require('./package.json');

module.exports = {
app_name: packageJson.name,
version: packageJson.version,
channel: "nightly",
owner: "example",
};

The Magic of Auto-Updates โœจโ€‹

Let's create our main.js file step by step:

1. Import Required Modulesโ€‹

const { app, BrowserWindow, dialog, shell } = require('electron');
const fetch = require('node-fetch');
const os = require('os');
const { version, app_name, channel, owner } = require('./config.js');
const fs = require('fs');

2. Platform Detectionโ€‹

function getLinuxDistributionFamily() {
let distroFamily = 'Linux';
try {
const releaseInfo = fs.readFileSync('/etc/os-release', 'utf8');
const match = releaseInfo.match(/^ID(?:_LIKE)?=(.*)$/m);
if (match) {
const idLike = match[1].trim().toLowerCase();
if (idLike.includes('rhel') || idLike.includes('fedora') || idLike.includes('centos')) {
distroFamily = 'RHEL';
} else if (idLike.includes('debian') || idLike.includes('ubuntu') || idLike.includes('kali')) {
distroFamily = 'Debian';
}
}
} catch (err) {
console.error('Error getting Linux distribution family:', err);
}
return distroFamily;
}

3. Update Choice Windowโ€‹

function createChoiceWindow(updateOptions) {
const win = new BrowserWindow({
width: 600,
height: 400,
webPreferences: {
nodeIntegration: true,
},
});

win.loadURL(`data:text/html,
<html>
<body>
<h2>Choose an update package:</h2>
<ul>
${updateOptions
.map(
(option, index) =>
`<li><a id="option-${index}" href="${option.url}">${option.name}</a></li>`
)
.join('')}
</ul>
<script>
const { shell } = require('electron');
document.addEventListener('click', (event) => {
if (event.target.tagName === 'A') {
event.preventDefault();
shell.openExternal(event.target.href);
}
});
</script>
</body>
</html>`
);

return win;
}

4. Update Check Functionโ€‹

function checkUpdates() {
let url = `http://localhost:9000/checkVersion?app_name=${app_name}&version=${version}&platform=${os.platform()}&arch=${os.arch()}&owner=${owner}`;

if (channel !== undefined) {
url += `&channel=${channel}`;
}

fetch(url, { method: 'GET' })
.then((res) => res.json())
.then((data) => {
console.log(data);
if (data.update_available) {
const message = `You have an older version. Would you like to update your app?`;
dialog.showMessageBox({
type: 'question',
title: 'Update available',
message: message,
buttons: ['Yes', 'No'],
defaultId: 0,
}).then(({ response }) => {
if (response === 0) {
const updateOptions = [];
for (const key in data) {
if (key.startsWith('update_url_')) {
updateOptions.push({ name: key.substring(11).toUpperCase(), url: data[key] });
}
}
const choiceWindow = createChoiceWindow(updateOptions);
}
});
}
})
.catch(() => {});
}

5. Main Window Creationโ€‹

function createWindow() {
let osName = os.platform();
let pcArch = os.arch();
if (osName === 'linux') {
osName = getLinuxDistributionFamily();
}
const title = `${app_name} - v${version} (${osName}-${pcArch})`;

let win = new BrowserWindow({
width: 400,
height: 300,
webPreferences: {
nodeIntegration: true,
},
});

win.setTitle(title);
win.loadFile('index.html');
win.on('closed', () => {
win = null;
});

checkUpdates();
}

app.whenReady().then(createWindow);

Running Your App ๐Ÿƒโ€โ™‚๏ธโ€‹

To start your app, simply run:

npm start

If everything is set up correctly in faynoSync and a newer version exists, you'll see something like this in your logs:

{
"critical": false,
"update_available": true,
"update_url_dmg": "http://localhost:9010/cb-faynosync-s3-public/myapp-example/nightly/darwin/arm64/myapp-0.0.2.0.dmg"
}

And in your app's UI, you'll see a notification about the available update. After agreeing to update, you can download and install the new version.


Next Steps ๐Ÿš€โ€‹

  1. Customize the update process to match your app's needs
  2. Add more sophisticated update handling
  3. Implement your own update installation logic
  4. Add progress indicators for downloads

Need Help? ๐Ÿคโ€‹

If you have any questions or need assistance:

  1. Check out our documentation
  2. Create an issue on GitHub

How to try faynoSync?โ€‹

  1. Follow the Getting Started guide:
    ๐Ÿ‘‰ https://ku9nov.github.io/faynoSync-site/docs/category/getting-started

  2. Create your app using the REST API or web dashboard:
    ๐Ÿ“ฆ API Docs: https://ku9nov.github.io/faynoSync-site/docs/api
    ๐Ÿ–ฅ๏ธ Dashboard UI: https://github.com/ku9nov/faynoSync-dashboard

  3. Upload at least two versions of your application.

  4. Check for updates with this simple request:
    ๐Ÿ“ก /info/latest


If you find this project helpful, please consider subscribing, leaving a comment, or giving it a star, create Issue or feature request on GitHub.
Your support keeps the project alive and growing ๐Ÿ’š

Local Development with faynoSync โ€” Choose Your Path

ยท 3 min read

Getting started with faynoSync development? Great! You have two main options for setting up your local environment. Whether you prefer a traditional local setup or the convenience of Docker, we've got you covered.


Option 1: Traditional Local Development ๐Ÿ–ฅ๏ธโ€‹

Perfect for developers who want full control over their environment and need to make frequent code changes.

What You'll Need:โ€‹

Setting Up:โ€‹

  1. Install all required services
  2. Create your .env file with necessary configurations
  3. Run faynoSync:
    # First run (with migrations)
    go run faynoSync.go --migration

    # Subsequent runs
    go run faynoSync.go

Benefits:โ€‹

  • โšก Fast development cycle
  • ๐Ÿ”ง Direct access to all components
  • ๐Ÿงช Easy debugging
  • ๐Ÿ”„ Quick code changes

Testing Your Setup:โ€‹

Want to make sure everything is working correctly? Just run:

go test

This will verify that all components are properly configured and your local environment is ready for development.


Option 2: Docker Development ๐Ÿณโ€‹

Ideal for quick setup and testing, or when you want to avoid installing dependencies locally.

What You'll Need:โ€‹

Two Ways to Use Docker:โ€‹

1. Full Container Setupโ€‹

docker-compose up --build

Perfect for:

  • ๐Ÿš€ Quick testing
  • ๐Ÿงช Initial setup
  • ๐Ÿ”„ Testing API functionality

2. Hybrid Approachโ€‹

docker-compose -f docker-compose.yaml -f docker-compose.development.yaml up

This starts only the dependencies (MongoDB and MinIO) while you run faynoSync locally.

Benefits:โ€‹

  • ๐Ÿš€ Quick setup
  • ๐Ÿงฉ Isolated environment
  • ๐Ÿ”„ Consistent across machines
  • ๐Ÿงช Easy testing

Testing Your Setup:โ€‹

After running docker-compose up --build, wait until the s3-service successfully creates the bucket, then run:

docker exec -it faynoSync_backend "/usr/bin/faynoSync_tests"

This will run the test suite inside the container to verify everything is working correctly.


Environment Configuration โš™๏ธโ€‹

Both approaches need proper environment configuration. Here are the key variables you'll need:

# Storage Configuration
STORAGE_DRIVER=minio
S3_ACCESS_KEY=your_access_key
S3_SECRET_KEY=your_secret_key
S3_BUCKET_NAME=your_bucket

# Database Configuration
MONGODB_URL=mongodb://root:password@127.0.0.1/faynosync_db

# API Configuration
API_URL=http://localhost:9000
PORT=9000

For a complete list of environment variables, check out our Environment Configuration Guide.


Which Option Should You Choose? ๐Ÿค”โ€‹

Choose Local Development if you:โ€‹

  • ๐Ÿ”ง Need to modify the code frequently
  • ๐Ÿ› Want to debug easily
  • โšก Need fast development cycles
  • ๐Ÿ’ป Prefer direct control over your environment

Choose Docker if you:โ€‹

  • ๐Ÿš€ Want quick setup
  • ๐Ÿงช Need to test the API
  • ๐Ÿ’ป Work on multiple machines
  • ๐Ÿงฉ Prefer isolated environments

What's Next? ๐Ÿš€โ€‹

In our next posts, we'll explore:

  • How to properly use Fetch latest version of app request
  • Performance optimization tips

Stay tuned for more faynoSync tips and tricks! ๐Ÿ’š


How to try faynoSync?โ€‹

  1. Follow the Getting Started guide:
    ๐Ÿ‘‰ https://ku9nov.github.io/faynoSync-site/docs/category/getting-started

  2. Create your app using the REST API or web dashboard:
    ๐Ÿ“ฆ API Docs: https://ku9nov.github.io/faynoSync-site/docs/api
    ๐Ÿ–ฅ๏ธ Dashboard UI: https://github.com/ku9nov/faynoSync-dashboard

  3. Upload at least two versions of your application.

  4. Check for updates with this simple request:
    ๐Ÿ“ก /info/latest


If you find this project helpful, please consider subscribing, leaving a comment, or giving it a star, create Issue or feature request on GitHub.
Your support keeps the project alive and growing ๐Ÿ’š