remove expired room

This commit is contained in:
Peter Maquiran
2024-10-07 13:27:49 +01:00
parent d8eb3ddbd6
commit 0dd4fd665b
101 changed files with 698 additions and 4682 deletions
@@ -6,9 +6,9 @@ import { DexieRoomsTable, RoomTableColumn } from 'src/app/infra/database/dexie/i
import { DexieTypingsTable, TypingTableColumn } from 'src/app/infra/database/dexie/instance/chat/schema/typing';
import { MessageEntity } from 'src/app/core/chat/entity/message';
import { AttachmentTableColumn, DexieAttachmentsTableSchema } from 'src/app/infra/database/dexie/instance/chat/schema/attachment';
import { DexieDistributionTable, DistributionTable, DistributionTableColumn } from './instance/chat/schema/destribution';
import { BoldTableColumn, DexieBoldTable } from './instance/chat/schema/bold';
import { DexieUserPhotoTable, UserPhotoTable, UserPhotoTableColumn } from './instance/chat/schema/user-foto';
import { DexieDistributionTable, DistributionTable, DistributionTableColumn } from './schema/destribution';
import { BoldTableColumn, DexieBoldTable } from './schema/bold';
import { DexieUserPhotoTable, UserPhotoTable, UserPhotoTableColumn } from './schema/user-foto';
// import FDBFactory from 'fake-indexeddb/lib/FDBFactory';
// import FDBKeyRange from 'fake-indexeddb/lib/FDBKeyRange';
@@ -0,0 +1,210 @@
import { EntityTable } from 'Dexie';
import { z } from 'zod';
const DscSchema = z.object({
environment: z.string(),
public_key: z.string(),
release: z.string(),
replay_id: z.any(),
sample_rate: z.string(),
sampled: z.boolean(),
trace_id: z.string(),
transaction: z.any(),
});
const MetaSchema = z.object({
breadcrumbs: z.object({
values: z.record(z.string(), z.any()),
}),
});
const Breadcrumbs2Schema = z.object({
values: z.array(z.object({
timestamp: z.number(),
type: z.string(),
category: z.string(),
level: z.string(),
message: z.string().optional(),
data: z.object({
method: z.string().optional(),
status_code: z.number().optional(),
url: z.string().optional(),
arguments: z.array(z.any()).optional(),
logger: z.string().optional(),
from: z.string().optional(),
to: z.string().optional(),
__span: z.string().optional(),
}).optional(),
event_id: z.string().optional(),
})),
});
const MetricsSchema = z.object({
"bytes.ingested.event": z.number(),
"bytes.stored.event": z.number(),
});
const ContextsSchema = z.object({
angular: z.object({
type: z.string(),
version: z.number(),
}),
browser: z.object({
name: z.string(),
version: z.string(),
type: z.string(),
}),
os: z.object({
name: z.string(),
version: z.string(),
type: z.string(),
}),
trace: z.object({
trace_id: z.string(),
span_id: z.string(),
op: z.string(),
status: z.string(),
client_sample_rate: z.number(),
type: z.string(),
}),
});
const ExceptionSchema = z.object({
values: z.array(z.object({
type: z.string(),
value: z.string(),
stacktrace: z.object({
frames: z.array(z.object({
function: z.string(),
module: z.string(),
filename: z.string(),
abs_path: z.string(),
lineno: z.number().optional(),
colno: z.number().optional(),
pre_context: z.array(z.string()).optional(),
context_line: z.string().optional(),
post_context: z.array(z.string()).optional(),
in_app: z.boolean(),
data: z.object({
sourcemap: z.string(),
resolved_with: z.string(),
sourcemap_origin: z.object({
scraped_file: z.string(),
}),
symbolicated: z.boolean(),
orig_in_app: z.number().optional(),
}).optional(),
})),
}),
raw_stacktrace: z.object({
frames: z.array(z.object({
function: z.string().optional(),
filename: z.string(),
abs_path: z.string(),
lineno: z.number().optional(),
colno: z.number().optional(),
context_line: z.string().optional(),
post_context: z.array(z.string()).optional(),
in_app: z.boolean(),
})),
}),
mechanism: z.object({
type: z.string(),
handled: z.boolean(),
}),
})),
});
const GroupingConfigSchema = z.object({
enhancements: z.string(),
id: z.string(),
});
const IngestPathSchema = z.array(z.object({
version: z.string(),
public_key: z.string(),
}));
const MetadataSchema = z.object({
display_title_with_tree_label: z.boolean(),
filename: z.string(),
function: z.string(),
in_app_frame_mix: z.string(),
type: z.string(),
value: z.string(),
});
const RequestSchema = z.object({
url: z.string(),
headers: z.array(z.tuple([z.string(), z.string()])),
});
const ScrapingAttemptSchema = z.array(z.object({
status: z.string(),
url: z.string(),
}));
const SdkSchema = z.object({
name: z.string(),
version: z.string(),
integrations: z.array(z.string()),
packages: z.array(z.object({
name: z.string(),
version: z.string(),
})),
});
const UserSchema = z.object({
ip_address: z.string(),
geo: z.object({
country_code: z.string(),
city: z.string(),
subdivision: z.string(),
region: z.string(),
}),
sentry_user: z.string(),
});
const SentryErrorTableSchema = z.object({
event_id: z.string(),
project: z.number(),
release: z.string(),
dist: z.string(),
platform: z.string(),
message: z.string(),
datetime: z.string(),
tags: z.array(z.array(z.string())),
_dsc: DscSchema,
_meta: MetaSchema,
_metrics: MetricsSchema,
breadcrumbs: Breadcrumbs2Schema,
contexts: ContextsSchema,
culprit: z.string(),
environment: z.string(),
exception: ExceptionSchema,
fingerprint: z.array(z.string()),
grouping_config: GroupingConfigSchema,
hashes: z.array(z.string()),
ingest_path: IngestPathSchema,
key_id: z.string(),
level: z.string(),
location: z.string(),
logger: z.string(),
metadata: MetadataSchema,
nodestore_insert: z.number(),
received: z.number(),
request: RequestSchema,
scraping_attempts: ScrapingAttemptSchema,
sdk: SdkSchema,
timestamp: z.number(),
title: z.string(),
type: z.string(),
user: UserSchema,
version: z.string(),
});
export type SentryErrorTable = z.infer<typeof SentryErrorTableSchema>;
export type DexieSentryErrorTable = EntityTable<SentryErrorTable, 'event_id'>;
export const SentryErrorTableColumn = 'event_id';
@@ -0,0 +1,17 @@
import { Dexie } from 'Dexie';
import { DexieSentryErrorTable, SentryErrorTableColumn } from './schema/SentryErrors';
// import FDBFactory from 'fake-indexeddb/lib/FDBFactory';
// import FDBKeyRange from 'fake-indexeddb/lib/FDBKeyRange';
// Database declaration (move this to its own module also)
export const LogsDatabase = new Dexie('logs-analytics', {
// indexedDB: new FDBFactory,
// IDBKeyRange: FDBKeyRange, // Mocking IDBKeyRange
}) as Dexie & {
sentryError: DexieSentryErrorTable
};
LogsDatabase.version(1).stores({
sentryError: SentryErrorTableColumn
});
+11 -3
View File
@@ -6,9 +6,17 @@ import { Observable } from 'rxjs';
export abstract class HttpAdapter {
abstract post<T>(url: string, body: any): Promise<Result<HttpResult<T>, HttpErrorResponse>>
abstract get<T>(url: string, options?: Object): Promise<Result<HttpResult<T>, HttpErrorResponse>>
abstract get<T>(url: string, options?: IHttpOptions): Promise<Result<HttpResult<T>, HttpErrorResponse>>
abstract put<T>(url: string, body: any): Promise<Result<HttpResult<T>, HttpErrorResponse>>
abstract patch<T>(url: string, body?: Object): Promise<Result<HttpResult<T>, HttpErrorResponse>>
abstract patch<T>(url: string, body?: Object): Promise<Result<HttpResult<T>, HttpErrorResponse>>
abstract delete<T>(url: string, body?: Object): Promise<Result<HttpResult<T>, HttpErrorResponse>>
abstract listen():Observable<Result<HttpResult<any>, HttpErrorResponse>>
}
}
// Define the interface for HTTP options
export interface IHttpOptions {
params?: { [param: string]: string | number };
headers?: HttpHeaders;
responseType?: 'json' | 'text' | 'blob' | 'arraybuffer';
}
+18 -3
View File
@@ -3,7 +3,9 @@ import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ok, err, Result } from 'neverthrow';
import { HttpResult } from './type';
import { BehaviorSubject } from 'rxjs';
import { BehaviorSubject, Observable } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { IHttpOptions } from './adapter';
@Injectable({
providedIn: 'root'
@@ -32,9 +34,22 @@ export class HttpService {
}
}
async get<T>(url: string, options = {}): Promise<Result<HttpResult<T>, HttpErrorResponse>> {
async get<T>(url: string, options?: IHttpOptions): Promise<Result<HttpResult<T>, HttpErrorResponse>> {
try {
const response = await this.http.get<T>(url, { ...options, observe: 'response' }).toPromise();
let httpParams = new HttpParams();
if (options?.params) {
Object.keys(options.params).forEach(key => {
httpParams = httpParams.append(key, String(options.params[key]));
});
}
const httpOptions = {
params: httpParams,
headers: options?.headers || new HttpHeaders(),
responseType: options?.responseType || 'json' as any,
};
const response = await this.http.get<T>(url, { ...httpOptions, observe: 'response', responseType: httpOptions.responseType }).toPromise();
const data = {
method: 'GET',
+6 -1
View File
@@ -20,7 +20,7 @@ export abstract class IDexieRepository<T, R, I = EntityTable<any, any>> {
abstract find(filter: Partial<T>): Promise<RepositoryResult<R[], T[]>>
abstract findOne(filter: Partial<T>): Promise<RepositoryResult<T | undefined, T>>
abstract findOne(filter: Partial<T>): Promise<RepositoryResult<T & ILocalModel | undefined, T>>
abstract findAll(): Promise<RepositoryResult<T[], T>>
@@ -28,3 +28,8 @@ export abstract class IDexieRepository<T, R, I = EntityTable<any, any>> {
abstract clear(): Promise<Result<any, any>>
}
export abstract class ILocalModel{
abstract save()
abstract delete()
}
@@ -2,7 +2,7 @@ import { Result, ok, err } from 'neverthrow';
import Dexie, { EntityTable, Table } from 'Dexie';
import { ZodError, ZodObject, ZodSchema } from 'zod';
import { Logger } from 'src/app/services/logger/main/service';
import { IDexieRepository, RepositoryResult } from '../adapter'
import { IDexieRepository, ILocalModel, RepositoryResult } from '../adapter'
import { IDBError, IDBErrorParams, IDexieError } from '../types';
// Define a type for the Result of repository operations
@@ -150,6 +150,10 @@ export class DexieRepository<T, R, I = EntityTable<any, any>> implements IDexieR
const schema = this.ZodSchema.array()
const dataValidation = schema.safeParse(updatedDocument)
if(updatedDocument.length == 0) {
console.log(`dexie.js failed to update many into ${this.table.name}, empty array)`)
}
if(dataValidation.success) {
try {
const updatedCount = await this.table.bulkPut(dataValidation.data);
@@ -157,7 +161,7 @@ export class DexieRepository<T, R, I = EntityTable<any, any>> implements IDexieR
} catch (_error) {
const error: IDexieError = _error
return err(new DBError({
message: `dexie.js Failed to update into ${this.table.name}, ${error.message} `,
message: `dexie.js Failed to update many into ${this.table.name}, ${error.message} `,
parameters: document,
error: error
}))
@@ -214,7 +218,7 @@ export class DexieRepository<T, R, I = EntityTable<any, any>> implements IDexieR
}
}
async findOne(filter: Partial<T>): Promise<RepositoryResult<T | undefined, T>> {
async findOne(filter: Partial<T>): Promise<RepositoryResult<T & ILocalModel | undefined, T>> {
try {
const document = await this.table.where(filter).first();
return ok(document);
@@ -228,7 +232,7 @@ export class DexieRepository<T, R, I = EntityTable<any, any>> implements IDexieR
}
}
async findAll(): Promise<RepositoryResult<T[], T>> {
async findAll(): Promise<RepositoryResult<(T & ILocalModel)[], T>> {
try {
const documents = await this.table.toArray()
return ok(documents);
@@ -265,3 +269,23 @@ export class DexieRepository<T, R, I = EntityTable<any, any>> implements IDexieR
}
}
}
export class LocalModel<T, R, I = EntityTable<any, any>> implements ILocalModel {
constructor(
private table: EntityTable<any, any>,
private repository: DexieRepository<T, R, I>,
private db?:Dexie,
) {}
save() {
const primaryKey = this.db[this.table.name].schema.primKey.name
return this.repository.update(primaryKey, this as any)
}
delete() {
const primaryKey = this.db[this.table.name].schema.primKey.name
return this.repository.delete(primaryKey)
}
}
+3 -3
View File
@@ -2,11 +2,11 @@ import * as signalR from '@microsoft/signalr';
import { BehaviorSubject, Observable, race, timer } from 'rxjs';
import { ok, Result, err } from 'neverthrow';
import { SessionStore } from 'src/app/store/session.service';
import { filter, first } from 'rxjs/operators';
import { filter, first, map } from 'rxjs/operators';
import { v4 as uuidv4 } from 'uuid'
import { ISignalRInput } from '../type';
import { MessageOutPutDataDTO } from 'src/app/core/chat/repository/dto/messageOutputDTO';
import { Subject } from 'rxjs';
export interface SocketMessage<T> {
method: string,
data: T
@@ -170,7 +170,7 @@ export class SignalRConnection {
}
public getConnectionState(): Observable<boolean> {
return this.connectionStateSubject.asObservable();
return this.connectionStateSubject.asObservable()
}
public getDisconnectTrigger(): Observable<boolean> {