Compare commits
2 Commits
aafb08e63f
...
a436d57ce5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a436d57ce5 | ||
|
|
b60f42f6fe |
@ -30,11 +30,15 @@ function runtimeForCurrentPlatform() {
|
||||
if (arch === "arm64") return "osx-arm64";
|
||||
return "osx-x64";
|
||||
}
|
||||
throw new Error(`Unsupported platform '${process.platform}' for sidecar publish.`);
|
||||
throw new Error(
|
||||
`Unsupported platform '${process.platform}' for sidecar publish.`,
|
||||
);
|
||||
}
|
||||
|
||||
function sidecarFileName() {
|
||||
return process.platform === "win32" ? "Journal.Sidecar.exe" : "Journal.Sidecar";
|
||||
return process.platform === "win32"
|
||||
? "Journal.Sidecar.exe"
|
||||
: "Journal.Sidecar";
|
||||
}
|
||||
|
||||
const runtime = runtimeForCurrentPlatform();
|
||||
@ -42,7 +46,9 @@ const sidecarName = sidecarFileName();
|
||||
const publishedSidecar = path.join(publishOutputDir, sidecarName);
|
||||
const bundledSidecar = path.join(tauriBinDir, sidecarName);
|
||||
|
||||
console.log(`Publishing sidecar for ${process.platform}/${process.arch} (${runtime})...`);
|
||||
console.log(
|
||||
`Publishing sidecar for ${process.platform}/${process.arch} (${runtime})...`,
|
||||
);
|
||||
|
||||
const publishArgs = [
|
||||
"publish",
|
||||
|
||||
@ -24,9 +24,7 @@
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"resources": [
|
||||
"bin"
|
||||
],
|
||||
"resources": ["bin"],
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
|
||||
@ -8,14 +8,11 @@ export function hydrateWorkspace(password: string): Promise<unknown> {
|
||||
}
|
||||
|
||||
type RuntimeConfigRaw = {
|
||||
dataDirectory?: string;
|
||||
vaultDirectory?: string;
|
||||
DataDirectory?: string;
|
||||
VaultDirectory?: string;
|
||||
};
|
||||
|
||||
type RuntimeConfig = {
|
||||
dataDirectory: string;
|
||||
vaultDirectory: string;
|
||||
};
|
||||
|
||||
@ -34,7 +31,6 @@ async function getRuntimeConfig(
|
||||
);
|
||||
|
||||
return {
|
||||
dataDirectory: pickCase(data, "dataDirectory", "DataDirectory", ""),
|
||||
vaultDirectory: pickCase(data, "vaultDirectory", "VaultDirectory", ""),
|
||||
};
|
||||
}
|
||||
@ -46,7 +42,6 @@ export async function unlockVaultWorkspace(password: string): Promise<void> {
|
||||
payload: {
|
||||
password,
|
||||
vaultDirectory: config.vaultDirectory,
|
||||
dataDirectory: config.dataDirectory,
|
||||
},
|
||||
});
|
||||
|
||||
@ -58,7 +53,6 @@ export async function unlockVaultWorkspace(password: string): Promise<void> {
|
||||
action: "db.hydrate_workspace",
|
||||
payload: {
|
||||
password,
|
||||
dataDirectory: config.dataDirectory,
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -75,7 +69,6 @@ export async function persistAndClearVault(
|
||||
payload: {
|
||||
password,
|
||||
vaultDirectory: config.vaultDirectory,
|
||||
dataDirectory: config.dataDirectory,
|
||||
},
|
||||
},
|
||||
options,
|
||||
@ -84,9 +77,7 @@ export async function persistAndClearVault(
|
||||
await sendCommand<boolean>(
|
||||
{
|
||||
action: "vault.clear_data_directory",
|
||||
payload: {
|
||||
dataDirectory: config.dataDirectory,
|
||||
},
|
||||
payload: {},
|
||||
},
|
||||
options,
|
||||
);
|
||||
|
||||
@ -35,7 +35,6 @@ export type EntrySaveResultDto = {
|
||||
};
|
||||
|
||||
export type EntrySearchRequestDto = {
|
||||
dataDirectory: string;
|
||||
query?: string;
|
||||
section?: string;
|
||||
startDate?: string;
|
||||
@ -214,12 +213,10 @@ function normalizeEntrySearchResult(
|
||||
};
|
||||
}
|
||||
|
||||
export async function listEntries(
|
||||
dataDirectory?: string,
|
||||
): Promise<EntryListItemDto[]> {
|
||||
export async function listEntries(): Promise<EntryListItemDto[]> {
|
||||
const data = await sendCommand<EntryListItemDtoRaw[]>({
|
||||
action: "entries.list",
|
||||
payload: { dataDirectory },
|
||||
payload: {},
|
||||
});
|
||||
|
||||
return data
|
||||
|
||||
@ -46,12 +46,10 @@ function normalizeTemplateItem(
|
||||
};
|
||||
}
|
||||
|
||||
export async function listEntryTemplates(
|
||||
dataDirectory?: string,
|
||||
): Promise<EntryTemplateItemDto[]> {
|
||||
export async function listEntryTemplates(): Promise<EntryTemplateItemDto[]> {
|
||||
const data = await sendCommand<EntryTemplateItemDtoRaw[]>({
|
||||
action: "templates.list",
|
||||
payload: { dataDirectory },
|
||||
payload: {},
|
||||
});
|
||||
|
||||
return data
|
||||
@ -78,7 +76,6 @@ export async function saveEntryTemplate(payload: {
|
||||
name: string;
|
||||
content: string;
|
||||
filePath?: string;
|
||||
dataDirectory?: string;
|
||||
}): Promise<EntryTemplateSaveResultDto> {
|
||||
const data = await sendCommand<EntryTemplateSaveResultDtoRaw>({
|
||||
action: "templates.save",
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
import { listFragments, type FragmentDto } from "$lib/backend/fragments";
|
||||
import { listLists, type ListDocumentDto } from "$lib/backend/lists";
|
||||
import { listTodoLists, type TodoListDto } from "$lib/backend/todos";
|
||||
import { sendCommand } from "$lib/backend/client";
|
||||
import CalendarWidget from "$lib/components/CalendarWidget.svelte";
|
||||
import {
|
||||
entriesBusyStore,
|
||||
@ -31,6 +30,7 @@
|
||||
todoListsStore,
|
||||
todosStore,
|
||||
} from "$lib/stores/todos";
|
||||
import { vaultUnlocked } from "$lib/stores/session";
|
||||
import { extractEntryTags } from "$lib/utils/metadata";
|
||||
|
||||
export let activeSection = "entries";
|
||||
@ -231,16 +231,6 @@
|
||||
return { startDate: toIsoDate(monthStart), endDate: toIsoDate(monthEnd) };
|
||||
}
|
||||
|
||||
async function getDataDirectory(): Promise<string> {
|
||||
const config = await sendCommand<{
|
||||
dataDirectory?: string;
|
||||
DataDirectory?: string;
|
||||
}>({
|
||||
action: "config.get",
|
||||
});
|
||||
return (config.dataDirectory ?? config.DataDirectory ?? "").trim();
|
||||
}
|
||||
|
||||
function toFragmentTimelineItem(fragment: FragmentDto): SidePanelItem {
|
||||
const split = fragment.description.split(/\n{2,}/);
|
||||
const title = (split[0] ?? "").trim() || "Untitled Fragment";
|
||||
@ -348,16 +338,14 @@
|
||||
calendarBusy = true;
|
||||
calendarError = "";
|
||||
try {
|
||||
const dataDirectory = await getDataDirectory();
|
||||
if (requestId !== calendarRefreshRequestId) return;
|
||||
if (!dataDirectory) {
|
||||
if (!$vaultUnlocked) {
|
||||
calendarTimelineItems = [];
|
||||
return;
|
||||
}
|
||||
|
||||
const { startDate, endDate } = getActiveDateRange();
|
||||
const entryItems = await searchEntriesAsItems({
|
||||
dataDirectory,
|
||||
query: calendarQuery.trim() || undefined,
|
||||
});
|
||||
if (requestId !== calendarRefreshRequestId) return;
|
||||
@ -633,6 +621,12 @@
|
||||
|
||||
async function refreshTemplates() {
|
||||
if (activeSection !== "entries") return;
|
||||
if (!$vaultUnlocked) {
|
||||
templatesBusy = false;
|
||||
templateError = "";
|
||||
templateItems = [];
|
||||
return;
|
||||
}
|
||||
templatesBusy = true;
|
||||
templateError = "";
|
||||
try {
|
||||
|
||||
@ -88,10 +88,10 @@ export function createEntryDraft(): EntryItem {
|
||||
};
|
||||
}
|
||||
|
||||
export async function hydrateEntries(dataDirectory?: string): Promise<void> {
|
||||
export async function hydrateEntries(): Promise<void> {
|
||||
entriesBusyStore.set(true);
|
||||
try {
|
||||
const items = await listEntriesCommand(dataDirectory);
|
||||
const items = await listEntriesCommand();
|
||||
const mapped = items.map(fromListDto);
|
||||
entriesStore.set(mapped);
|
||||
} catch (error) {
|
||||
@ -162,18 +162,13 @@ export async function searchEntriesAsItems(
|
||||
payload: EntrySearchRequestDto,
|
||||
): Promise<EntryItem[]> {
|
||||
const results = await searchEntriesCommand(payload);
|
||||
const dataDirectory = payload.dataDirectory?.trim() ?? "";
|
||||
const separator = dataDirectory.includes("\\") ? "\\" : "/";
|
||||
const basePath = dataDirectory.replace(/[\\/]+$/, "");
|
||||
const toSearchPath = (fileName: string): string =>
|
||||
`db://entry/${encodeURIComponent(fileName)}`;
|
||||
const mapped = results.map((result) => ({
|
||||
id: basePath
|
||||
? toStoreId(`${basePath}${separator}${result.fileName}`)
|
||||
: `entries/search/${encodeURIComponent(result.fileName)}`,
|
||||
id: toStoreId(toSearchPath(result.fileName)),
|
||||
label: toLabel(result.fileName),
|
||||
initialContent: result.entry.rawContent,
|
||||
filePath: basePath
|
||||
? `${basePath}${separator}${result.fileName}`
|
||||
: undefined,
|
||||
filePath: toSearchPath(result.fileName),
|
||||
date: result.entry.date,
|
||||
}));
|
||||
return mapped;
|
||||
|
||||
@ -176,7 +176,9 @@
|
||||
|
||||
function pruneDocumentCache(preserveIds: string[] = []) {
|
||||
const preserve = new Set(
|
||||
preserveIds.filter(Boolean).concat(activeDocumentId ? [activeDocumentId] : []),
|
||||
preserveIds
|
||||
.filter(Boolean)
|
||||
.concat(activeDocumentId ? [activeDocumentId] : []),
|
||||
);
|
||||
const cachedIds = Object.keys(openDocuments);
|
||||
if (cachedIds.length <= MAX_CACHED_DOCUMENTS) return;
|
||||
|
||||
@ -25,7 +25,7 @@ public class InMemoryFragmentRepository : IFragmentRepository
|
||||
|
||||
public void Add(Fragment fragment)
|
||||
{
|
||||
if (fragment is null) throw new ArgumentNullException(nameof(fragment));
|
||||
ArgumentNullException.ThrowIfNull(fragment);
|
||||
lock (_lock)
|
||||
{
|
||||
if (fragment.Tags != null)
|
||||
|
||||
@ -266,19 +266,16 @@ public sealed class SqliteFragmentRepository(IDatabaseSessionService session) :
|
||||
|
||||
foreach (var tag in tags)
|
||||
{
|
||||
// Upsert into tags table
|
||||
using var upsert = conn.CreateCommand();
|
||||
upsert.CommandText = "INSERT OR IGNORE INTO tags (name) VALUES (@name);";
|
||||
upsert.Parameters.AddWithValue("@name", tag);
|
||||
upsert.ExecuteNonQuery();
|
||||
|
||||
// Get tag id
|
||||
using var getTagId = conn.CreateCommand();
|
||||
getTagId.CommandText = "SELECT id FROM tags WHERE name = @name;";
|
||||
getTagId.Parameters.AddWithValue("@name", tag);
|
||||
var tagId = (long)getTagId.ExecuteScalar()!;
|
||||
|
||||
// Link fragment to tag
|
||||
using var link = conn.CreateCommand();
|
||||
link.CommandText = "INSERT OR IGNORE INTO fragment_tags (fragment_id, tag_id) VALUES (@fid, @tid);";
|
||||
link.Parameters.AddWithValue("@fid", fragmentRowId);
|
||||
@ -289,7 +286,6 @@ public sealed class SqliteFragmentRepository(IDatabaseSessionService session) :
|
||||
|
||||
private static Fragment MapRow(SqliteDataReader reader)
|
||||
{
|
||||
// columns: id (int), guid (text), type (text), description (text), time (text)
|
||||
var guid = Guid.Parse(reader.GetString(1));
|
||||
var type = reader.GetString(2);
|
||||
var description = reader.IsDBNull(3) ? "" : reader.GetString(3);
|
||||
|
||||
@ -75,8 +75,5 @@ public sealed class DatabaseSessionService(IJournalDatabaseService database) : I
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
CloseConnection();
|
||||
}
|
||||
public void Dispose() => CloseConnection();
|
||||
}
|
||||
|
||||
@ -136,15 +136,15 @@ public sealed class JournalDatabaseService(IJournalConfigService config) : IJour
|
||||
public JournalDatabaseStatus GetStatus(string password)
|
||||
{
|
||||
var tables = GetSchemaStatements().Keys.OrderBy(x => x, StringComparer.Ordinal).ToArray();
|
||||
var runtime = ProbeRuntime(password);
|
||||
var (Ready, Message) = ProbeRuntime(password);
|
||||
return new JournalDatabaseStatus(
|
||||
DatabasePath: GetDatabasePath(),
|
||||
KeyLengthBytes: DeriveDatabaseKey(password).Length,
|
||||
Iterations: Iterations,
|
||||
KeyDerivation: "PBKDF2-HMAC-SHA256",
|
||||
SchemaTables: tables,
|
||||
RuntimeReady: runtime.Ready,
|
||||
RuntimeMessage: runtime.Message);
|
||||
RuntimeReady: Ready,
|
||||
RuntimeMessage: Message);
|
||||
}
|
||||
|
||||
public JournalDatabaseHydrationResult HydrateWorkspace(string password)
|
||||
|
||||
@ -76,6 +76,6 @@ public static partial class HtmlSanitizer
|
||||
];
|
||||
if (markers.Any(marker => lowered.Contains(marker, StringComparison.Ordinal)))
|
||||
return true;
|
||||
return HtmlTagCountRegex().Matches(lowered).Count >= 8;
|
||||
return HtmlTagCountRegex().Count(lowered) >= 8;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,8 +17,7 @@ public sealed class DisabledSpeechBridgeService(string provider = "none", string
|
||||
SpeechTranscribeRequestDto request,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (request is null)
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
var engine = string.IsNullOrWhiteSpace(request.Engine) ? "none" : request.Engine.Trim();
|
||||
var warning = $"{_message} (provider={_provider})";
|
||||
return Task.FromResult(new SpeechTranscribeResultDto("", engine, warning));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user