Browse Source

revert BUILDING to master version

streamline-attempt
Matthew Raymer 1 week ago
parent
commit
f82e3d4590
  1. 723
      BUILDING.md

723
BUILDING.md

@ -1,6 +1,6 @@
# Building TimeSafari
This guide explains how to build TimeSafari for different platforms using our unified build scripts.
This guide explains how to build TimeSafari for different platforms.
## Prerequisites
@ -9,54 +9,7 @@ For a quick dev environment setup, use [pkgx](https://pkgx.dev).
- Node.js (LTS version recommended)
- npm (comes with Node.js)
- Git
- For mobile builds: Android Studio (Android) or Xcode (iOS)
- For desktop builds: Capacitor Electron platform
## Unified Build Scripts
TimeSafari now uses unified build scripts that automatically handle environment variables, logging, error handling, and timing. All scripts are located in the `scripts/` directory and use a common utilities library.
### Script Features
- **Automatic Environment Setup**: Each script sets the correct environment variables for its build type
- **Rich Logging**: Colored, timestamped output with different log levels
- **Error Handling**: Proper exit codes and graceful failure recovery
- **Timing**: Automatic execution time tracking for each step
- **Validation**: Checks for required dependencies and files
- **CLI Options**: `--help`, `--verbose`, `--env` flags for all scripts
### Available Scripts
| Script | Purpose | Command |
|--------|---------|---------|
| `capacitor-dev.sh` | Capacitor development | `./scripts/capacitor-dev.sh` |
| `capacitor-build.sh` | Capacitor build | `./scripts/build-capacitor.sh` |
| `web-dev.sh` | Web development | `./scripts/web-dev.sh` |
| `web-build.sh` | Web build | `./scripts/build-web.sh` |
### Environment Variables
All scripts automatically set the correct environment variables for their build type:
| Build Type | VITE_PLATFORM | VITE_PWA_ENABLED | VITE_DISABLE_PWA | NODE_ENV |
|------------|---------------|------------------|------------------|----------|
| `capacitor` | capacitor | false | true | - |
| `web` | web | true | false | - |
### CLI Options
All scripts support these options:
```bash
# Show help
./scripts/build-capacitor.sh --help
# Enable verbose logging
./scripts/build-capacitor.sh --verbose
# Show environment variables
./scripts/build-capacitor.sh --env
```
- For desktop builds: Additional build tools based on your OS
## Forks
@ -77,305 +30,287 @@ Install dependencies:
npm install
```
## Package Management
## Web Dev Locally
TimeSafari uses a mixed package management approach, combining npm and JSR (JavaScript Registry) for optimal dependency management.
```bash
npm run dev
```
### JSR Integration
## Web Build for Server
Some packages are installed via JSR for better ESM support and modern TypeScript compatibility:
1. Run the production build:
```bash
# Install JSR packages
npx jsr add @nostr/tools
rm -rf dist
npm run build:web
```
### Package Migration History
#### nostr-tools → @nostr/tools
The built files will be in the `dist` directory.
**Date**: June 2025
**Reason**: Resolved Vite/Rollup build issues with deep imports
2. To test the production build locally:
**Before** (npm):
You'll likely want to use test locations for the Endorser & image & partner servers; see "DEFAULT_ENDORSER_API_SERVER" & "DEFAULT_IMAGE_API_SERVER" & "DEFAULT_PARTNER_API_SERVER" below.
```typescript
import { finalizeEvent } from "nostr-tools/lib/cjs/index.js";
import { accountFromExtendedKey } from "nostr-tools/lib/cjs/nip06.js";
```bash
npm run serve
```
**After** (JSR):
### Compile and minify for test & production
```typescript
import { finalizeEvent } from "@nostr/tools";
import { accountFromExtendedKey } from "@nostr/tools/nip06";
```
* If there are DB changes: before updating the test server, open browser(s) with current version to test DB migrations.
**Benefits**:
- ✅ Proper ESM support
- ✅ No deep import issues with Vite/Rollup
- ✅ Better TypeScript compatibility
- ✅ Modern package structure
* `npx prettier --write ./sw_scripts/`
### Current Package Strategy
* Update the ClickUp tasks & CHANGELOG.md & the version in package.json, run `npm install`.
- **npm**: Primary package manager for most dependencies
- **JSR**: Used for packages with better ESM support or modern alternatives
- **Mixed approach**: Allows using the best package for each dependency
* Run a build to make sure package-lock version is updated, linting works, etc: `npm install && npm run build`
### When to Use JSR
* Commit everything (since the commit hash is used the app).
Consider using JSR for:
- Packages with ESM/CJS compatibility issues in npm
- Modern TypeScript-first packages
- Packages that work better with modern bundlers
- New dependencies where JSR has a better alternative
* Put the commit hash in the changelog (which will help you remember to bump the version in the step later).
### Vite Configuration
* Tag with the new version, [online](https://gitea.anomalistdesign.com/trent_larson/crowd-funder-for-time-pwa/releases) or `git tag 1.0.2 && git push origin 1.0.2`.
The build system is configured to handle both npm and JSR packages:
* For test, build the app (because test server is not yet set up to build):
```typescript
// vite.config.common.mts
resolve: {
alias: {
'@nostr/tools': path.resolve(__dirname, 'node_modules/@nostr/tools'),
'@nostr/tools/nip06': path.resolve(__dirname, 'node_modules/@nostr/tools/nip06'),
}
}
```bash
TIME_SAFARI_APP_TITLE="TimeSafari_Test" VITE_APP_SERVER=https://test.timesafari.app VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app VITE_DEFAULT_PARTNER_API_SERVER=https://test-partner-api.endorser.ch VITE_DEFAULT_PUSH_SERVER=https://test.timesafari.app VITE_PASSKEYS_ENABLED=true npm run build:web
```
### Troubleshooting Package Issues
... and transfer to the test server:
1. **Build failures with deep imports**
- Check if package has ESM/CJS compatibility issues
- Consider JSR alternative if available
- Update Vite configuration if needed
```bash
rsync -azvu -e "ssh -i ~/.ssh/..." dist ubuntutest@test.timesafari.app:time-safari
```
2. **TypeScript errors**
- Ensure proper type definitions are available
- Check package exports in package.json
- Verify import paths match package structure
(Let's replace that with a .env.development or .env.staging file.)
3. **Mixed package manager issues**
- Keep package.json and node_modules in sync
- Use `npm install` after JSR package additions
- Check for conflicting package versions
(Note: The test BVC_MEETUPS_PROJECT_CLAIM_ID does not resolve as a URL because it's only in the test DB and the prod redirect won't redirect there.)
## Web Development
* For prod, get on the server and run the correct build:
### Local Development
... and log onto the server:
```bash
npm run dev
```
* `pkgx +npm sh`
### Web Build for Server
* `cd crowd-funder-for-time-pwa && git checkout master && git pull && git checkout 1.0.2 && npm install && npm run build:web && cd -`
1. Run the production build:
(The plain `npm run build:web` uses the .env.production file.)
```bash
npm run build:web
```
* Back up the time-safari/dist folder & deploy: `mv time-safari/dist time-safari-dist-prev-2 && mv crowd-funder-for-time-pwa/dist time-safari/`
The built files will be in the `dist` directory.
* Record the new hash in the changelog. Edit package.json to increment version & add "-beta", `npm install`, commit, and push. Also record what version is on production.
2. To test the production build locally:
## Docker Deployment
```bash
npm run serve
```
The application can be containerized using Docker for consistent deployment across environments.
### Prerequisites
### Environment Configuration
- Docker installed on your system
- Docker Compose (optional, for multi-container setups)
For different environments, create `.env` files:
### Building the Docker Image
```bash
# .env.development
VITE_APP_SERVER=https://dev.timesafari.app
VITE_DEFAULT_ENDORSER_API_SERVER=https://dev-api.endorser.ch
VITE_DEFAULT_IMAGE_API_SERVER=https://dev-image-api.timesafari.app
VITE_DEFAULT_PARTNER_API_SERVER=https://dev-partner-api.endorser.ch
VITE_DEFAULT_PUSH_SERVER=https://dev.timesafari.app
VITE_PASSKEYS_ENABLED=true
1. Build the Docker image:
# .env.production
VITE_APP_SERVER=https://timesafari.app
VITE_DEFAULT_ENDORSER_API_SERVER=https://api.endorser.ch
VITE_DEFAULT_IMAGE_API_SERVER=https://image-api.timesafari.app
VITE_DEFAULT_PARTNER_API_SERVER=https://partner-api.endorser.ch
VITE_DEFAULT_PUSH_SERVER=https://timesafari.app
VITE_PASSKEYS_ENABLED=true
```bash
docker build -t timesafari:latest .
```
## Desktop Build (Capacitor Electron)
2. For development builds with specific environment variables:
### Prerequisites
```bash
docker build --build-arg NODE_ENV=development -t timesafari:dev .
```
1. Install Capacitor CLI:
### Running the Container
1. Run the container:
```bash
npm install -g @capacitor/cli
docker run -d -p 80:80 timesafari:latest
```
2. Add Electron platform:
2. For development with hot-reloading:
```bash
npx cap add electron
docker run -d -p 80:80 -v $(pwd):/app timesafari:dev
```
### Development
### Using Docker Compose
For development with automatic environment setup:
Create a `docker-compose.yml` file:
```bash
# Build web assets
npm run build:capacitor
```yaml
version: '3.8'
services:
timesafari:
build: .
ports:
- "80:80"
environment:
- NODE_ENV=production
restart: unless-stopped
```
# Sync with Capacitor
npx cap sync electron
Run with Docker Compose:
# Open in Electron
npx cap open electron
```bash
docker-compose up -d
```
### Production Build
### Production Deployment
For production builds:
For production deployment, consider the following:
1. Use specific version tags instead of 'latest'
2. Implement health checks
3. Configure proper logging
4. Set up reverse proxy with SSL termination
5. Use Docker secrets for sensitive data
Example production deployment:
```bash
# Build web assets
npm run build:capacitor
# Build with specific version
docker build -t timesafari:1.0.0 .
# Sync with Capacitor
npx cap sync electron
# Build Electron app
npx cap build electron
```
### Packaging
Capacitor Electron uses electron-builder for packaging. Configure the build in `capacitor.config.json`:
```json
{
"plugins": {
"ElectronBuilder": {
"buildOptions": {
"appId": "app.timesafari.app",
"productName": "TimeSafari",
"directories": {
"output": "dist-electron-packages"
},
"files": [
"dist/**/*",
"electron/**/*"
],
"linux": {
"target": ["AppImage", "deb"],
"category": "Office"
},
"mac": {
"target": ["dmg", "zip"],
"category": "public.app-category.productivity"
},
"win": {
"target": ["nsis", "portable"]
}
}
}
}
}
# Run with production settings
docker run -d \
--name timesafari \
-p 80:80 \
--restart unless-stopped \
-e NODE_ENV=production \
timesafari:1.0.0
```
### Running the Packaged App
### Troubleshooting Docker
- **Linux**: AppImage files are self-contained executables
- **macOS**: `.app` bundles can be dragged to Applications folder
- **Windows**: `.exe` installers or portable executables
1. **Container fails to start**
- Check logs: `docker logs <container_id>`
- Verify port availability
- Check environment variables
## Mobile Builds (Capacitor)
2. **Build fails**
- Ensure all dependencies are in package.json
- Check Dockerfile syntax
- Verify build context
### Android Build
3. **Performance issues**
- Monitor container resources: `docker stats`
- Check nginx configuration
- Verify caching settings
Prerequisites: Android Studio with Java SDK installed
## Desktop Build (Electron)
#### Complete Build Process
### Linux Build
Use the unified Android build script:
1. Build the electron app in production mode:
```bash
./scripts/build-android.sh
npm run build:electron-prod
```
This script automatically:
1. Sets up environment variables for Capacitor
2. Cleans previous builds
3. Builds web assets
4. Builds Capacitor version
5. Cleans and builds Gradle project
6. Syncs with Capacitor
7. Generates assets
8. Opens Android Studio
2. Package the Electron app for Linux:
#### Manual Steps (if needed)
```bash
# For AppImage (recommended)
npm run electron:build-linux
If you need to run individual steps:
# For .deb package
npm run electron:build-linux-deb
```
3. The packaged applications will be in `dist-electron-packages/`:
- AppImage: `dist-electron-packages/TimeSafari-x.x.x.AppImage`
- DEB: `dist-electron-packages/timesafari_x.x.x_amd64.deb`
### macOS Build
1. Build the electron app in production mode:
1. Build the web assets:
```bash
npm run build:web
npm run build:capacitor
npm run build:electron
npm run electron:build-mac
```
2. Update Android project:
2. Package the Electron app for macOS:
```bash
npx cap sync android
# For Intel Macs
npm run electron:build-mac
# For Universal build (Intel + Apple Silicon)
npm run electron:build-mac-universal
```
3. Generate assets:
3. The packaged applications will be in `dist-electron-packages/`:
- `.app` bundle: `TimeSafari.app`
- `.dmg` installer: `TimeSafari-x.x.x.dmg`
- `.zip` archive: `TimeSafari-x.x.x-mac.zip`
### Code Signing and Notarization (macOS)
For public distribution on macOS, you need to code sign and notarize your app:
1. Set up environment variables:
```bash
npx capacitor-assets generate --android
export CSC_LINK=/path/to/your/certificate.p12
export CSC_KEY_PASSWORD=your_certificate_password
export APPLE_ID=your_apple_id
export APPLE_ID_PASSWORD=your_app_specific_password
```
4. Open in Android Studio:
2. Build with signing:
```bash
npx cap open android
npm run electron:build-mac
```
#### Console Build
For building from the console:
### Running the Packaged App
- **Linux**:
- AppImage: Make executable and run
```bash
cd android
./gradlew clean
./gradlew build -Dlint.baselines.continue=true
cd -
chmod +x dist-electron-packages/TimeSafari-*.AppImage
./dist-electron-packages/TimeSafari-*.AppImage
```
For creating an `aab` file:
- DEB: Install and run
```bash
cd android
./gradlew bundleDebug -Dlint.baselines.continue=true
cd -
sudo dpkg -i dist-electron-packages/timesafari_*_amd64.deb
timesafari
```
For creating a signed release:
- **macOS**:
- `.app` bundle: Double-click `TimeSafari.app` in Finder
- `.dmg` installer:
1. Double-click the `.dmg` file
2. Drag the app to your Applications folder
3. Launch from Applications
- `.zip` archive:
1. Extract the `.zip` file
2. Move `TimeSafari.app` to your Applications folder
3. Launch from Applications
Note: If you get a security warning when running the app:
1. Right-click the app
2. Select "Open"
3. Click "Open" in the security dialog
### Development Testing
For testing the Electron build before packaging:
1. Setup signing configuration in `app/gradle.properties.secrets`
2. Add signing key file `app/time-safari-upload-key-pkcs12.jks`
3. Update version in `app/build.gradle`
4. Build release:
```bash
cd android
./gradlew bundleRelease -Dlint.baselines.continue=true
cd -
# Build and run in development mode (includes DevTools)
npm run electron:dev
# Build in production mode and test
npm run build:electron-prod && npm run electron:start
```
The `aab` file will be at `app/build/outputs/bundle/release`.
## Mobile Builds (Capacitor)
### iOS Build
@ -383,184 +318,154 @@ Prerequisites: macOS with Xcode installed
#### First-time iOS Configuration
- Generate certificates inside Xcode
- Right-click on App and under Signing & Capabilities set the Team
- Generate certificates inside XCode.
- Right-click on App and under Signing & Capabilities set the Team.
#### Each Release
0. First time (or if dependencies change):
#### Build Process
- `pkgx +rubygems.org sh`
- ... and you may have to fix these, especially with pkgx:
```bash
gem_path=$(which gem)
shortened_path="${gem_path:h:h}"
export GEM_HOME=$shortened_path
export GEM_PATH=$shortened_path
```
1. Build the web assets & update ios:
1. Build the web assets & update iOS:
```bash
rm -rf dist
npm run build:web
npm run build:capacitor
npx cap sync ios
```
2. Generate assets:
- If that fails with "Could not find..." then look at the "gem_path" instructions above.
3. Copy the assets:
```bash
# Create required directories
# It makes no sense why capacitor-assets will not run without these but it actually changes the contents.
mkdir -p ios/App/App/Assets.xcassets/AppIcon.appiconset
echo '{"images":[]}' > ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json
mkdir -p ios/App/App/Assets.xcassets/Splash.imageset
echo '{"images":[]}' > ios/App/App/Assets.xcassets/Splash.imageset/Contents.json
# Generate assets
npx capacitor-assets generate --ios
```
3. Update version to match Android & package.json:
```bash
cd ios/App
xcrun agvtool new-version 35
perl -p -i -e "s/MARKETING_VERSION = .*;/MARKETING_VERSION = 1.0.2;/g" App.xcodeproj/project.pbxproj
cd -
```
4. Bump the version to match Android & package.json:
4. Open in Xcode:
```bash
npx cap open ios
```
5. Build and run on simulator or device using Xcode
#### Release Process
1. Choose Product -> Destination -> Any iOS Device
2. Choose Product -> Archive
3. Click Distribute -> App Store Connect
4. In App Store Connect, add the build to the distribution
## Testing
### Complete Test Suite
Run all tests with automatic environment setup:
```bash
./scripts/test-all.sh
cd ios/App && xcrun agvtool new-version 35 && perl -p -i -e "s/MARKETING_VERSION = .*;/MARKETING_VERSION = 1.0.2;/g" App.xcodeproj/project.pbxproj && cd -
# Unfortunately this edits Info.plist directly.
#xcrun agvtool new-marketing-version 0.4.5
```
### Mobile Tests
Run mobile-specific tests:
5. Open the project in Xcode:
```bash
./scripts/test-mobile.sh
npx cap open ios
```
### Environment Testing
6. Use Xcode to build and run on simulator or device.
Test environment variable handling:
* Select Product -> Destination with some Simulator version. Then click the run arrow.
```bash
./scripts/test-env.sh
```
7. Release
## Docker Deployment
* Someday: Under "General" we want to rename a bunch of things to "Time Safari"
* Choose Product -> Destination -> Any iOS Device
* Choose Product -> Archive
* This will trigger a build and take time, needing user's "login" keychain password (user's login password), repeatedly.
* If it fails with `building for 'iOS', but linking in dylib (.../.pkgx/zlib.net/v1.3.0/lib/libz.1.3.dylib) built for 'macOS'` then run XCode outside that terminal (ie. not with `npx cap open ios`).
* Click Distribute -> App Store Connect
* In AppStoreConnect, add the build to the distribution: remove the current build with the "-" when you hover over it, then "Add Build" with the new build.
* May have to go to App Review, click Submission, then hover over the build and click "-".
* It can take 15 minutes for the build to show up in the list of builds.
* You'll probably have to "Manage" something about encryption, disallowed in France.
* Then "Save" and "Add to Review" and "Resubmit to App Review".
The application can be containerized using Docker for consistent deployment across environments.
### Prerequisites
- Docker installed on your system
- Docker Compose (optional, for multi-container setups)
### Android Build
### Building the Docker Image
Prerequisites: Android Studio with Java SDK installed
1. Build the Docker image:
1. Build the web assets:
```bash
docker build -t timesafari:latest .
rm -rf dist
npm run build:web
npm run build:capacitor
```
2. For development builds with specific environment variables:
2. Update Android project with latest build:
```bash
docker build --build-arg NODE_ENV=development -t timesafari:dev .
npx cap sync android
```
### Running the Container
1. Run the container:
3. Copy the assets
```bash
docker run -d -p 80:80 timesafari:latest
npx capacitor-assets generate --android
```
2. For development with hot-reloading:
4. Bump version to match iOS & package.json: android/app/build.gradle
5. Open the project in Android Studio:
```bash
docker run -d -p 80:80 -v $(pwd):/app timesafari:dev
npx cap open android
```
### Using Docker Compose
6. Use Android Studio to build and run on emulator or device.
Create a `docker-compose.yml` file:
## Android Build from the console
```yaml
version: '3.8'
services:
timesafari:
build: .
ports:
- "80:80"
environment:
- NODE_ENV=production
restart: unless-stopped
```bash
cd android
./gradlew clean
./gradlew build -Dlint.baselines.continue=true
cd -
```
Run with Docker Compose:
... or, to create the `aab` file, `bundle` instead of `build`:
```bash
docker-compose up -d
./gradlew bundleDebug -Dlint.baselines.continue=true
```
### Production Deployment
For production deployment, consider the following:
1. Use specific version tags instead of 'latest'
2. Implement health checks
3. Configure proper logging
4. Set up reverse proxy with SSL termination
5. Use Docker secrets for sensitive data
... or, to create a signed release:
Example production deployment:
* Setup by adding the app/gradle.properties.secrets file (see properties at top of app/build.gradle) and the app/time-safari-upload-key-pkcs12.jks file
* In app/build.gradle, bump the versionCode and maybe the versionName
* Then `bundleRelease`:
```bash
# Build with specific version
docker build -t timesafari:1.0.0 .
# Run with production settings
docker run -d \
--name timesafari \
-p 80:80 \
--restart unless-stopped \
-e NODE_ENV=production \
timesafari:1.0.0
cd android
./gradlew bundleRelease -Dlint.baselines.continue=true
cd -
```
### Troubleshooting Docker
1. **Container fails to start**
- Check logs: `docker logs <container_id>`
- Verify port availability
- Check environment variables
... and find your `aab` file at app/build/outputs/bundle/release
2. **Build fails**
- Ensure all dependencies are in package.json
- Check Dockerfile syntax
- Verify build context
At play.google.com/console:
3. **Performance issues**
- Monitor container resources: `docker stats`
- Check nginx configuration
- Verify caching settings
- Go to the Testing Track (eg. Closed).
- Click "Create new release".
- Upload the `aab` file.
- Hit "Next".
- Save, go to "Publishing Overview" as prompted, and click "Send changes for review".
## Configuration
- Note that if you add testers, you have to go to "Publishing Overview" and send those changes or your (closed) testers won't see it.
### Deep Links
#### Android Configuration
## Android Configuration for deep links
You must add the following intent filter to the `android/app/src/main/AndroidManifest.xml` file:
@ -573,94 +478,4 @@ You must add the following intent filter to the `android/app/src/main/AndroidMan
</intent-filter>
```
Note: When using `timesafari://` scheme, you may encounter build errors about missing http(s) scheme and host attributes. This is expected for custom URL schemes.
#### iOS Configuration
For iOS deep links, configure the URL scheme in Xcode:
1. Open the project in Xcode
2. Select your app target
3. Go to Info tab
4. Add URL Types with scheme `timesafari`
## Troubleshooting
### Common Issues
1. **Environment Variables Not Set**
- Use `--env` flag to check current environment: `./scripts/build-capacitor.sh --env`
- Verify `.env` file exists and is properly formatted
- Check script output for environment setup messages
2. **Build Failures**
- Use `--verbose` flag for detailed logging: `./scripts/build-capacitor.sh --verbose`
- Check prerequisites are installed
- Verify all dependencies are installed: `npm install`
3. **Permission Issues**
- Make scripts executable: `chmod +x scripts/*.sh`
- Check file permissions on build directories
4. **Platform-Specific Issues**
- **Android**: Verify Android Studio and SDK are properly configured
- **iOS**: Ensure Xcode and certificates are set up correctly
- **Electron**: Check Capacitor Electron platform installation
### Getting Help
- Check script help: `./scripts/build-capacitor.sh --help`
- Review script documentation in `scripts/README.md`
- Test environment setup: `./scripts/test-env.sh`
- Test common utilities: `./scripts/test-common.sh`
### Platform Support Matrix
| Platform | Mode | PWA Enabled | Native Features | Notes |
|----------|------|-------------|-----------------|-------|
| `web` | web | true | false | Standard web browser |
| `capacitor` | capacitor | false | true | Mobile app (iOS/Android) |
| `electron` | capacitor | false | true | Desktop app (via Capacitor Electron) |
## Platform Service Architecture
TimeSafari uses a unified platform service architecture that works across all platforms:
### Platform Detection
The `CapacitorPlatformService` automatically detects the platform and adjusts capabilities:
```typescript
getCapabilities(): PlatformCapabilities {
const platform = Capacitor.getPlatform();
const isElectron = platform === "electron";
return {
hasFileSystem: true,
hasCamera: true,
isMobile: !isElectron, // false for Electron, true for mobile
isIOS: platform === "ios",
hasFileDownload: isElectron, // Electron can download files directly
needsFileHandlingInstructions: !isElectron, // Mobile needs instructions
isNativeApp: true,
};
}
```
### Unified Database Layer
All platforms use the same SQLite database through Capacitor plugins:
- **Mobile**: `@capacitor-community/sqlite` plugin
- **Desktop**: Same plugin via Capacitor Electron
- **Web**: IndexedDB fallback with absurd-sql
### Feature Parity
The same Capacitor plugins work across all platforms:
- File system operations
- Camera access
- SQLite database
- Deep linking
- Sharing functionality
... though when we tried that most recently it failed to 'build' the APK with: http(s) scheme and host attribute are missing, but are required for Android App Links [AppLinkUrlError]

Loading…
Cancel
Save