refactoring stuff to make sure the right responsibility is fullfilled in the right place
This commit is contained in:
parent
fa9264326b
commit
ddf4519f41
3 changed files with 138 additions and 127 deletions
|
@ -1,38 +1,68 @@
|
|||
import Dexie, { EntityTable } from "dexie";
|
||||
import { createContext, ParentComponent, useContext } from "solid-js";
|
||||
import { Accessor, createContext, createMemo, onMount, ParentComponent, useContext } from "solid-js";
|
||||
import { createStore } from "solid-js/store";
|
||||
import { isServer } from "solid-js/web";
|
||||
import * as json from './parser/json';
|
||||
|
||||
interface FileEntity {
|
||||
name: string;
|
||||
key: string;
|
||||
handle: FileSystemDirectoryHandle;
|
||||
}
|
||||
|
||||
type Store = Dexie & {
|
||||
files: EntityTable<FileEntity, 'name'>;
|
||||
files: EntityTable<FileEntity, 'key'>;
|
||||
};
|
||||
|
||||
interface FilesContextType {
|
||||
set(name: string, handle: FileSystemDirectoryHandle): Promise<void>;
|
||||
get(name: string): Promise<FileSystemDirectoryHandle | undefined>;
|
||||
interface InternalFilesContextType {
|
||||
onChange(hook: (key: string, handle: FileSystemDirectoryHandle) => any): void;
|
||||
set(key: string, handle: FileSystemDirectoryHandle): Promise<void>;
|
||||
get(key: string): Promise<FileSystemDirectoryHandle | undefined>;
|
||||
remove(key: string): Promise<void>;
|
||||
keys(): Promise<string[]>;
|
||||
entries(): Promise<FileEntity[]>;
|
||||
list(): Promise<FileSystemDirectoryHandle[]>;
|
||||
}
|
||||
|
||||
interface FilesContextType {
|
||||
readonly files: Accessor<FileEntity[]>,
|
||||
|
||||
get(key: string): Accessor<FileSystemDirectoryHandle | undefined>
|
||||
set(key: string, handle: FileSystemDirectoryHandle): Promise<void>;
|
||||
remove(key: string): Promise<void>;
|
||||
}
|
||||
|
||||
const FilesContext = createContext<FilesContextType>();
|
||||
|
||||
const clientContext = (): FilesContextType => {
|
||||
const clientContext = (): InternalFilesContextType => {
|
||||
const db = new Dexie('Files') as Store;
|
||||
|
||||
db.version(1).stores({
|
||||
files: 'name, handle'
|
||||
files: 'key, handle'
|
||||
});
|
||||
|
||||
return {
|
||||
async set(name: string, handle: FileSystemDirectoryHandle) {
|
||||
await db.files.put({ name, handle });
|
||||
onChange(hook: (key: string, handle: FileSystemDirectoryHandle) => any) {
|
||||
const callHook = (key: string, handle: FileSystemDirectoryHandle) => setTimeout(() => hook(key, handle), 1);
|
||||
|
||||
db.files.hook('creating', (_: string, { key, handle }: FileEntity) => { callHook(key, handle); });
|
||||
db.files.hook('deleting', (_: string, { key, handle }: FileEntity) => callHook(key, handle));
|
||||
db.files.hook('updating', (_1: Object, _2: string, { key, handle }: FileEntity) => callHook(key, handle));
|
||||
},
|
||||
async get(name: string) {
|
||||
return (await db.files.get(name))?.handle;
|
||||
|
||||
async set(key: string, handle: FileSystemDirectoryHandle) {
|
||||
await db.files.put({ key, handle });
|
||||
},
|
||||
async get(key: string) {
|
||||
return (await db.files.get(key))?.handle;
|
||||
},
|
||||
async remove(key: string) {
|
||||
return (await db.files.delete(key));
|
||||
},
|
||||
async keys() {
|
||||
return (await db.files.toArray()).map(f => f.key);
|
||||
},
|
||||
async entries() {
|
||||
return await db.files.toArray();
|
||||
},
|
||||
async list() {
|
||||
const files = await db.files.toArray();
|
||||
|
@ -42,25 +72,69 @@ const clientContext = (): FilesContextType => {
|
|||
}
|
||||
};
|
||||
|
||||
const serverContext = (): FilesContextType => ({
|
||||
set() {
|
||||
const serverContext = (): InternalFilesContextType => ({
|
||||
onChange(hook: (key: string, handle: FileSystemDirectoryHandle) => any) {
|
||||
|
||||
},
|
||||
set(key: string, handle: FileSystemDirectoryHandle) {
|
||||
return Promise.resolve();
|
||||
},
|
||||
get(name: string) {
|
||||
get(key: string) {
|
||||
return Promise.resolve(undefined);
|
||||
},
|
||||
remove(key: string) {
|
||||
return Promise.resolve(undefined);
|
||||
},
|
||||
keys() {
|
||||
return Promise.resolve([]);
|
||||
},
|
||||
entries() {
|
||||
return Promise.resolve([]);
|
||||
},
|
||||
list() {
|
||||
return Promise.resolve<FileSystemDirectoryHandle[]>([]);
|
||||
return Promise.resolve([]);
|
||||
},
|
||||
});
|
||||
|
||||
export const FilesProvider: ParentComponent = (props) => {
|
||||
const ctx = isServer ? serverContext() : clientContext();
|
||||
const internal = isServer ? serverContext() : clientContext();
|
||||
|
||||
return <FilesContext.Provider value={ctx}>{props.children}</FilesContext.Provider>;
|
||||
const [state, setState] = createStore<{ files: FileEntity[] }>({ files: [] });
|
||||
|
||||
const updateFilesInState = async () => {
|
||||
const entities = await internal.entries();
|
||||
|
||||
setState('files', entities);
|
||||
};
|
||||
|
||||
internal.onChange((key: string, handle: FileSystemDirectoryHandle) => {
|
||||
updateFilesInState();
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
updateFilesInState();
|
||||
});
|
||||
|
||||
const context: FilesContextType = {
|
||||
files: createMemo(() => state.files),
|
||||
|
||||
get(key: string): Accessor<FileSystemDirectoryHandle | undefined> {
|
||||
return createMemo(() => state.files.find(entity => entity.key === key)?.handle);
|
||||
},
|
||||
|
||||
async set(key: string, handle: FileSystemDirectoryHandle) {
|
||||
await internal.set(key, handle);
|
||||
},
|
||||
|
||||
async remove(key: string) {
|
||||
await internal.remove(key);
|
||||
},
|
||||
};
|
||||
|
||||
return <FilesContext.Provider value={context}>{props.children}</FilesContext.Provider>;
|
||||
}
|
||||
|
||||
export const useFiles = () => useContext(FilesContext);
|
||||
export const useFiles = () => useContext(FilesContext)!;
|
||||
|
||||
export const load = (file: File): Promise<Map<string, string> | undefined> => {
|
||||
switch (file.type) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue