learning_ai_notes/mobile/src/lib/offline-queue.ts
2026-03-31 00:17:41 -07:00

71 lines
1.8 KiB
TypeScript

import { createOfflineQueue } from '@bytelyst/offline-queue';
import { PRODUCT_ID } from '../api/config';
import { getApiClient } from '../api/client';
import { mmkvStorage } from '../store/mmkv-storage';
export const OFFLINE_QUEUE_MAX_RETRIES = 5;
export const OFFLINE_QUEUE_MAX_SIZE = 50;
export const noteOfflineQueue = createOfflineQueue({
storageKey: `${PRODUCT_ID}-offline-queue`,
storage: {
getItem: (key: string) => mmkvStorage.getItem(key),
setItem: (key: string, value: string) => mmkvStorage.setItem(key, value),
},
maxRetries: OFFLINE_QUEUE_MAX_RETRIES,
maxQueueSize: OFFLINE_QUEUE_MAX_SIZE,
});
export function getNoteQueueSize(): number {
return noteOfflineQueue.length();
}
export function enqueueNoteCreate(input: {
id: string;
workspaceId: string;
title: string;
body: string;
tags?: string[];
links?: string[];
}): void {
noteOfflineQueue.enqueue({
id: input.id,
action: 'create',
path: '/notes',
payload: {
id: input.id,
workspaceId: input.workspaceId,
title: input.title,
body: input.body,
tags: input.tags ?? [],
links: input.links ?? [],
},
});
}
export function enqueueNoteUpdate(input: {
id: string;
workspaceId: string;
title: string;
body: string;
}): void {
noteOfflineQueue.enqueue({
id: input.id,
action: 'update',
path: `/notes/${input.id}?workspaceId=${encodeURIComponent(input.workspaceId)}`,
payload: {
title: input.title,
body: input.body,
},
});
}
export async function flushNoteQueue(): Promise<{ flushed: number; failed: number }> {
return noteOfflineQueue.flush(async (action, path, payload) => {
await getApiClient().fetch(path, {
method: action === 'create' ? 'POST' : 'PATCH',
body: JSON.stringify(payload),
});
});
}