Files
CT/src/Model/Files/fileModel.ts
T

196 lines
5.0 KiB
TypeScript
Raw Normal View History

2024-07-21 21:41:19 +02:00
// this file is responsible for managing files within chats.
2024-07-22 02:05:27 +02:00
import { DATA_VERSION, ValidObject } from "../Utility/typeSafety";
2024-07-22 11:49:05 +02:00
import {
HandlerManager,
2024-07-22 11:49:05 +02:00
createTimestamp,
parseValidObject,
stringify,
} from "../Utility/utility";
import StorageModel, { filePaths } from "../Global/storageModel";
2024-07-24 00:12:45 +02:00
import BoardModel from "./boadModel";
2024-07-22 02:05:27 +02:00
import ChatModel from "../Chat/chatModel";
2024-07-22 00:37:36 +02:00
import { v4 } from "uuid";
2024-07-21 21:45:18 +02:00
export default class FileModel {
chatModel: ChatModel;
2024-07-21 23:32:20 +02:00
storageModel: StorageModel;
2024-07-21 21:45:18 +02:00
2024-07-24 00:12:45 +02:00
taskModel: BoardModel;
2024-07-22 02:16:58 +02:00
fileContentHandlerManager: HandlerManager<FileContent<string>> = new HandlerManager();
2024-07-22 03:01:04 +02:00
// paths
getBasePath = (): string[] => {
return StorageModel.getPath(
"chat",
filePaths.chat.files(this.chatModel.id)
);
};
getFileContainerPath = (): string[] => {
2024-07-23 18:23:26 +02:00
return [...this.getBasePath(), FileModelSubPath.Data];
};
getModelContainerPath = (
2024-07-23 18:23:26 +02:00
modelName: FileModelSubPath
2024-07-22 12:39:26 +02:00
): string[] => {
2024-07-23 18:23:26 +02:00
return [...this.getBasePath(), FileModelSubPath.Model, modelName];
2024-07-22 12:39:26 +02:00
};
2024-07-22 03:01:04 +02:00
getFilePath = (fileId: string): string[] => {
return [...this.getFileContainerPath(), fileId];
2024-07-22 03:01:04 +02:00
};
2024-07-22 18:11:18 +02:00
getFileContentPath = (fileId: string, fileContentId: string): string[] => {
const filePath: string[] = this.getFilePath(fileId);
2024-07-22 18:11:18 +02:00
return [...filePath, fileContentId];
2024-07-22 03:01:04 +02:00
};
2024-07-22 23:33:57 +02:00
// handlers
2024-07-22 18:11:18 +02:00
handleStringifiedFileContent = (stringifiedFileContent: string): void => {
const fileContent: FileContent<string> | null = parseValidObject(
stringifiedFileContent,
FileContentReference
);
2024-07-22 18:11:18 +02:00
if (fileContent == null) return;
2024-07-22 00:37:36 +02:00
2024-07-22 18:11:18 +02:00
this.handleFileContent(fileContent);
};
2024-07-22 18:11:18 +02:00
handleFileContent = (fileContent: FileContent<string>): void => {
const didStore: boolean = this.storeFileContent(fileContent);
if (didStore == false) return;
2024-07-22 14:36:03 +02:00
2024-07-22 18:11:18 +02:00
this.taskModel.handleFileContent(fileContent);
this.fileContentHandlerManager.trigger(fileContent);
2024-07-21 23:32:20 +02:00
};
2024-07-22 11:49:05 +02:00
// methods
2024-07-22 18:11:18 +02:00
addFileContent = (fileContent: FileContent<string>): void => {
this.handleFileContent(fileContent);
this.chatModel.sendMessage("", fileContent);
2024-07-22 11:49:05 +02:00
};
// storage
2024-07-22 18:11:18 +02:00
storeFileContent = (fileContent: FileContent<string>): boolean => {
const fileContentPath: string[] = this.getFileContentPath(
fileContent.fileId,
fileContent.fileContentId
2024-07-21 23:32:20 +02:00
);
2024-07-22 00:37:36 +02:00
2024-07-22 18:11:18 +02:00
// check if fileContent already exists
const existingFileContent: string | null =
this.storageModel.read(fileContentPath);
if (existingFileContent != null) return false;
2024-07-22 00:37:36 +02:00
2024-07-22 18:11:18 +02:00
const stringifiedContent: string = stringify(fileContent);
this.storageModel.write(fileContentPath, stringifiedContent);
return true;
2024-07-21 23:32:20 +02:00
};
listFileIds = (): string[] => {
2024-07-22 03:01:04 +02:00
return this.storageModel.list(this.getBasePath());
2024-07-21 23:32:20 +02:00
};
2024-07-22 18:11:18 +02:00
listFileContentIds = (fileId: string): string[] => {
2024-07-22 13:09:33 +02:00
const filePath: string[] = this.getFilePath(fileId);
2024-07-22 11:57:47 +02:00
return this.storageModel.list(filePath);
};
2024-07-22 18:11:18 +02:00
selectLatestFileContentId = (
fileContentIds: string[]
): string | undefined => {
2024-07-22 18:11:18 +02:00
return fileContentIds[fileContentIds.length - 1];
2024-07-21 23:32:20 +02:00
};
2024-07-22 18:11:18 +02:00
getFileContent = <T extends FileContent<string>>(
fileId: string,
2024-07-22 18:11:18 +02:00
fileContentName: string,
reference: T
): T | null => {
2024-07-22 18:11:18 +02:00
const filePath: string[] = this.getFileContentPath(fileId, fileContentName);
const fileContentOrNull: T | null = this.storageModel.readStringifiable(
filePath,
reference
);
2024-07-22 18:11:18 +02:00
return fileContentOrNull;
};
2024-07-22 18:11:18 +02:00
getLatestFileContent = <T extends FileContent<string>>(
fileId: string,
reference: T
): T | null => {
2024-07-22 18:11:18 +02:00
const fileContentsIds: string[] = this.listFileContentIds(fileId);
const latestFileContentId: string | undefined =
this.selectLatestFileContentId(fileContentsIds);
if (latestFileContentId == undefined) return null;
2024-07-22 18:11:18 +02:00
const fileContent: T | null = this.getFileContent(
fileId,
2024-07-22 18:11:18 +02:00
latestFileContentId,
reference
);
2024-07-22 18:11:18 +02:00
return fileContent;
2024-07-21 23:32:20 +02:00
};
2024-07-21 21:45:18 +02:00
// init
2024-07-21 23:32:20 +02:00
constructor(chatModel: ChatModel, storageModel: StorageModel) {
2024-07-21 21:45:18 +02:00
this.chatModel = chatModel;
2024-07-21 23:32:20 +02:00
this.storageModel = storageModel;
2024-07-22 02:16:58 +02:00
2024-07-24 00:12:45 +02:00
this.taskModel = new BoardModel(this.storageModel, chatModel, this);
2024-07-21 21:45:18 +02:00
}
2024-07-21 21:41:19 +02:00
2024-07-21 23:32:20 +02:00
// utility
2024-07-22 18:11:18 +02:00
static generateFileContentId = (creationDate): string => {
return creationDate + v4();
2024-07-21 23:32:20 +02:00
};
2024-07-21 20:54:18 +02:00
2024-07-22 18:11:18 +02:00
static createFileContent = <T extends string>(
fileId: string,
type: T
2024-07-22 18:11:18 +02:00
): FileContent<T> => {
const creationDate: string = createTimestamp();
2024-07-22 18:11:18 +02:00
const fileContentId: string = FileModel.generateFileContentId(creationDate);
2024-07-22 11:49:05 +02:00
return {
dataVersion: DATA_VERSION,
fileId,
2024-07-22 18:11:18 +02:00
fileContentId,
creationDate,
2024-07-22 11:49:05 +02:00
type,
2024-07-22 01:22:59 +02:00
};
};
2024-07-21 20:54:18 +02:00
}
2024-07-22 12:39:26 +02:00
// paths
2024-07-23 18:23:26 +02:00
export enum FileModelSubPath {
Data = "data",
Model = "model",
ModelView = "view",
2024-07-23 18:23:26 +02:00
ModelTask = "tasks",
2024-07-22 12:39:26 +02:00
};
2024-07-21 23:32:20 +02:00
// types
2024-07-22 18:11:18 +02:00
export interface FileContent<T extends string> extends ValidObject {
fileId: string;
2024-07-22 18:11:18 +02:00
fileContentId: string;
2024-07-22 01:05:19 +02:00
creationDate: string;
2024-07-21 23:32:20 +02:00
2024-07-22 11:49:05 +02:00
type: T;
2024-07-21 20:54:18 +02:00
}
2024-07-22 01:22:59 +02:00
// references
2024-07-22 18:11:18 +02:00
export const FileContentReference: FileContent<string> = {
2024-07-22 01:22:59 +02:00
dataVersion: DATA_VERSION,
fileId: "",
2024-07-22 18:11:18 +02:00
fileContentId: "",
2024-07-22 01:22:59 +02:00
creationDate: "",
type: "",
2024-07-22 01:38:08 +02:00
};