refactor: automate protocol sync and reorganize repo for store readiness

This commit is contained in:
MacBook
2026-05-04 04:43:30 +02:00
parent 0f1f8bde1b
commit 652f1cef4f
10 changed files with 117 additions and 7 deletions
+2 -2
View File
@@ -29,9 +29,9 @@ KoalaSync is a specialized tool for **synchronized video playback** across multi
## 3. Mandatory Reading
Before touching any code, you MUST read the following documents in order:
1. [ARCHITECTURE.md](ARCHITECTURE.md) Detailed communication flows, Dual Heartbeat, and two-phase sync protocol.
1. [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) Detailed communication flows, Dual Heartbeat, and two-phase sync protocol.
2. [extension/README.md](extension/README.md) Extension components, tab structure, and loading process.
3. [SYNC_GUIDE.md](SYNC_GUIDE.md) Protocol constants and synchronization requirements.
3. [docs/SYNC_GUIDE.md](docs/SYNC_GUIDE.md) Protocol constants and synchronization requirements.
## 4. The "Vanilla JS Mirror" Pattern
To avoid boot-time race conditions in Manifest V3 without a bundler, the following architectural trade-off is enforced:
+35
View File
@@ -0,0 +1,35 @@
# Contributing to KoalaSync
Thank you for your interest in contributing to KoalaSync! We welcome all contributions, from bug reports to new features.
## Development Workflow
### 1. Prerequisites
- Node.js (v18+)
- Docker (for local server testing)
### 2. Setup
1. Clone the repository.
2. Run `npm install` in the root directory to install build dependencies.
### 3. Protocol Synchronization
KoalaSync uses a "Single Source of Truth" for protocol constants in `shared/constants.js`.
- **CRITICAL**: If you modify the constants, you MUST run the build script:
```bash
node scripts/build-extension.js
```
This will automatically synchronize the changes to the extension and generate the browser-specific bundles in the `dist/` folder.
### 4. Code Standards
- **Vanilla JS**: The extension must remain dependency-free. Do not add npm packages to the `extension/` directory.
- **Privacy**: Do not add external requests (CDNs, fonts, etc.).
- **Comments**: Maintain the existing documentation style, especially for complex sync logic.
## Pull Request Process
1. Create a new branch for your feature or bugfix.
2. Ensure your code is tested locally (Chrome and Firefox).
3. Update relevant documentation (e.g., `docs/ARCHITECTURE.md` if you change the protocol).
4. Submit your PR with a clear description of the changes.
## Security
If you find a security vulnerability, please do not open a public issue. Instead, refer to our `SECURITY.md` for disclosure instructions.
+27
View File
@@ -0,0 +1,27 @@
# Privacy Policy
KoalaSync is built with a **Privacy-First** architecture. We believe that your browsing habits and watch history are your business, not ours.
## 1. Zero External Requests
The KoalaSync extension and its official marketing website are designed to be completely self-contained.
- **No CDNs**: We do not load scripts or styles from external Content Delivery Networks.
- **No Google Fonts**: We use a modern system font stack to avoid tracking by third-party font services.
- **No Analytics**: There are no tracking pixels, telemetry, or analytics scripts (like Google Analytics or Mixpanel) in the codebase.
## 2. Data Sovereignty
- **Self-Hostable**: You can host your own relay server using our Docker image, giving you 100% control over your data.
- **Memory-Only State**: The relay server stores all room data in RAM. Nothing is written to a database or disk. When a room is empty, it is purged immediately.
- **No Logs**: The official relay server (`sync.shik3i.net`) does not log user IP addresses or room activity.
## 3. Extension Permissions
KoalaSync requires the following permissions to function:
- `storage`: To remember your username and server preferences locally.
- `tabs` & `scripting`: To detect video elements on pages you visit so they can be synchronized.
- `<all_urls>`: Necessary because KoalaSync works on any website with a `<video>` tag.
## 4. Zero Data Collection
We do not collect, store, or sell any personal information. Your `peerId` and `username` are stored only on your local device and transmitted only to the relay server you choose to connect to.
---
**KoalaSync is and always will be Open Source.** You are encouraged to audit the code yourself on [GitHub](https://github.com/Shik3i/KoalaSync).
+9 -3
View File
@@ -15,10 +15,16 @@ KoalaSync is a premium, lightweight Browser Extension and Relay Server for synch
- `server/`: Node.js + Socket.IO Relay Server (Containerized).
- `website/`: Marketing landing page & **Invitation Bridge**.
- `shared/`: Protocol constants and domain blacklist.
- `scripts/`: Development utilities for protocol synchronization.
- `scripts/`: Development utilities (Build & Sync).
- `docs/`: Technical documentation ([ARCHITECTURE.md](docs/ARCHITECTURE.md), [SYNC_GUIDE.md](docs/SYNC_GUIDE.md)).
> [!NOTE]
> For deep technical dives, see [ARCHITECTURE.md](ARCHITECTURE.md) and [SYNC_GUIDE.md](SYNC_GUIDE.md).
## 🔒 Privacy & Security
KoalaSync is built for users who value privacy.
- **Zero Collection**: We do not collect or sell your data.
- **Zero Telemetry**: No analytics or tracking scripts.
- **Zero Dependencies**: The extension uses 100% Vanilla JS for maximum security.
- **Self-Hostable**: Full Docker support for private relay servers.
See [PRIVACY.md](PRIVACY.md) for our full commitment.
## Key Features
- **Global Synchronization**: Synchronize Play, Pause, and Seeking on any website with a `<video>` tag.
Binary file not shown.

After

Width:  |  Height:  |  Size: 462 KiB

+6
View File
@@ -0,0 +1,6 @@
# Technical Documentation
This directory contains deep-dives into the KoalaSync protocol and architecture.
- [ARCHITECTURE.md](ARCHITECTURE.md): Communication flows, Dual Heartbeat, and Sync logic.
- [SYNC_GUIDE.md](SYNC_GUIDE.md): Protocol constants and sync requirements.
+3 -1
View File
@@ -14,7 +14,8 @@
}
window.koalaSyncInjected = true;
// Local Protocol Constants (Mirroring shared/constants.js)
// --- SHARED_EVENTS_INJECT_START ---
// This block is automatically updated by /scripts/build-extension.js
const EVENTS = {
PLAY: "play",
PAUSE: "pause",
@@ -26,6 +27,7 @@
EPISODE_LOBBY: "episode_lobby",
EPISODE_READY: "episode_ready"
};
// --- SHARED_EVENTS_INJECT_END ---
let expectedEvents = new Set();
let expectedTimeouts = {};
+35 -1
View File
@@ -37,17 +37,51 @@ console.log('✓ constants.js and blacklist.js synced to extension/shared/');
const baseManifest = JSON.parse(fs.readFileSync(baseManifestPath, 'utf8'));
// Helper to copy files, ignoring manifest.json and manifest.base.json
// Also injects shared constants into content.js
function copyExtensionFiles(targetDir) {
fs.mkdirSync(targetDir, { recursive: true });
// Read master constants for injection
const masterConstantsPath = path.join(rootDir, 'shared', 'constants.js');
const constantsContent = fs.readFileSync(masterConstantsPath, 'utf8');
// Extract the EVENTS object using regex
const eventsMatch = constantsContent.match(/export const EVENTS = ({[\s\S]+?});/);
if (!eventsMatch) {
throw new Error('CRITICAL: Could not find EVENTS object in shared/constants.js');
}
const eventsObject = eventsMatch[1];
const items = fs.readdirSync(extDir);
for (const item of items) {
if (item === 'manifest.json' || item === 'manifest.base.json') continue;
const srcPath = path.join(extDir, item);
const destPath = path.join(targetDir, item);
if (fs.lstatSync(srcPath).isDirectory()) {
fs.cpSync(srcPath, destPath, { recursive: true });
} else {
fs.copyFileSync(srcPath, destPath);
if (item === 'content.js') {
// Perform injection
let content = fs.readFileSync(srcPath, 'utf8');
const startMarker = '// --- SHARED_EVENTS_INJECT_START ---';
const endMarker = '// --- SHARED_EVENTS_INJECT_END ---';
const pattern = new RegExp(`${startMarker}[\\s\\S]+?${endMarker}`);
const replacement = `${startMarker}\n // This block is automatically updated by /scripts/build-extension.js\n const EVENTS = ${eventsObject};\n ${endMarker}`;
if (pattern.test(content)) {
content = content.replace(pattern, replacement);
fs.writeFileSync(destPath, content);
console.log('✓ Injected shared events into content.js');
} else {
console.warn('⚠️ WARNING: Markers not found in content.js, skipping injection.');
fs.copyFileSync(srcPath, destPath);
}
} else {
fs.copyFileSync(srcPath, destPath);
}
}
}
}