mirror of
https://github.com/polaroi8d/cactoide.git
synced 2026-03-22 22:25:29 +00:00
Compare commits
3 Commits
fix/databa
...
fix/missin
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1fa879f36 | ||
|
|
b723aac180 | ||
|
|
277ad3ff14 |
@@ -10,4 +10,14 @@ APP_VERSION=latest
|
||||
PORT=5173
|
||||
HOSTNAME=0.0.0.0
|
||||
|
||||
# Logger configuration
|
||||
LOG_PRETTY=true
|
||||
LOG_LEVEL="trace"
|
||||
|
||||
# If you don't want to use the default home page you can turn off
|
||||
# in this case the /discovery page remain the home of your site
|
||||
PUBLIC_LANDING_INFO=true
|
||||
|
||||
# Federation config
|
||||
FEDERATION_INSTANCE=false
|
||||
|
||||
|
||||
15
README.md
15
README.md
@@ -59,6 +59,17 @@ make db-only
|
||||
npm run dev -- --open
|
||||
```
|
||||
|
||||
#### Build the image in local
|
||||
|
||||
```
|
||||
docker build \
|
||||
--build-arg LOG_PRETTY=${LOG_PRETTY:-true} \
|
||||
--build-arg LOG_LEVEL=${LOG_LEVEL:-trace} \
|
||||
--build-arg PUBLIC_LANDING_INFO=${PUBLIC_LANDING_INFO:-true} \
|
||||
--build-arg FEDERATION_INSTANCE=${FEDERATION_INSTANCE:-true} \
|
||||
-t cactoide-example .
|
||||
```
|
||||
|
||||
Your app will be available at `http://localhost:5173`. You can use the Makefile commands to run the application or the database, eg.: `make db-only`.
|
||||
|
||||
Use the `database/seed.sql` if you want to populate your database with dummy data.
|
||||
@@ -103,12 +114,12 @@ Your instance will automatically expose:
|
||||
To add your instance to the global federation list (so other instances can discover your events):
|
||||
|
||||
1. Fork the [Cactoide repository](https://github.com/polaroi8d/cactoide)
|
||||
2. Add your instance URL to the `instances` array in [`federation.config.js`](https://github.com/polaroi8d/cactoide/blob/main/federation.config.js):
|
||||
2. Add your instance URL to the `instances` array in `federation.config.js`:
|
||||
3. Open a pull request to the main repository
|
||||
|
||||
Once merged, your instance will appear in the federation network, and other instances will be able to discover and display your public events.
|
||||
|
||||
You can view all registered federated instances in the main repository: [`federation.config.js`](https://github.com/polaroi8d/cactoide/blob/main/federation.config.js) file.
|
||||
You can view all registered federated instances in the main repository: `federation.config.js` file.
|
||||
|
||||
### Options
|
||||
|
||||
|
||||
@@ -37,6 +37,10 @@ services:
|
||||
DATABASE_URL: ${DATABASE_URL:-postgres://cactoide:cactoide_password@postgres:5432/cactoide_database}
|
||||
PORT: 3000
|
||||
HOSTNAME: ${HOSTNAME:-0.0.0.0}
|
||||
LOG_PRETTY: ${LOG_PRETTY:-true}
|
||||
LOG_LEVEL: ${LOG_LEVEL:-trace}
|
||||
PUBLIC_LANDING_INFO: ${PUBLIC_LANDING_INFO:-true}
|
||||
FEDERATION_INSTANCE: ${FEDERATION_INSTANCE:-true}
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
const config = {
|
||||
name: 'Cactoide Genesis',
|
||||
instances: [
|
||||
{
|
||||
url: 'cactoide.org'
|
||||
}
|
||||
// {
|
||||
// url: 'cactoide.org'
|
||||
// }
|
||||
// {
|
||||
// url: 'YOUR_INSTANCE_URL'
|
||||
// }
|
||||
@@ -1,76 +1,18 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { logger } from '$lib/logger';
|
||||
import type { Event } from '$lib/types';
|
||||
|
||||
import config from '../../federation.config.js';
|
||||
|
||||
console.log(config.instances);
|
||||
|
||||
interface FederationConfig {
|
||||
name: string;
|
||||
instances: Array<{ url: string }>;
|
||||
}
|
||||
import config from '$lib/config/federation.config.js';
|
||||
|
||||
interface FederationEventsResponse {
|
||||
events: Array<Event & { federation?: boolean }>;
|
||||
count?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the federation config file
|
||||
*/
|
||||
async function readFederationConfig(): Promise<FederationConfig | null> {
|
||||
try {
|
||||
const configPath = join(process.cwd(), 'federation.config.js');
|
||||
|
||||
// Use dynamic import to load the config file as a module
|
||||
// This is safer than eval and works with ES modules
|
||||
const configModule = await import(configPath + '?t=' + Date.now());
|
||||
const config = (configModule.default || configModule.config) as FederationConfig;
|
||||
|
||||
if (config && config.instances && Array.isArray(config.instances)) {
|
||||
return config;
|
||||
}
|
||||
|
||||
logger.warn('Invalid federation config structure');
|
||||
return null;
|
||||
} catch (error) {
|
||||
// If dynamic import fails, try reading as text and parsing
|
||||
try {
|
||||
const configPath = join(process.cwd(), 'federation.config.js');
|
||||
const configContent = readFileSync(configPath, 'utf-8');
|
||||
|
||||
// Try to extract JSON-like structure
|
||||
const configMatch = configContent.match(/instances:\s*\[([\s\S]*?)\]/);
|
||||
if (configMatch) {
|
||||
// Simple parsing - extract URLs
|
||||
const urlMatches = configContent.matchAll(/url:\s*['"]([^'"]+)['"]/g);
|
||||
const instances = Array.from(urlMatches, (match) => ({ url: match[1] }));
|
||||
|
||||
if (instances.length > 0) {
|
||||
return {
|
||||
name: 'Federated Instances',
|
||||
instances
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch (fallbackError) {
|
||||
logger.error({ error: fallbackError }, 'Error parsing federation.config.js as fallback');
|
||||
}
|
||||
|
||||
logger.error({ error }, 'Error reading federation.config.js');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches events from a single federated instance
|
||||
*/
|
||||
async function fetchEventsFromInstance(instanceUrl: string): Promise<Event[]> {
|
||||
try {
|
||||
// Ensure URL has protocol and append /api/federation/events
|
||||
|
||||
const apiUrl = `http://${instanceUrl}/api/federation/events`;
|
||||
|
||||
logger.debug({ apiUrl }, 'Fetching events from federated instance');
|
||||
@@ -120,18 +62,11 @@ async function fetchEventsFromInstance(instanceUrl: string): Promise<Event[]> {
|
||||
* Fetches events from all configured federated instances
|
||||
*/
|
||||
export async function fetchAllFederatedEvents(): Promise<Event[]> {
|
||||
const config = await readFederationConfig();
|
||||
|
||||
if (!config || !config.instances || config.instances.length === 0) {
|
||||
logger.debug('No federation config or instances found');
|
||||
return [];
|
||||
}
|
||||
|
||||
logger.info(
|
||||
{ instanceCount: config.instances.length },
|
||||
'Fetching events from federated instances'
|
||||
);
|
||||
|
||||
// Fetch from all instances in parallel
|
||||
const fetchPromises = config.instances.map((instance) => fetchEventsFromInstance(instance.url));
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { database } from '$lib/database/db';
|
||||
import { events } from '$lib/database/schema';
|
||||
import { eq, count } from 'drizzle-orm';
|
||||
import { logger } from '$lib/logger';
|
||||
import federationConfig from '../../../../../federation.config.js';
|
||||
import federationConfig from '$lib/config/federation.config.js';
|
||||
|
||||
import { FEDERATION_INSTANCE } from '$env/static/private';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { logger } from '$lib/logger';
|
||||
import federationConfig from '../../../federation.config.js';
|
||||
import federationConfig from '$lib/config/federation.config.js';
|
||||
|
||||
interface InstanceInfo {
|
||||
name: string;
|
||||
|
||||
@@ -130,10 +130,7 @@
|
||||
|
||||
<p class="py-8 text-center text-slate-400">
|
||||
{t('instance.description')}
|
||||
<a
|
||||
href="https://github.com/cactoide/cactoide/blob/main/federation.config.js"
|
||||
class="text-violet-300/80">{t('instance.configFile')}</a
|
||||
>
|
||||
{t('instance.configFile')}
|
||||
{t('instance.file')}
|
||||
</p>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user