obsidian-limitless-plugin/actors/lifelogs/query.ts
Graham Barber 985383e6a5
feat: initial version
Working proof-of-concept
2025-03-22 18:09:31 -07:00

110 lines
2.6 KiB
TypeScript

import { fromPromise } from "xstate";
import { request } from "obsidian";
interface QueryInput {
apiKey: string;
start: Date;
end: Date;
cursor: string | null;
}
export interface ContentNode {
/** Type of content node (e.g., heading1, heading2, heading3, blockquote). More types might be added. */
type: string;
/** Content of the node. */
content: string;
/** ISO format in given timezone. */
startTime: string;
/** ISO format in given timezone. */
endTime: string;
/** Milliseconds after the start of this entry. */
startOffsetMs: number;
/** Milliseconds after the start of this entry. */
endOffsetMs: number;
/** Child content nodes. */
children?: ContentNode[];
/** Speaker identifier, present for certain node types (e.g., blockquote). */
speakerName: string | null;
/** Speaker identifier, when applicable. Set to "user" when the speaker has been identified as the user. */
speakerIdentifier: string | null;
}
export interface Lifelog {
/** Unique identifier for this entry. */
id: string;
/** Title of the entry. Equal to the first heading1 node. */
title: string;
/** Raw markdown content of the entry. */
markdown: string;
/** List of ContentNodes. */
contents: ContentNode[];
/** ISO format in given timezone. */
startTime: string;
/** ISO format in given timezone. */
endTime: string;
}
export interface LifelogsResponse {
data: {
lifelogs: Lifelog[];
};
meta: {
lifelogs: {
/** Cursor for pagination to retireve the next set of lifelogs. */
nextCursor?: string | null;
/** Number of lifelogs in the current response. */
count: number;
};
};
}
export const queryLifelogs = fromPromise(
async ({ input }: { input: QueryInput }) => {
// return await input.client.get<LifelogsResponse>("lifelogs", {
// searchParams: {
// start: format(input.start),
// end: format(input.end),
// ...(input.cursor ? { cursor: input.cursor } : {}),
// },
// }).json();
const url = new URL("https://api.limitless.ai/v1/lifelogs");
url.searchParams.set("start", input.start.toISOString());
url.searchParams.set("end", input.end.toISOString());
url.searchParams.set("includeMarkdown", "false");
if (input.cursor) {
url.searchParams.set("cursor", input.cursor);
}
try {
const res = await request({
url: url.toString(),
headers: {
"X-API-Key": input.apiKey,
},
});
console.log(res);
return JSON.parse(res) as LifelogsResponse;
} catch (err) {
console.error(err);
throw err;
}
},
);