Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:undyingwraith/ipmc into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
undyingwraith committed Jun 18, 2024
2 parents 5549b71 + b91302f commit 9181f78
Show file tree
Hide file tree
Showing 43 changed files with 555 additions and 612 deletions.
18 changes: 13 additions & 5 deletions packages/core/src/Application.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
import { Container, interfaces } from 'inversify';
import { IApplication } from './IApplication';
import { IModule } from './Modules/IModule';
import { IApplicationRegistration } from './IApplicationRegistration';

export class Application implements IApplication, IApplicationRegistration {
public registerConstant<T>(service: T, identifier: symbol) {
if (this.container.isBound(identifier)) {
this.container.unbind(identifier);
}
this.container.bind<T>(identifier).toConstantValue(service);
}

export class Application implements IApplication {
public register<T>(service: interfaces.Newable<T>, identifier: symbol) {
if (this.container.isBound(identifier)) {
this.container.unbind(identifier);
}
this.container.bind<T>(identifier).to(service);
}

getService<T>(identifier: symbol): T | undefined {
return this.container.get<T>(identifier);
public use(module: IModule): void {
module(this);
}

use(module: IModule): void {
module(this);
public getService<T>(identifier: symbol): T | undefined {
return this.container.get<T>(identifier);
}

/**
Expand Down
16 changes: 0 additions & 16 deletions packages/core/src/IApplication.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,11 @@
import { interfaces } from 'inversify';
import { IModule } from './Modules/IModule';

/**
* The main application holding everything together.
*/
export interface IApplication {
/**
* Registers a new service.
* @param service service to register.
* @param identifier symbol for the service.
*/
register<T>(service: interfaces.ServiceIdentifier<T>, identifier: symbol): void;

/**
* Gets a service identified by its symbol.
* @param identifier symbol for the service.
* @returns The requested service.
*/
getService<T>(identifier: symbol): T | undefined;

/**
* Registers a {@link IModule}.
* @param module {@link IModule} to use in the {@link IApplication}.
*/
use(module: IModule): void;
}
24 changes: 24 additions & 0 deletions packages/core/src/IApplicationRegistration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { IModule } from './Modules';
import { interfaces } from 'inversify';

export interface IApplicationRegistration {
/**
* Registers a new service.
* @param service service to register.
* @param identifier symbol for the service.
*/
register<T>(service: interfaces.ServiceIdentifier<T>, identifier: symbol): void;

/**
* Registers a new constant.
* @param service service to register.
* @param identifier symbol for the service.
*/
registerConstant<T>(service: T, identifier: symbol): void;

/**
* Registers a {@link IModule}.
* @param module {@link IModule} to use in the {@link IApplication}.
*/
use(module: IModule): void;
}
4 changes: 3 additions & 1 deletion packages/core/src/Modules/CoreModule.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { IKeyValueStoreSymbol, IObjectStoreSymbol } from 'ipmc-interfaces';
import { IIndexManagerSymbol, IKeyValueStoreSymbol, IObjectStoreSymbol } from 'ipmc-interfaces';
import { MemoryKeyValueStore } from '../Services/MemoryKeyValueStore';
import { ObjectStore } from '../Services/ObjectStore';
import { IModule } from './IModule';
import { IndexManager } from '../Services/IndexManager';

export const CoreModule: IModule = (app) => {
app.register(MemoryKeyValueStore, IKeyValueStoreSymbol);
app.register(ObjectStore, IObjectStoreSymbol);
app.register(IndexManager, IIndexManagerSymbol);
};
4 changes: 2 additions & 2 deletions packages/core/src/Modules/IModule.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IApplication } from '../IApplication';
import { IApplicationRegistration } from '../IApplicationRegistration';

/**
* A Module for an {@link IApplication}.
* @param app the instance of an {@link IApplication}.
*/
export type IModule = (app: IApplication) => void;
export type IModule = (app: IApplicationRegistration) => void;
92 changes: 92 additions & 0 deletions packages/core/src/Services/IndexManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Signal } from '@preact/signals-core';
import { inject, injectable, postConstruct, preDestroy } from 'inversify';
import { IIndexManager, IIpfsService, IIpfsServiceSymbol, ILibrary, ILibraryIndex, IObjectStore, IObjectStoreSymbol, IProfile, IProfileSymbol, ITask, isMovieLibrary, isSeriesLibrary } from 'ipmc-interfaces';
import { MovieIndexFetcher, SeriesIndexFetcher } from './Indexer';

@injectable()
export class IndexManager implements IIndexManager {
public constructor(
@inject(IProfileSymbol) private readonly profile: IProfile,
@inject(IIpfsServiceSymbol) private readonly ipfs: IIpfsService,
@inject(IObjectStoreSymbol) private readonly objectStore: IObjectStore,
) {
for (const lib of this.profile.libraries) {
this.libraries.set(lib.name, new Signal<ILibrary>(lib));
const indexSignal = new Signal<ILibraryIndex<any> | undefined>(this.objectStore.get(this.getIndexStorageKey(lib.name)));
this.indexes.set(lib.name, indexSignal);
indexSignal.subscribe((newState) => {
if (newState !== undefined) {
this.objectStore.set(this.getIndexStorageKey(lib.name), newState);
}
});
}
}

@postConstruct()
public start(): void {
this.triggerUpdate();
this.timer = setInterval(() => {
this.triggerUpdate();
}, 15 * 60 * 1000);
}

@preDestroy()
public stop(): void {
clearInterval(this.timer);
}

public indexes = new Map<string, Signal<ILibraryIndex<any> | undefined>>();

public tasks = new Signal<ITask[]>([]);

private getIndexStorageKey(name: string) {
return `${this.profile.id}_index_${name}`;
}

private triggerUpdate(): void {
for (const library of this.libraries.values()) {
const lib = library.value;
if (!this.updates.has(lib.name)) {
const task = {
title: 'Updating library ' + lib.name,
};
this.tasks.value = [...this.tasks.value, task];
this.updates.set(lib.name, this.updateLibrary(lib).finally(() => {
this.updates.delete(lib.name);
this.tasks.value = this.tasks.value.filter(t => t != task);
}));
}
}
}

private async updateLibrary(library: ILibrary): Promise<void> {
const index = this.indexes.get(library.name);
if (library.upstream != undefined && index != undefined) {
try {
const cid = await this.ipfs.resolve(library.upstream);
const indexer = isMovieLibrary(library) ? new MovieIndexFetcher(this.ipfs, library) : isSeriesLibrary(library) ? new SeriesIndexFetcher(this.ipfs, library) : undefined;
if (index.value?.cid != cid || indexer?.version !== index.value?.indexer) {
if (indexer == undefined) {
throw new Error(`Unknown library type [${library.type}]`);
}

const newIndex = await indexer.fetchIndex();

index.value = {
cid: cid,
indexer: indexer.version,
index: newIndex,
};
}
} catch (ex) {
console.error(ex);
}
}
}

private libraries = new Map<string, Signal<ILibrary>>();

private updates = new Map<string, Promise<void>>();

private timer: any;
}
1 change: 1 addition & 0 deletions packages/core/src/Services/Indexer/IIndexFetcher.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export interface IIndexFetcher<TIndex> {
fetchIndex(): Promise<TIndex>;
version: string;
}
2 changes: 2 additions & 0 deletions packages/core/src/Services/Indexer/MovieIndexFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export class MovieIndexFetcher implements IIndexFetcher<IMovieMetaData[]> {
constructor(private readonly node: IIpfsService, private readonly lib: IGenericLibrary<IMovieMetaData, 'movie'>) {
}

public version = '0';

public async fetchIndex(): Promise<IMovieMetaData[]> {
const files = (await this.node.ls(this.lib.root.toString())).filter(f => f.type == 'dir');
const index = [];
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/Services/Indexer/SeriesIndexFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export class SeriesIndexFetcher implements IIndexFetcher<ISeriesMetaData[]> {
constructor(private readonly node: IIpfsService, private readonly lib: IGenericLibrary<ISeriesMetaData, 'series'>) {
}

public version = '0';

public async fetchIndex(): Promise<ISeriesMetaData[]> {
const files = (await this.node.ls(this.lib.root.toString())).filter(f => f.type == 'dir');
const index = [];
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/Services/Indexer/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { type IIndexFetcher } from './IIndexFetcher';
export { MovieIndexFetcher } from './MovieIndexFetcher';
export { SeriesIndexFetcher } from './SeriesIndexFetcher';
103 changes: 0 additions & 103 deletions packages/core/src/Services/ProfileManager/BaseProfileManager.ts

This file was deleted.

Loading

0 comments on commit 9181f78

Please sign in to comment.