Jacob Schmidt 0465b05845 feat: add shutdown command, auth/entries backend, and editor panel
- Add Rust shutdown command that kills sidecar and exits app cleanly
- Frontend calls invoke('shutdown') after vault flush on close
- Add auth.ts, entries.ts, and normalize.ts backend modules
- Add EditorPanel.svelte component
- Expand entries store with full CRUD support
- Add JournalEntryDtos and JournalEntryDtoMapper in Journal.Core
- Update entry search, fragments, and sidecar CLI

Co-Authored-By: Oz <oz-agent@warp.dev>
2026-02-26 15:34:28 -06:00

87 lines
2.0 KiB
TypeScript

import { sendCommand } from "./client";
import { pickCase } from "./normalize";
export type FragmentDto = {
id: string;
type: string;
description: string;
time: string;
tags: string[];
};
export type CreateFragmentPayload = {
type: string;
description: string;
tags?: string[];
};
export type UpdateFragmentPayload = {
type?: string;
description?: string;
tags?: string[];
time?: string;
};
export type FragmentDtoRaw = {
id?: string;
type?: string;
description?: string;
time?: string;
tags?: string[];
Id?: string;
Type?: string;
Description?: string;
Time?: string;
Tags?: string[];
};
export function normalizeFragment(raw: FragmentDtoRaw): FragmentDto {
return {
id: pickCase(raw, "id", "Id", ""),
type: pickCase(raw, "type", "Type", ""),
description: pickCase(raw, "description", "Description", ""),
time: pickCase(raw, "time", "Time", ""),
tags: pickCase(raw, "tags", "Tags", [] as string[])
};
}
export async function listFragments(): Promise<FragmentDto[]> {
const data = await sendCommand<FragmentDtoRaw[]>({
action: "fragments.list"
});
return data.map(normalizeFragment).filter((item) => Boolean(item.id));
}
export async function getFragment(id: string): Promise<FragmentDto | null> {
const data = await sendCommand<FragmentDtoRaw | null>({
action: "fragments.get",
id
});
if (!data) return null;
const normalized = normalizeFragment(data);
return normalized.id ? normalized : null;
}
export async function createFragment(payload: CreateFragmentPayload): Promise<FragmentDto> {
const data = await sendCommand<FragmentDtoRaw>({
action: "fragments.create",
payload
});
return normalizeFragment(data);
}
export function updateFragment(id: string, payload: UpdateFragmentPayload): Promise<boolean> {
return sendCommand<boolean>({
action: "fragments.update",
id,
payload
});
}
export function deleteFragment(id: string): Promise<boolean> {
return sendCommand<boolean>({
action: "fragments.delete",
id
});
}