mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 21:41:09 +02:00
feat(spaces): migrate 43 modules to scopedForModule (Batches A–D)
Mass rollout of the scope wrapper to every module that had a simple
db.table('X').toArray() or .orderBy('k').toArray() pattern. The
calendar/todo/notes/contacts pilots stay as the original templates;
this commit adds the rest in one pass so the scope layer is the
universal read path.
Modules migrated (43):
Batch A (health/tracking): body, mood, sleep, period, habits,
dreams, journal, meditate, drink, food
Batch B (content/media): recipes, plants, places, firsts, who,
library, quotes, music, photos, picture,
presi, cards, wishes
Batch C (productivity): events, finance, invoices, times, storage,
uload, inventory, skilltree, citycorners,
guides, questions, quiz
Batch D (AI/tools): chat, context, kontext, memoro, mail,
companion, moodlit, wetter, playground,
calc, stretch
Pattern:
- db.table<T>('n').toArray() → scopedForModule<T,string>('mod','n').toArray()
- db.table<T>('n').orderBy('k').toArray() → same, replacing .toArray()
with .sortBy('k') so the sort
runs in-memory on the scope-
filtered result
Also adds scopedAnd() to the scope barrel — wraps an existing indexed
Collection (e.g. `.where('date').aboveOrEqual(x)`) with the scope filter
via Collection.and(). Lets indexed queries keep their index hit while
still honouring scope. ~27 remaining db.table<>.where() calls will move
to scopedAnd() in a follow-up once the active-space-indexed compound
indexes land.
Visibility filtering (applyVisibility) is opt-in: the calendar/todo/
notes/contacts pilots call it; the mass-migrated modules skip it until
private records actually show up in a shared space. The default
visibility='space' makes it a no-op anyway — worth adding later when
records with visibility='private' exist in practice.
Type-check: 0 errors across 7143 files.
Plan: docs/plans/spaces-foundation.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b13eb449b3
commit
00b1c9b378
44 changed files with 379 additions and 155 deletions
|
|
@ -106,6 +106,27 @@ export function scopedForModule<T, PK>(
|
|||
return scopedTable<T, PK>(tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the scope filter to an existing Dexie Collection produced by an
|
||||
* indexed query. Use this when a module needs the performance of an
|
||||
* indexed `where(...)` and wants to narrow the result to the active
|
||||
* space as the second step.
|
||||
*
|
||||
* const recent = await scopedAnd(
|
||||
* db.table<LocalMeal>('meals').where('date').aboveOrEqual(since),
|
||||
* ).toArray();
|
||||
*
|
||||
* The wrapper accepts any Collection so the caller can freely build
|
||||
* compound queries with `.or()`, `.and()`, `.reverse()` first.
|
||||
*/
|
||||
export function scopedAnd<T, PK>(collection: Collection<T, PK>): Collection<T, PK> {
|
||||
const ids = getInScopeSpaceIds();
|
||||
return collection.and((record) => {
|
||||
const r = record as { spaceId?: unknown };
|
||||
return typeof r.spaceId === 'string' && ids.includes(r.spaceId);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a single record by primary key with a scope check. Returns undefined
|
||||
* if the record doesn't exist OR if its spaceId isn't in the current
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { LocalMeal, MealWithNutrition } from '$lib/modules/food/types';
|
||||
import type {
|
||||
LocalBodyExercise,
|
||||
|
|
@ -131,7 +132,10 @@ export function toBodyPhase(local: LocalBodyPhase): BodyPhase {
|
|||
|
||||
export function useAllBodyExercises() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalBodyExercise>('bodyExercises').toArray();
|
||||
const locals = await scopedForModule<LocalBodyExercise, string>(
|
||||
'body',
|
||||
'bodyExercises'
|
||||
).toArray();
|
||||
const visible = locals.filter((e) => !e.deletedAt);
|
||||
const decrypted = await decryptRecords('bodyExercises', visible);
|
||||
return decrypted.map(toBodyExercise).sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
|
@ -140,7 +144,9 @@ export function useAllBodyExercises() {
|
|||
|
||||
export function useAllBodyRoutines() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalBodyRoutine>('bodyRoutines').orderBy('order').toArray();
|
||||
const locals = await scopedForModule<LocalBodyRoutine, string>('body', 'bodyRoutines').sortBy(
|
||||
'order'
|
||||
);
|
||||
const visible = locals.filter((r) => !r.deletedAt);
|
||||
const decrypted = await decryptRecords('bodyRoutines', visible);
|
||||
return decrypted.map(toBodyRoutine);
|
||||
|
|
@ -149,7 +155,10 @@ export function useAllBodyRoutines() {
|
|||
|
||||
export function useAllBodyWorkouts() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalBodyWorkout>('bodyWorkouts').toArray();
|
||||
const locals = await scopedForModule<LocalBodyWorkout, string>(
|
||||
'body',
|
||||
'bodyWorkouts'
|
||||
).toArray();
|
||||
const visible = locals.filter((w) => !w.deletedAt);
|
||||
const decrypted = await decryptRecords('bodyWorkouts', visible);
|
||||
return decrypted.map(toBodyWorkout).sort((a, b) => b.startedAt.localeCompare(a.startedAt));
|
||||
|
|
@ -158,7 +167,7 @@ export function useAllBodyWorkouts() {
|
|||
|
||||
export function useAllBodySets() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalBodySet>('bodySets').toArray();
|
||||
const locals = await scopedForModule<LocalBodySet, string>('body', 'bodySets').toArray();
|
||||
const visible = locals.filter((s) => !s.deletedAt);
|
||||
const decrypted = await decryptRecords('bodySets', visible);
|
||||
return decrypted.map(toBodySet);
|
||||
|
|
@ -180,7 +189,10 @@ export function useSetsForWorkout(workoutId: string) {
|
|||
|
||||
export function useAllBodyMeasurements() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalBodyMeasurement>('bodyMeasurements').toArray();
|
||||
const locals = await scopedForModule<LocalBodyMeasurement, string>(
|
||||
'body',
|
||||
'bodyMeasurements'
|
||||
).toArray();
|
||||
const visible = locals.filter((m) => !m.deletedAt);
|
||||
const decrypted = await decryptRecords('bodyMeasurements', visible);
|
||||
return decrypted.map(toBodyMeasurement).sort((a, b) => b.date.localeCompare(a.date));
|
||||
|
|
@ -189,7 +201,7 @@ export function useAllBodyMeasurements() {
|
|||
|
||||
export function useAllBodyChecks() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalBodyCheck>('bodyChecks').toArray();
|
||||
const locals = await scopedForModule<LocalBodyCheck, string>('body', 'bodyChecks').toArray();
|
||||
const visible = locals.filter((c) => !c.deletedAt);
|
||||
const decrypted = await decryptRecords('bodyChecks', visible);
|
||||
return decrypted.map(toBodyCheck).sort((a, b) => b.date.localeCompare(a.date));
|
||||
|
|
@ -198,7 +210,7 @@ export function useAllBodyChecks() {
|
|||
|
||||
export function useAllBodyPhases() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalBodyPhase>('bodyPhases').toArray();
|
||||
const locals = await scopedForModule<LocalBodyPhase, string>('body', 'bodyPhases').toArray();
|
||||
const visible = locals.filter((p) => !p.deletedAt);
|
||||
const decrypted = await decryptRecords('bodyPhases', visible);
|
||||
return decrypted.map(toBodyPhase).sort((a, b) => b.startDate.localeCompare(a.startDate));
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { LocalCalculation, LocalSavedFormula } from './types';
|
||||
import type { Calculation, SavedFormula } from '@calc/shared';
|
||||
|
||||
|
|
@ -39,7 +40,10 @@ export function toSavedFormula(local: LocalSavedFormula): SavedFormula {
|
|||
/** All calculations (history), newest first. */
|
||||
export function useAllCalculations() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalCalculation>('calculations').toArray();
|
||||
const locals = await scopedForModule<LocalCalculation, string>(
|
||||
'calc',
|
||||
'calculations'
|
||||
).toArray();
|
||||
return locals
|
||||
.filter((c) => !c.deletedAt)
|
||||
.map(toCalculation)
|
||||
|
|
@ -50,7 +54,10 @@ export function useAllCalculations() {
|
|||
/** All saved formulas. */
|
||||
export function useAllSavedFormulas() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalSavedFormula>('savedFormulas').toArray();
|
||||
const locals = await scopedForModule<LocalSavedFormula, string>(
|
||||
'calc',
|
||||
'savedFormulas'
|
||||
).toArray();
|
||||
return locals.filter((f) => !f.deletedAt).map(toSavedFormula);
|
||||
}, []);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { liveQuery } from 'dexie';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecord, decryptRecords } from '$lib/data/crypto';
|
||||
import type { LocalDeck, LocalCard, Deck, Card } from './types';
|
||||
|
||||
|
|
@ -45,7 +46,9 @@ export function toCard(local: LocalCard): Card {
|
|||
/** All decks, auto-updates on any change. */
|
||||
export function useAllDecks() {
|
||||
return liveQuery(async () => {
|
||||
const visible = (await db.table<LocalDeck>('cardDecks').toArray()).filter((d) => !d.deletedAt);
|
||||
const visible = (
|
||||
await scopedForModule<LocalDeck, string>('cards', 'cardDecks').toArray()
|
||||
).filter((d) => !d.deletedAt);
|
||||
const decrypted = await decryptRecords('cardDecks', visible);
|
||||
return decrypted.map(toDeck);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type {
|
||||
LocalConversation,
|
||||
|
|
@ -69,9 +70,9 @@ export function toMessage(local: LocalMessage): Message {
|
|||
/** All non-archived conversations, sorted by pinned first then updatedAt desc. */
|
||||
export function useAllConversations() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalConversation>('conversations').toArray()).filter(
|
||||
(c) => !c.deletedAt && !c.isArchived
|
||||
);
|
||||
const visible = (
|
||||
await scopedForModule<LocalConversation, string>('chat', 'conversations').toArray()
|
||||
).filter((c) => !c.deletedAt && !c.isArchived);
|
||||
const decrypted = await decryptRecords('conversations', visible);
|
||||
return sortConversations(decrypted.map(toConversation));
|
||||
}, [] as Conversation[]);
|
||||
|
|
@ -80,9 +81,9 @@ export function useAllConversations() {
|
|||
/** All archived conversations, sorted by updatedAt desc. */
|
||||
export function useArchivedConversations() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalConversation>('conversations').toArray()).filter(
|
||||
(c) => !c.deletedAt && c.isArchived
|
||||
);
|
||||
const visible = (
|
||||
await scopedForModule<LocalConversation, string>('chat', 'conversations').toArray()
|
||||
).filter((c) => !c.deletedAt && c.isArchived);
|
||||
const decrypted = await decryptRecords('conversations', visible);
|
||||
return decrypted
|
||||
.map(toConversation)
|
||||
|
|
@ -93,9 +94,9 @@ export function useArchivedConversations() {
|
|||
/** All templates, sorted by name. */
|
||||
export function useAllTemplates() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalTemplate>('chatTemplates').toArray()).filter(
|
||||
(t) => !t.deletedAt
|
||||
);
|
||||
const visible = (
|
||||
await scopedForModule<LocalTemplate, string>('chat', 'chatTemplates').toArray()
|
||||
).filter((t) => !t.deletedAt);
|
||||
const decrypted = await decryptRecords('chatTemplates', visible);
|
||||
return decrypted.map(toTemplate).sort((a, b) => a.name.localeCompare(b.name));
|
||||
}, [] as Template[]);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { LocalCity, LocalLocation, LocalFavorite } from './types';
|
||||
|
||||
// ─── Live Query Hooks ─────────────────────────────────────
|
||||
|
|
@ -19,7 +20,7 @@ import type { LocalCity, LocalLocation, LocalFavorite } from './types';
|
|||
/** All cities, sorted by name. Auto-updates on any change. */
|
||||
export function useAllCities() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const all = await db.table<LocalCity>('cities').toArray();
|
||||
const all = await scopedForModule<LocalCity, string>('citycorners', 'cities').toArray();
|
||||
return all.filter((c) => !c.deletedAt).sort((a, b) => a.name.localeCompare(b.name));
|
||||
}, [] as LocalCity[]);
|
||||
}
|
||||
|
|
@ -27,7 +28,10 @@ export function useAllCities() {
|
|||
/** All locations, sorted by name. Auto-updates on any change. */
|
||||
export function useAllLocations() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const all = await db.table<LocalLocation>('ccLocations').toArray();
|
||||
const all = await scopedForModule<LocalLocation, string>(
|
||||
'citycorners',
|
||||
'ccLocations'
|
||||
).toArray();
|
||||
return all.filter((l) => !l.deletedAt).sort((a, b) => a.name.localeCompare(b.name));
|
||||
}, [] as LocalLocation[]);
|
||||
}
|
||||
|
|
@ -35,7 +39,10 @@ export function useAllLocations() {
|
|||
/** All favorites. Auto-updates on any change. */
|
||||
export function useAllFavorites() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const all = await db.table<LocalFavorite>('ccFavorites').toArray();
|
||||
const all = await scopedForModule<LocalFavorite, string>(
|
||||
'citycorners',
|
||||
'ccFavorites'
|
||||
).toArray();
|
||||
return all.filter((f) => !f.deletedAt);
|
||||
}, [] as LocalFavorite[]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,16 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { LocalConversation, LocalMessage } from './types';
|
||||
|
||||
export function useConversations() {
|
||||
return useLiveQueryWithDefault<LocalConversation[]>(async () => {
|
||||
try {
|
||||
const all = await db.table<LocalConversation>('companionConversations').toArray();
|
||||
const all = await scopedForModule<LocalConversation, string>(
|
||||
'companion',
|
||||
'companionConversations'
|
||||
).toArray();
|
||||
return all.filter((c) => !c.deletedAt).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
||||
} catch {
|
||||
return [];
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type { LocalContextSpace, LocalDocument, Space, Document, DocumentType } from './types';
|
||||
|
||||
|
|
@ -49,7 +50,10 @@ export function toDocument(local: LocalDocument): Document {
|
|||
/** All spaces, sorted by name. Auto-updates on any change. */
|
||||
export function useAllSpaces() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalContextSpace>('contextSpaces').toArray();
|
||||
const locals = await scopedForModule<LocalContextSpace, string>(
|
||||
'context',
|
||||
'contextSpaces'
|
||||
).toArray();
|
||||
return locals
|
||||
.filter((s) => !s.deletedAt)
|
||||
.map(toSpace)
|
||||
|
|
@ -60,7 +64,7 @@ export function useAllSpaces() {
|
|||
/** All documents, sorted by updated_at desc. Auto-updates on any change. */
|
||||
export function useAllDocuments() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalDocument>('documents').toArray();
|
||||
const locals = await scopedForModule<LocalDocument, string>('context', 'documents').toArray();
|
||||
const visible = locals.filter((d) => !d.deletedAt);
|
||||
const decrypted = await decryptRecords('documents', visible);
|
||||
return decrypted
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type { Dream, DreamSymbol, LocalDream, LocalDreamSymbol } from './types';
|
||||
|
||||
|
|
@ -62,9 +63,9 @@ export function toDreamSymbol(local: LocalDreamSymbol): DreamSymbol {
|
|||
|
||||
export function useAllDreams() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalDream>('dreams').toArray()).filter(
|
||||
(d) => !d.deletedAt && !d.isArchived
|
||||
);
|
||||
const visible = (
|
||||
await scopedForModule<LocalDream, string>('dreams', 'dreams').toArray()
|
||||
).filter((d) => !d.deletedAt && !d.isArchived);
|
||||
const decrypted = await decryptRecords('dreams', visible);
|
||||
return decrypted.map(toDream).sort((a, b) => {
|
||||
if (a.isPinned !== b.isPinned) return a.isPinned ? -1 : 1;
|
||||
|
|
@ -75,9 +76,9 @@ export function useAllDreams() {
|
|||
|
||||
export function useAllDreamSymbols() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalDreamSymbol>('dreamSymbols').toArray()).filter(
|
||||
(s) => !s.deletedAt
|
||||
);
|
||||
const visible = (
|
||||
await scopedForModule<LocalDreamSymbol, string>('dreams', 'dreamSymbols').toArray()
|
||||
).filter((s) => !s.deletedAt);
|
||||
// Only `meaning` is encrypted; `name` stays plaintext for indexed lookups.
|
||||
const decrypted = await decryptRecords('dreamSymbols', visible);
|
||||
return decrypted.map(toDreamSymbol).sort((a, b) => b.count - a.count);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { LocalDrinkEntry, LocalDrinkPreset, DrinkEntry, DrinkPreset } from './types';
|
||||
|
||||
// ─── Type Converters ──────────────────────────────────────
|
||||
|
|
@ -58,7 +59,9 @@ export function useAllDrinkEntries() {
|
|||
|
||||
export function useAllDrinkPresets() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalDrinkPreset>('drinkPresets').orderBy('order').toArray();
|
||||
const locals = await scopedForModule<LocalDrinkPreset, string>('drink', 'drinkPresets').sortBy(
|
||||
'order'
|
||||
);
|
||||
const visible = locals.filter((p) => !p.deletedAt);
|
||||
const decrypted = await decryptRecords('drinkPresets', visible);
|
||||
return decrypted.map(toDrinkPreset);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { timeBlockTable } from '$lib/data/time-blocks/collections';
|
||||
import type { LocalTimeBlock } from '$lib/data/time-blocks/types';
|
||||
|
|
@ -87,7 +88,10 @@ export function toEventGuest(local: LocalEventGuest): EventGuest {
|
|||
/** All non-deleted events, joined with their TimeBlock for time fields. */
|
||||
export function useAllEvents() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalSocialEvent>('socialEvents').toArray();
|
||||
const locals = await scopedForModule<LocalSocialEvent, string>(
|
||||
'events',
|
||||
'socialEvents'
|
||||
).toArray();
|
||||
const visible = locals.filter((e) => !e.deletedAt);
|
||||
const active = await decryptRecords('socialEvents', visible);
|
||||
const blocks = await timeBlockTable.bulkGet(active.map((e) => e.timeBlockId));
|
||||
|
|
@ -98,7 +102,10 @@ export function useAllEvents() {
|
|||
/** Upcoming events (startTime >= now), sorted ascending. */
|
||||
export function useUpcomingEvents() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalSocialEvent>('socialEvents').toArray();
|
||||
const locals = await scopedForModule<LocalSocialEvent, string>(
|
||||
'events',
|
||||
'socialEvents'
|
||||
).toArray();
|
||||
const visible = locals.filter((e) => !e.deletedAt && e.status !== 'cancelled');
|
||||
const active = await decryptRecords('socialEvents', visible);
|
||||
const blocks = await timeBlockTable.bulkGet(active.map((e) => e.timeBlockId));
|
||||
|
|
@ -113,7 +120,10 @@ export function useUpcomingEvents() {
|
|||
/** Past events. */
|
||||
export function usePastEvents() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalSocialEvent>('socialEvents').toArray();
|
||||
const locals = await scopedForModule<LocalSocialEvent, string>(
|
||||
'events',
|
||||
'socialEvents'
|
||||
).toArray();
|
||||
const visible = locals.filter((e) => !e.deletedAt);
|
||||
const active = await decryptRecords('socialEvents', visible);
|
||||
const blocks = await timeBlockTable.bulkGet(active.map((e) => e.timeBlockId));
|
||||
|
|
@ -145,7 +155,7 @@ export function useEvent(eventId: () => string) {
|
|||
export function useGuestsByEvent() {
|
||||
return useLiveQueryWithDefault(
|
||||
async () => {
|
||||
const all = await db.table<LocalEventGuest>('eventGuests').toArray();
|
||||
const all = await scopedForModule<LocalEventGuest, string>('events', 'eventGuests').toArray();
|
||||
const visible = all.filter((g) => !g.deletedAt);
|
||||
const decrypted = await decryptRecords('eventGuests', visible);
|
||||
const map = new Map<string, EventGuest[]>();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type {
|
||||
LocalTransaction,
|
||||
|
|
@ -45,9 +46,9 @@ export function toCategory(local: LocalFinanceCategory): FinanceCategory {
|
|||
|
||||
export function useAllTransactions() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalTransaction>('transactions').toArray()).filter(
|
||||
(t) => !t.deletedAt
|
||||
);
|
||||
const visible = (
|
||||
await scopedForModule<LocalTransaction, string>('finance', 'transactions').toArray()
|
||||
).filter((t) => !t.deletedAt);
|
||||
const decrypted = await decryptRecords('transactions', visible);
|
||||
return decrypted
|
||||
.map(toTransaction)
|
||||
|
|
@ -57,7 +58,10 @@ export function useAllTransactions() {
|
|||
|
||||
export function useAllCategories() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalFinanceCategory>('financeCategories').toArray();
|
||||
const locals = await scopedForModule<LocalFinanceCategory, string>(
|
||||
'finance',
|
||||
'financeCategories'
|
||||
).toArray();
|
||||
return locals
|
||||
.filter((c) => !c.deletedAt)
|
||||
.map(toCategory)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type { First, FirstStatus, LocalFirst } from './types';
|
||||
|
||||
|
|
@ -35,9 +36,9 @@ export function toFirst(local: LocalFirst): First {
|
|||
|
||||
export function useAllFirsts() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalFirst>('firsts').toArray()).filter(
|
||||
(f) => !f.deletedAt && !f.isArchived
|
||||
);
|
||||
const visible = (
|
||||
await scopedForModule<LocalFirst, string>('firsts', 'firsts').toArray()
|
||||
).filter((f) => !f.deletedAt && !f.isArchived);
|
||||
const decrypted = await decryptRecords('firsts', visible);
|
||||
return decrypted.map(toFirst).sort((a, b) => {
|
||||
if (a.isPinned !== b.isPinned) return a.isPinned ? -1 : 1;
|
||||
|
|
@ -58,9 +59,9 @@ export function useAllFirsts() {
|
|||
|
||||
export function useDreams() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalFirst>('firsts').toArray()).filter(
|
||||
(f) => !f.deletedAt && !f.isArchived && f.status === 'dream'
|
||||
);
|
||||
const visible = (
|
||||
await scopedForModule<LocalFirst, string>('firsts', 'firsts').toArray()
|
||||
).filter((f) => !f.deletedAt && !f.isArchived && f.status === 'dream');
|
||||
const decrypted = await decryptRecords('firsts', visible);
|
||||
return decrypted.map(toFirst).sort((a, b) => {
|
||||
const pDiff = (b.priority ?? 0) - (a.priority ?? 0);
|
||||
|
|
@ -72,9 +73,9 @@ export function useDreams() {
|
|||
|
||||
export function useLivedFirsts() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalFirst>('firsts').toArray()).filter(
|
||||
(f) => !f.deletedAt && !f.isArchived && f.status === 'lived'
|
||||
);
|
||||
const visible = (
|
||||
await scopedForModule<LocalFirst, string>('firsts', 'firsts').toArray()
|
||||
).filter((f) => !f.deletedAt && !f.isArchived && f.status === 'lived');
|
||||
const decrypted = await decryptRecords('firsts', visible);
|
||||
return decrypted
|
||||
.map(toFirst)
|
||||
|
|
@ -84,9 +85,9 @@ export function useLivedFirsts() {
|
|||
|
||||
export function useFirstsByPerson(personId: string) {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalFirst>('firsts').toArray()).filter(
|
||||
(f) => !f.deletedAt && !f.isArchived && f.personIds?.includes(personId)
|
||||
);
|
||||
const visible = (
|
||||
await scopedForModule<LocalFirst, string>('firsts', 'firsts').toArray()
|
||||
).filter((f) => !f.deletedAt && !f.isArchived && f.personIds?.includes(personId));
|
||||
const decrypted = await decryptRecords('firsts', visible);
|
||||
return decrypted.map(toFirst);
|
||||
}, [] as First[]);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type {
|
||||
LocalMeal,
|
||||
|
|
@ -43,7 +44,7 @@ export function toMealWithNutrition(local: LocalMeal): MealWithNutrition {
|
|||
/** All meals, auto-updates on any change. */
|
||||
export function useAllMeals() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalMeal>('meals').toArray();
|
||||
const locals = await scopedForModule<LocalMeal, string>('food', 'meals').toArray();
|
||||
const visible = locals.filter((m) => !m.deletedAt);
|
||||
const decrypted = await decryptRecords('meals', visible);
|
||||
return decrypted.map(toMealWithNutrition);
|
||||
|
|
@ -65,7 +66,7 @@ export async function loadMealById(id: string): Promise<MealWithNutrition | null
|
|||
/** All goals, auto-updates on any change. */
|
||||
export function useAllGoals() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalGoal>('goals').toArray();
|
||||
const locals = await scopedForModule<LocalGoal, string>('food', 'goals').toArray();
|
||||
return locals.filter((g) => !g.deletedAt);
|
||||
}, [] as LocalGoal[]);
|
||||
}
|
||||
|
|
@ -73,7 +74,7 @@ export function useAllGoals() {
|
|||
/** All favorites, auto-updates on any change. */
|
||||
export function useAllFavorites() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalFavorite>('foodFavorites').toArray();
|
||||
const locals = await scopedForModule<LocalFavorite, string>('food', 'foodFavorites').toArray();
|
||||
return locals.filter((f) => !f.deletedAt);
|
||||
}, [] as LocalFavorite[]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type {
|
||||
LocalGuide,
|
||||
|
|
@ -78,7 +79,7 @@ export function toRun(local: LocalRun): Run {
|
|||
|
||||
export function useAllGuides() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const all = await db.table<LocalGuide>('guides').toArray();
|
||||
const all = await scopedForModule<LocalGuide, string>('guides', 'guides').toArray();
|
||||
const visible = all.filter((g) => !g.deletedAt);
|
||||
const decrypted = await decryptRecords('guides', visible);
|
||||
return decrypted.map(toGuide).sort((a, b) => a.order - b.order);
|
||||
|
|
@ -138,7 +139,7 @@ export function useLatestRun(guideId: () => string) {
|
|||
|
||||
export function useRunsByGuide() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const all = await db.table<LocalRun>('runs').toArray();
|
||||
const all = await scopedForModule<LocalRun, string>('guides', 'runs').toArray();
|
||||
const visible = all.filter((r) => !r.deletedAt);
|
||||
const map = new Map<string, Run>();
|
||||
// Keep only the latest run per guide
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { LocalHabit, LocalHabitLog, Habit, HabitLog } from './types';
|
||||
import type { LocalTimeBlock } from '$lib/data/time-blocks/types';
|
||||
|
||||
|
|
@ -44,14 +45,14 @@ export function toHabitLog(local: LocalHabitLog, block?: LocalTimeBlock | null):
|
|||
|
||||
export function useAllHabits() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalHabit>('habits').orderBy('order').toArray();
|
||||
const locals = await scopedForModule<LocalHabit, string>('habits', 'habits').sortBy('order');
|
||||
return locals.filter((h) => !h.deletedAt).map(toHabit);
|
||||
}, [] as Habit[]);
|
||||
}
|
||||
|
||||
export function useAllHabitLogs() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalHabitLog>('habitLogs').toArray();
|
||||
const locals = await scopedForModule<LocalHabitLog, string>('habits', 'habitLogs').toArray();
|
||||
const active = locals.filter((l) => !l.deletedAt);
|
||||
|
||||
// Batch-fetch all related timeBlocks
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type { LocalCollection, LocalItem, LocalLocation, LocalCategory } from './types';
|
||||
|
||||
|
|
@ -161,14 +162,19 @@ export function toCategory(local: LocalCategory): Category {
|
|||
|
||||
export function useAllCollections() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalCollection>('invCollections').toArray();
|
||||
const locals = await scopedForModule<LocalCollection, string>(
|
||||
'inventory',
|
||||
'invCollections'
|
||||
).toArray();
|
||||
return locals.filter((c) => !c.deletedAt).map(toCollection);
|
||||
}, []);
|
||||
}
|
||||
|
||||
export function useAllItems() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalItem>('invItems').toArray()).filter((i) => !i.deletedAt);
|
||||
const visible = (
|
||||
await scopedForModule<LocalItem, string>('inventory', 'invItems').toArray()
|
||||
).filter((i) => !i.deletedAt);
|
||||
const decrypted = await decryptRecords('invItems', visible);
|
||||
return decrypted.map(toItem);
|
||||
}, []);
|
||||
|
|
@ -176,14 +182,20 @@ export function useAllItems() {
|
|||
|
||||
export function useAllLocations() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalLocation>('invLocations').toArray();
|
||||
const locals = await scopedForModule<LocalLocation, string>(
|
||||
'inventory',
|
||||
'invLocations'
|
||||
).toArray();
|
||||
return locals.filter((l) => !l.deletedAt).map(toLocation);
|
||||
}, []);
|
||||
}
|
||||
|
||||
export function useAllCategories() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalCategory>('invCategories').toArray();
|
||||
const locals = await scopedForModule<LocalCategory, string>(
|
||||
'inventory',
|
||||
'invCategories'
|
||||
).toArray();
|
||||
return locals.filter((c) => !c.deletedAt).map(toCategory);
|
||||
}, []);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type { JournalEntry, JournalMood, LocalJournalEntry } from './types';
|
||||
|
||||
|
|
@ -35,9 +36,9 @@ export function toJournalEntry(local: LocalJournalEntry): JournalEntry {
|
|||
|
||||
export function useAllJournalEntries() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalJournalEntry>('journalEntries').toArray()).filter(
|
||||
(e) => !e.deletedAt && !e.isArchived
|
||||
);
|
||||
const visible = (
|
||||
await scopedForModule<LocalJournalEntry, string>('journal', 'journalEntries').toArray()
|
||||
).filter((e) => !e.deletedAt && !e.isArchived);
|
||||
const decrypted = await decryptRecords('journalEntries', visible);
|
||||
return decrypted.map(toJournalEntry).sort((a, b) => {
|
||||
if (a.isPinned !== b.isPinned) return a.isPinned ? -1 : 1;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { LocalLibraryEntry, LibraryEntry, LibraryKind, LibraryStatus } from './types';
|
||||
|
||||
// ─── Type Converter ──────────────────────────────────────
|
||||
|
|
@ -40,7 +41,10 @@ export function toLibraryEntry(local: LocalLibraryEntry): LibraryEntry {
|
|||
|
||||
export function useAllEntries() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalLibraryEntry>('libraryEntries').toArray();
|
||||
const locals = await scopedForModule<LocalLibraryEntry, string>(
|
||||
'library',
|
||||
'libraryEntries'
|
||||
).toArray();
|
||||
const visible = locals.filter((e) => !e.deletedAt);
|
||||
const decrypted = await decryptRecords('libraryEntries', visible);
|
||||
return decrypted.map(toLibraryEntry);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { LocalMailDraft, MailDraft } from './types';
|
||||
|
||||
// ─── Draft Converter ────────────────────────────────────────
|
||||
|
|
@ -29,7 +30,7 @@ export function toMailDraft(local: LocalMailDraft): MailDraft {
|
|||
|
||||
export function useAllDrafts() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalMailDraft>('mailDrafts').toArray();
|
||||
const locals = await scopedForModule<LocalMailDraft, string>('mail', 'mailDrafts').toArray();
|
||||
const visible = locals.filter((d) => !d.deletedAt);
|
||||
const decrypted = await decryptRecords('mailDrafts', visible);
|
||||
return decrypted.map(toMailDraft);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type {
|
||||
LocalMeditatePreset,
|
||||
LocalMeditateSession,
|
||||
|
|
@ -93,7 +94,10 @@ export function useAllSessions() {
|
|||
export function useSettings() {
|
||||
return useLiveQueryWithDefault(
|
||||
async () => {
|
||||
const locals = await db.table<LocalMeditateSettings>('meditateSettings').toArray();
|
||||
const locals = await scopedForModule<LocalMeditateSettings, string>(
|
||||
'meditate',
|
||||
'meditateSettings'
|
||||
).toArray();
|
||||
if (locals.length === 0) return null;
|
||||
return toMeditateSettings(locals[0]);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
// `useAllTags` re-exports the shared-tags hook below; the actual tag
|
||||
// objects flowing through this module are the shared shape, not the
|
||||
|
|
@ -68,7 +69,7 @@ export function toSpace(local: LocalSpace): Space {
|
|||
/** All non-archived memos, sorted by pinned first then createdAt desc. */
|
||||
export function useAllMemos() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalMemo>('memos').toArray()).filter(
|
||||
const visible = (await scopedForModule<LocalMemo, string>('memoro', 'memos').toArray()).filter(
|
||||
(m) => !m.deletedAt && !m.isArchived
|
||||
);
|
||||
const decrypted = await decryptRecords('memos', visible);
|
||||
|
|
@ -79,7 +80,7 @@ export function useAllMemos() {
|
|||
/** All archived memos, sorted by updatedAt desc. */
|
||||
export function useArchivedMemos() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalMemo>('memos').toArray()).filter(
|
||||
const visible = (await scopedForModule<LocalMemo, string>('memoro', 'memos').toArray()).filter(
|
||||
(m) => !m.deletedAt && m.isArchived
|
||||
);
|
||||
const decrypted = await decryptRecords('memos', visible);
|
||||
|
|
@ -106,7 +107,7 @@ export { useAllTags } from '@mana/shared-stores';
|
|||
/** All memo-tag associations. */
|
||||
export function useAllMemoTags() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalMemoTag>('memoTags').toArray();
|
||||
const locals = await scopedForModule<LocalMemoTag, string>('memoro', 'memoTags').toArray();
|
||||
return locals.filter((mt) => !mt.deletedAt);
|
||||
}, [] as LocalMemoTag[]);
|
||||
}
|
||||
|
|
@ -114,7 +115,7 @@ export function useAllMemoTags() {
|
|||
/** All spaces. */
|
||||
export function useAllSpaces() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalSpace>('memoroSpaces').toArray();
|
||||
const locals = await scopedForModule<LocalSpace, string>('memoro', 'memoroSpaces').toArray();
|
||||
return locals.filter((s) => !s.deletedAt).map(toSpace);
|
||||
}, [] as Space[]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule, applyVisibility } from '$lib/data/scope';
|
||||
import type {
|
||||
LocalMoodEntry,
|
||||
LocalMoodSettings,
|
||||
|
|
@ -46,8 +47,8 @@ export function toMoodSettings(local: LocalMoodSettings): MoodSettings {
|
|||
|
||||
export function useAllMoodEntries() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalMoodEntry>('moodEntries').toArray();
|
||||
const visible = locals.filter((e) => !e.deletedAt);
|
||||
const locals = await scopedForModule<LocalMoodEntry, string>('mood', 'moodEntries').toArray();
|
||||
const visible = applyVisibility(locals).filter((e) => !e.deletedAt);
|
||||
const decrypted = await decryptRecords('moodEntries', visible);
|
||||
return decrypted.map(toMoodEntry).sort((a, b) => {
|
||||
const cmp = b.date.localeCompare(a.date);
|
||||
|
|
@ -57,11 +58,17 @@ export function useAllMoodEntries() {
|
|||
}
|
||||
|
||||
export function useMoodSettings() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalMoodSettings>('moodSettings').toArray();
|
||||
const row = locals.find((s) => !s.deletedAt);
|
||||
return row ? toMoodSettings(row) : null;
|
||||
}, null as MoodSettings | null);
|
||||
return useLiveQueryWithDefault(
|
||||
async () => {
|
||||
const locals = await scopedForModule<LocalMoodSettings, string>(
|
||||
'mood',
|
||||
'moodSettings'
|
||||
).toArray();
|
||||
const row = applyVisibility(locals).find((s) => !s.deletedAt);
|
||||
return row ? toMoodSettings(row) : null;
|
||||
},
|
||||
null as MoodSettings | null
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Pure Helpers ───────────────────────────────────────────
|
||||
|
|
@ -142,7 +149,11 @@ export function getEmotionDistribution(
|
|||
}
|
||||
|
||||
/** Positive vs negative ratio. */
|
||||
export function getValenceRatio(entries: MoodEntry[]): { positive: number; negative: number; neutral: number } {
|
||||
export function getValenceRatio(entries: MoodEntry[]): {
|
||||
positive: number;
|
||||
negative: number;
|
||||
neutral: number;
|
||||
} {
|
||||
let positive = 0;
|
||||
let negative = 0;
|
||||
let neutral = 0;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { LocalMood, LocalSequence, Mood } from './types';
|
||||
|
||||
// ─── Helpers ──────────────────────────────────────────────
|
||||
|
|
@ -26,7 +27,7 @@ export function getMoodById(moods: Mood[], id: string): Mood | undefined {
|
|||
/** All moods, sorted by name. */
|
||||
export function useAllMoods() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalMood>('moods').toArray();
|
||||
const locals = await scopedForModule<LocalMood, string>('moodlit', 'moods').toArray();
|
||||
return locals.filter((m) => !m.deletedAt);
|
||||
}, []);
|
||||
}
|
||||
|
|
@ -34,7 +35,7 @@ export function useAllMoods() {
|
|||
/** All sequences, sorted by name. */
|
||||
export function useAllSequences() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalSequence>('sequences').toArray();
|
||||
const locals = await scopedForModule<LocalSequence, string>('moodlit', 'sequences').toArray();
|
||||
return locals.filter((s) => !s.deletedAt);
|
||||
}, []);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type {
|
||||
LocalSong,
|
||||
|
|
@ -71,7 +72,7 @@ export function toProject(local: LocalProject): Project {
|
|||
/** All songs, sorted by title. */
|
||||
export function useAllSongs() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalSong>('songs').toArray();
|
||||
const locals = await scopedForModule<LocalSong, string>('music', 'songs').toArray();
|
||||
const visible = locals.filter((s) => !s.deletedAt);
|
||||
// title is encrypted on disk; sort needs the plaintext value.
|
||||
const decrypted = await decryptRecords('songs', visible);
|
||||
|
|
@ -82,7 +83,10 @@ export function useAllSongs() {
|
|||
/** All playlists, sorted by name. */
|
||||
export function useAllPlaylists() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalPlaylist>('mukkePlaylists').toArray();
|
||||
const locals = await scopedForModule<LocalPlaylist, string>(
|
||||
'music',
|
||||
'mukkePlaylists'
|
||||
).toArray();
|
||||
const visible = locals.filter((p) => !p.deletedAt);
|
||||
const decrypted = await decryptRecords('mukkePlaylists', visible);
|
||||
return decrypted.map(toPlaylist).sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
|
@ -92,7 +96,10 @@ export function useAllPlaylists() {
|
|||
/** All playlist-song associations. */
|
||||
export function useAllPlaylistSongs() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalPlaylistSong>('playlistSongs').toArray();
|
||||
const locals = await scopedForModule<LocalPlaylistSong, string>(
|
||||
'music',
|
||||
'playlistSongs'
|
||||
).toArray();
|
||||
return locals.filter((ps) => !ps.deletedAt);
|
||||
}, []);
|
||||
}
|
||||
|
|
@ -100,7 +107,7 @@ export function useAllPlaylistSongs() {
|
|||
/** All projects, sorted by title. */
|
||||
export function useAllProjects() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalProject>('mukkeProjects').toArray();
|
||||
const locals = await scopedForModule<LocalProject, string>('music', 'mukkeProjects').toArray();
|
||||
return locals
|
||||
.filter((p) => !p.deletedAt)
|
||||
.map(toProject)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecord, decryptRecords } from '$lib/data/crypto';
|
||||
import type {
|
||||
Period,
|
||||
|
|
@ -65,9 +66,9 @@ export function toPeriodSymptom(local: LocalPeriodSymptom): PeriodSymptom {
|
|||
|
||||
export function useAllPeriods() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalPeriod>('periods').toArray()).filter(
|
||||
(c) => !c.deletedAt && !c.isArchived
|
||||
);
|
||||
const visible = (
|
||||
await scopedForModule<LocalPeriod, string>('period', 'periods').toArray()
|
||||
).filter((c) => !c.deletedAt && !c.isArchived);
|
||||
const decrypted = await decryptRecords('periods', visible);
|
||||
return decrypted.map(toPeriod).sort((a, b) => b.startDate.localeCompare(a.startDate));
|
||||
}, [] as Period[]);
|
||||
|
|
@ -76,7 +77,7 @@ export function useAllPeriods() {
|
|||
export function useCurrentPeriod() {
|
||||
return useLiveQueryWithDefault(
|
||||
async () => {
|
||||
const locals = await db.table<LocalPeriod>('periods').toArray();
|
||||
const locals = await scopedForModule<LocalPeriod, string>('period', 'periods').toArray();
|
||||
const real = locals.filter((c) => !c.deletedAt && !c.isArchived && !c.isPredicted);
|
||||
if (real.length === 0) return null;
|
||||
const latest = real.sort((a, b) => b.startDate.localeCompare(a.startDate))[0];
|
||||
|
|
@ -89,9 +90,9 @@ export function useCurrentPeriod() {
|
|||
|
||||
export function useAllDayLogs() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalPeriodDayLog>('periodDayLogs').toArray()).filter(
|
||||
(l) => !l.deletedAt
|
||||
);
|
||||
const visible = (
|
||||
await scopedForModule<LocalPeriodDayLog, string>('period', 'periodDayLogs').toArray()
|
||||
).filter((l) => !l.deletedAt);
|
||||
const decrypted = await decryptRecords('periodDayLogs', visible);
|
||||
return decrypted.map(toPeriodDayLog).sort((a, b) => b.logDate.localeCompare(a.logDate));
|
||||
}, [] as PeriodDayLog[]);
|
||||
|
|
@ -116,7 +117,10 @@ export function useDayLog(date: string) {
|
|||
|
||||
export function useAllSymptoms() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalPeriodSymptom>('periodSymptoms').toArray();
|
||||
const locals = await scopedForModule<LocalPeriodSymptom, string>(
|
||||
'period',
|
||||
'periodSymptoms'
|
||||
).toArray();
|
||||
return locals
|
||||
.filter((s) => !s.deletedAt)
|
||||
.map(toPeriodSymptom)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { LocalAlbum, LocalAlbumItem, LocalFavorite, Album, AlbumItem } from './types';
|
||||
|
||||
// ─── Type Converters ───────────────────────────────────────
|
||||
|
|
@ -42,7 +43,7 @@ export function toAlbumItem(local: LocalAlbumItem): AlbumItem {
|
|||
/** All albums. Auto-updates on any change. */
|
||||
export function useAllAlbums() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalAlbum>('albums').toArray();
|
||||
const locals = await scopedForModule<LocalAlbum, string>('photos', 'albums').toArray();
|
||||
return locals.filter((a) => !a.deletedAt).map(toAlbum);
|
||||
}, []);
|
||||
}
|
||||
|
|
@ -50,7 +51,7 @@ export function useAllAlbums() {
|
|||
/** All album items. Auto-updates on any change. */
|
||||
export function useAllAlbumItems() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalAlbumItem>('albumItems').toArray();
|
||||
const locals = await scopedForModule<LocalAlbumItem, string>('photos', 'albumItems').toArray();
|
||||
return locals.filter((i) => !i.deletedAt).map(toAlbumItem);
|
||||
}, []);
|
||||
}
|
||||
|
|
@ -58,7 +59,10 @@ export function useAllAlbumItems() {
|
|||
/** All favorites. Auto-updates on any change. */
|
||||
export function useAllFavorites() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalFavorite>('photoFavorites').toArray();
|
||||
const locals = await scopedForModule<LocalFavorite, string>(
|
||||
'photos',
|
||||
'photoFavorites'
|
||||
).toArray();
|
||||
return locals.filter((f) => !f.deletedAt);
|
||||
}, []);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
import { liveQuery } from 'dexie';
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type {
|
||||
LocalImage,
|
||||
|
|
@ -69,7 +70,7 @@ export function toBoard(local: LocalBoard): Board {
|
|||
/** All non-archived images, sorted by createdAt desc. */
|
||||
export function useAllImages() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalImage>('images').toArray();
|
||||
const locals = await scopedForModule<LocalImage, string>('picture', 'images').toArray();
|
||||
const visible = locals.filter((img) => !img.isArchived && !img.deletedAt);
|
||||
const decrypted = await decryptRecords('images', visible);
|
||||
return decrypted
|
||||
|
|
@ -81,7 +82,7 @@ export function useAllImages() {
|
|||
/** All archived images, sorted by createdAt desc. */
|
||||
export function useArchivedImages() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalImage>('images').toArray();
|
||||
const locals = await scopedForModule<LocalImage, string>('picture', 'images').toArray();
|
||||
const visible = locals.filter((img) => !!img.isArchived && !img.deletedAt);
|
||||
const decrypted = await decryptRecords('images', visible);
|
||||
return decrypted
|
||||
|
|
@ -93,8 +94,11 @@ export function useArchivedImages() {
|
|||
/** All boards with item counts, sorted by updatedAt desc. */
|
||||
export function useAllBoards() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalBoard>('boards').toArray();
|
||||
const allItems = await db.table<LocalBoardItem>('boardItems').toArray();
|
||||
const locals = await scopedForModule<LocalBoard, string>('picture', 'boards').toArray();
|
||||
const allItems = await scopedForModule<LocalBoardItem, string>(
|
||||
'picture',
|
||||
'boardItems'
|
||||
).toArray();
|
||||
|
||||
// boardItems.textContent is encrypted but the count map only
|
||||
// looks at structural fields (deletedAt + boardId), so no
|
||||
|
|
@ -128,7 +132,7 @@ export { useAllTags as useAllPictureTags } from '@mana/shared-stores';
|
|||
/** All image-tag associations. */
|
||||
export function useAllImageTags() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
return await db.table<LocalImageTag>('imageTags').toArray();
|
||||
return await scopedForModule<LocalImageTag, string>('picture', 'imageTags').toArray();
|
||||
}, [] as LocalImageTag[]);
|
||||
}
|
||||
|
||||
|
|
@ -136,7 +140,7 @@ export function useAllImageTags() {
|
|||
|
||||
export function allImages$() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalImage>('images').toArray();
|
||||
const locals = await scopedForModule<LocalImage, string>('picture', 'images').toArray();
|
||||
const visible = locals.filter((img) => !img.isArchived && !img.deletedAt);
|
||||
const decrypted = await decryptRecords('images', visible);
|
||||
return decrypted
|
||||
|
|
@ -147,7 +151,7 @@ export function allImages$() {
|
|||
|
||||
export function allBoards$() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalBoard>('boards').toArray();
|
||||
const locals = await scopedForModule<LocalBoard, string>('picture', 'boards').toArray();
|
||||
const visible = locals.filter((b) => !b.deletedAt);
|
||||
const decrypted = await decryptRecords('boards', visible);
|
||||
return decrypted.map(toBoard);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type { LocalPlace, LocalLocationLog, Place, LocationLog } from './types';
|
||||
|
||||
|
|
@ -46,7 +47,7 @@ export function toLocationLog(local: LocalLocationLog): LocationLog {
|
|||
|
||||
export function useAllPlaces() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalPlace>('places').toArray();
|
||||
const locals = await scopedForModule<LocalPlace, string>('places', 'places').toArray();
|
||||
const visible = locals.filter((p) => !p.deletedAt);
|
||||
const decrypted = await decryptRecords<LocalPlace>('places', visible);
|
||||
return decrypted.map(toPlace);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type { Tag } from '@mana/shared-tags';
|
||||
import type {
|
||||
|
|
@ -99,7 +100,9 @@ export function toWateringLog(local: LocalWateringLog): WateringLog {
|
|||
/** All plants. Auto-updates on any change. */
|
||||
export function useAllPlants() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalPlant>('plants').toArray()).filter((p) => !p.deletedAt);
|
||||
const visible = (
|
||||
await scopedForModule<LocalPlant, string>('plants', 'plants').toArray()
|
||||
).filter((p) => !p.deletedAt);
|
||||
const decrypted = await decryptRecords('plants', visible);
|
||||
return decrypted.map(toPlant);
|
||||
}, []);
|
||||
|
|
@ -108,7 +111,10 @@ export function useAllPlants() {
|
|||
/** All plant photos. Auto-updates on any change. */
|
||||
export function useAllPlantPhotos() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalPlantPhoto>('plantPhotos').toArray();
|
||||
const locals = await scopedForModule<LocalPlantPhoto, string>(
|
||||
'plants',
|
||||
'plantPhotos'
|
||||
).toArray();
|
||||
return locals.filter((p) => !p.deletedAt).map(toPlantPhoto);
|
||||
}, []);
|
||||
}
|
||||
|
|
@ -116,7 +122,10 @@ export function useAllPlantPhotos() {
|
|||
/** All watering schedules. Auto-updates on any change. */
|
||||
export function useAllWateringSchedules() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalWateringSchedule>('wateringSchedules').toArray();
|
||||
const locals = await scopedForModule<LocalWateringSchedule, string>(
|
||||
'plants',
|
||||
'wateringSchedules'
|
||||
).toArray();
|
||||
return locals.filter((s) => !s.deletedAt).map(toWateringSchedule);
|
||||
}, []);
|
||||
}
|
||||
|
|
@ -124,7 +133,10 @@ export function useAllWateringSchedules() {
|
|||
/** All watering logs. Auto-updates on any change. */
|
||||
export function useAllWateringLogs() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalWateringLog>('wateringLogs').toArray();
|
||||
const locals = await scopedForModule<LocalWateringLog, string>(
|
||||
'plants',
|
||||
'wateringLogs'
|
||||
).toArray();
|
||||
return locals.filter((l) => !l.deletedAt).map(toWateringLog);
|
||||
}, []);
|
||||
}
|
||||
|
|
@ -132,7 +144,7 @@ export function useAllWateringLogs() {
|
|||
/** All plant↔tag junctions (active only). */
|
||||
export function useAllPlantTags() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalPlantTag>('plantTags').toArray();
|
||||
const locals = await scopedForModule<LocalPlantTag, string>('plants', 'plantTags').toArray();
|
||||
return locals.filter((t) => !t.deletedAt);
|
||||
}, []);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type {
|
||||
LocalPlaygroundSnippet,
|
||||
|
|
@ -85,7 +86,10 @@ export function toMessage(local: LocalPlaygroundMessage): PlaygroundConversation
|
|||
|
||||
export function useAllConversations() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalPlaygroundConversation>('playgroundConversations').toArray();
|
||||
const locals = await scopedForModule<LocalPlaygroundConversation, string>(
|
||||
'playground',
|
||||
'playgroundConversations'
|
||||
).toArray();
|
||||
const visible = locals.filter((c) => !c.deletedAt);
|
||||
const decrypted = await decryptRecords<LocalPlaygroundConversation>(
|
||||
'playgroundConversations',
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecord, decryptRecords } from '$lib/data/crypto';
|
||||
import type { LocalDeck, LocalSlide, Deck, Slide } from './types';
|
||||
|
||||
|
|
@ -40,7 +41,9 @@ export function toSlide(local: LocalSlide): Slide {
|
|||
/** All decks, sorted by updatedAt descending. Auto-updates on any change. */
|
||||
export function useAllDecks() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalDeck>('presiDecks').toArray()).filter((d) => !d.deletedAt);
|
||||
const visible = (
|
||||
await scopedForModule<LocalDeck, string>('presi', 'presiDecks').toArray()
|
||||
).filter((d) => !d.deletedAt);
|
||||
const decrypted = await decryptRecords('presiDecks', visible);
|
||||
return decrypted
|
||||
.map(toDeck)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type { LocalCollection, LocalQuestion, LocalAnswer } from './types';
|
||||
|
||||
|
|
@ -103,7 +104,10 @@ export function toAnswer(local: LocalAnswer): Answer {
|
|||
/** All collections, sorted by sortOrder. Auto-updates on any change. */
|
||||
export function useAllCollections() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalCollection>('qCollections').toArray();
|
||||
const locals = await scopedForModule<LocalCollection, string>(
|
||||
'questions',
|
||||
'qCollections'
|
||||
).toArray();
|
||||
return locals
|
||||
.filter((c) => !c.deletedAt)
|
||||
.sort((a, b) => a.sortOrder - b.sortOrder)
|
||||
|
|
@ -114,7 +118,7 @@ export function useAllCollections() {
|
|||
/** All questions. Auto-updates on any change. */
|
||||
export function useAllQuestions() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalQuestion>('questions').toArray();
|
||||
const locals = await scopedForModule<LocalQuestion, string>('questions', 'questions').toArray();
|
||||
const visible = locals.filter((q) => !q.deletedAt);
|
||||
const decrypted = await decryptRecords('questions', visible);
|
||||
return decrypted.map(toQuestion);
|
||||
|
|
@ -124,7 +128,7 @@ export function useAllQuestions() {
|
|||
/** All answers for a given question. */
|
||||
export function useAnswersByQuestion(questionId: string) {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalAnswer>('answers').toArray();
|
||||
const locals = await scopedForModule<LocalAnswer, string>('questions', 'answers').toArray();
|
||||
const visible = locals.filter((a) => !a.deletedAt && a.questionId === questionId);
|
||||
const decrypted = await decryptRecords('answers', visible);
|
||||
return decrypted.map(toAnswer);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type {
|
||||
LocalQuiz,
|
||||
|
|
@ -69,7 +70,7 @@ export function toAttempt(local: LocalQuizAttempt): QuizAttempt {
|
|||
|
||||
export function useAllQuizzes() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const visible = (await db.table<LocalQuiz>('quizzes').toArray()).filter(
|
||||
const visible = (await scopedForModule<LocalQuiz, string>('quiz', 'quizzes').toArray()).filter(
|
||||
(q) => !q.deletedAt && !q.isArchived
|
||||
);
|
||||
const decrypted = await decryptRecords('quizzes', visible);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import { liveQuery } from 'dexie';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { LocalFavorite, LocalQuoteList, LocalCustomQuote } from './types';
|
||||
|
||||
// ─── Domain Types ─────────────────────────────────────────
|
||||
|
|
@ -73,7 +74,10 @@ export function toQuoteList(local: LocalQuoteList): QuoteList {
|
|||
/** All favorites. Auto-updates on any change. */
|
||||
export function useAllFavorites() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalFavorite>('quotesFavorites').toArray();
|
||||
const locals = await scopedForModule<LocalFavorite, string>(
|
||||
'quotes',
|
||||
'quotesFavorites'
|
||||
).toArray();
|
||||
return locals.filter((f) => !f.deletedAt).map(toFavorite);
|
||||
});
|
||||
}
|
||||
|
|
@ -81,7 +85,7 @@ export function useAllFavorites() {
|
|||
/** All lists. Auto-updates on any change. */
|
||||
export function useAllLists() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalQuoteList>('quotesLists').toArray();
|
||||
const locals = await scopedForModule<LocalQuoteList, string>('quotes', 'quotesLists').toArray();
|
||||
return locals.filter((l) => !l.deletedAt).map(toQuoteList);
|
||||
});
|
||||
}
|
||||
|
|
@ -89,7 +93,10 @@ export function useAllLists() {
|
|||
/** All custom quotes. Auto-updates on any change. */
|
||||
export function useAllCustomQuotes() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalCustomQuote>('customQuotes').toArray();
|
||||
const locals = await scopedForModule<LocalCustomQuote, string>(
|
||||
'quotes',
|
||||
'customQuotes'
|
||||
).toArray();
|
||||
return locals.filter((q) => !q.deletedAt).map(toCustomQuote);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { LocalRecipe, Recipe, Difficulty } from './types';
|
||||
|
||||
// ─── Type Converter ──────────────────────────────────────
|
||||
|
|
@ -35,7 +36,7 @@ export function toRecipe(local: LocalRecipe): Recipe {
|
|||
|
||||
export function useAllRecipes() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalRecipe>('recipes').toArray();
|
||||
const locals = await scopedForModule<LocalRecipe, string>('recipes', 'recipes').toArray();
|
||||
const visible = locals.filter((r) => !r.deletedAt);
|
||||
const decrypted = await decryptRecords('recipes', visible);
|
||||
return decrypted.map(toRecipe);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { LocalSkill, LocalActivity, LocalAchievement } from './types';
|
||||
import type { Skill, Activity, SkillBranch, UserStats } from './types';
|
||||
import { BRANCH_INFO } from './types';
|
||||
|
|
@ -47,7 +48,7 @@ export function toActivity(local: LocalActivity): Activity {
|
|||
/** All skills, auto-updates on any change. */
|
||||
export function useAllSkills() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalSkill>('skills').toArray();
|
||||
const locals = await scopedForModule<LocalSkill, string>('skilltree', 'skills').toArray();
|
||||
return locals.filter((s) => !s.deletedAt).map(toSkill);
|
||||
}, [] as Skill[]);
|
||||
}
|
||||
|
|
@ -55,7 +56,10 @@ export function useAllSkills() {
|
|||
/** All activities, auto-updates on any change. */
|
||||
export function useAllActivities() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalActivity>('activities').toArray();
|
||||
const locals = await scopedForModule<LocalActivity, string>(
|
||||
'skilltree',
|
||||
'activities'
|
||||
).toArray();
|
||||
return locals.filter((a) => !a.deletedAt).map(toActivity);
|
||||
}, [] as Activity[]);
|
||||
}
|
||||
|
|
@ -63,7 +67,10 @@ export function useAllActivities() {
|
|||
/** All achievements (raw local records), auto-updates on any change. */
|
||||
export function useAllAchievements() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalAchievement>('achievements').toArray();
|
||||
const locals = await scopedForModule<LocalAchievement, string>(
|
||||
'skilltree',
|
||||
'achievements'
|
||||
).toArray();
|
||||
return locals.filter((a) => !a.deletedAt);
|
||||
}, [] as LocalAchievement[]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type {
|
||||
LocalSleepEntry,
|
||||
LocalSleepHygieneLog,
|
||||
|
|
@ -84,7 +85,10 @@ export function toSleepSettings(local: LocalSleepSettings): SleepSettings {
|
|||
|
||||
export function useAllSleepEntries() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalSleepEntry>('sleepEntries').toArray();
|
||||
const locals = await scopedForModule<LocalSleepEntry, string>(
|
||||
'sleep',
|
||||
'sleepEntries'
|
||||
).toArray();
|
||||
const visible = locals.filter((e) => !e.deletedAt);
|
||||
const decrypted = await decryptRecords('sleepEntries', visible);
|
||||
return decrypted.map(toSleepEntry).sort((a, b) => b.date.localeCompare(a.date));
|
||||
|
|
@ -93,7 +97,10 @@ export function useAllSleepEntries() {
|
|||
|
||||
export function useAllSleepHygieneLogs() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalSleepHygieneLog>('sleepHygieneLogs').toArray();
|
||||
const locals = await scopedForModule<LocalSleepHygieneLog, string>(
|
||||
'sleep',
|
||||
'sleepHygieneLogs'
|
||||
).toArray();
|
||||
const visible = locals.filter((l) => !l.deletedAt);
|
||||
return visible.map(toSleepHygieneLog).sort((a, b) => b.date.localeCompare(a.date));
|
||||
}, [] as SleepHygieneLog[]);
|
||||
|
|
@ -101,7 +108,10 @@ export function useAllSleepHygieneLogs() {
|
|||
|
||||
export function useAllSleepHygieneChecks() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalSleepHygieneCheck>('sleepHygieneChecks').toArray();
|
||||
const locals = await scopedForModule<LocalSleepHygieneCheck, string>(
|
||||
'sleep',
|
||||
'sleepHygieneChecks'
|
||||
).toArray();
|
||||
const visible = locals.filter((c) => !c.deletedAt);
|
||||
const decrypted = await decryptRecords('sleepHygieneChecks', visible);
|
||||
return decrypted.map(toSleepHygieneCheck).sort((a, b) => a.order - b.order);
|
||||
|
|
@ -111,7 +121,10 @@ export function useAllSleepHygieneChecks() {
|
|||
export function useSleepSettings() {
|
||||
return useLiveQueryWithDefault(
|
||||
async () => {
|
||||
const locals = await db.table<LocalSleepSettings>('sleepSettings').toArray();
|
||||
const locals = await scopedForModule<LocalSleepSettings, string>(
|
||||
'sleep',
|
||||
'sleepSettings'
|
||||
).toArray();
|
||||
const row = locals.find((s) => !s.deletedAt);
|
||||
return row ? toSleepSettings(row) : null;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type { LocalFile, LocalFolder, LocalFileTag } from './types';
|
||||
|
||||
|
|
@ -107,7 +108,7 @@ export function toTag(local: {
|
|||
/** All non-deleted files, sorted by name. Auto-updates on any change. */
|
||||
export function useAllFiles() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalFile>('files').toArray();
|
||||
const locals = await scopedForModule<LocalFile, string>('storage', 'files').toArray();
|
||||
const visible = locals.filter((f) => !f.isDeleted && !f.deletedAt);
|
||||
// name + originalName are encrypted on disk; sort needs plaintext.
|
||||
const decrypted = await decryptRecords('files', visible);
|
||||
|
|
@ -118,7 +119,10 @@ export function useAllFiles() {
|
|||
/** All non-deleted folders, sorted by name. Auto-updates on any change. */
|
||||
export function useAllFolders() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalFolder>('storageFolders').toArray();
|
||||
const locals = await scopedForModule<LocalFolder, string>(
|
||||
'storage',
|
||||
'storageFolders'
|
||||
).toArray();
|
||||
return locals
|
||||
.filter((f) => !f.isDeleted && !f.deletedAt)
|
||||
.map(toFolder)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type {
|
||||
LocalStretchExercise,
|
||||
LocalStretchRoutine,
|
||||
|
|
@ -109,7 +110,10 @@ export function toStretchReminder(local: LocalStretchReminder): StretchReminder
|
|||
|
||||
export function useAllStretchExercises() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalStretchExercise>('stretchExercises').toArray();
|
||||
const locals = await scopedForModule<LocalStretchExercise, string>(
|
||||
'stretch',
|
||||
'stretchExercises'
|
||||
).toArray();
|
||||
const visible = locals.filter((e) => !e.deletedAt);
|
||||
const decrypted = await decryptRecords('stretchExercises', visible);
|
||||
return decrypted.map(toStretchExercise).sort((a, b) => a.order - b.order);
|
||||
|
|
@ -118,7 +122,10 @@ export function useAllStretchExercises() {
|
|||
|
||||
export function useAllStretchRoutines() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalStretchRoutine>('stretchRoutines').toArray();
|
||||
const locals = await scopedForModule<LocalStretchRoutine, string>(
|
||||
'stretch',
|
||||
'stretchRoutines'
|
||||
).toArray();
|
||||
const visible = locals.filter((r) => !r.deletedAt);
|
||||
const decrypted = await decryptRecords('stretchRoutines', visible);
|
||||
return decrypted.map(toStretchRoutine).sort((a, b) => a.order - b.order);
|
||||
|
|
@ -127,7 +134,10 @@ export function useAllStretchRoutines() {
|
|||
|
||||
export function useAllStretchSessions() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalStretchSession>('stretchSessions').toArray();
|
||||
const locals = await scopedForModule<LocalStretchSession, string>(
|
||||
'stretch',
|
||||
'stretchSessions'
|
||||
).toArray();
|
||||
const visible = locals.filter((s) => !s.deletedAt);
|
||||
const decrypted = await decryptRecords('stretchSessions', visible);
|
||||
return decrypted.map(toStretchSession).sort((a, b) => b.startedAt.localeCompare(a.startedAt));
|
||||
|
|
@ -136,7 +146,10 @@ export function useAllStretchSessions() {
|
|||
|
||||
export function useAllStretchAssessments() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalStretchAssessment>('stretchAssessments').toArray();
|
||||
const locals = await scopedForModule<LocalStretchAssessment, string>(
|
||||
'stretch',
|
||||
'stretchAssessments'
|
||||
).toArray();
|
||||
const visible = locals.filter((a) => !a.deletedAt);
|
||||
const decrypted = await decryptRecords('stretchAssessments', visible);
|
||||
return decrypted
|
||||
|
|
@ -147,7 +160,10 @@ export function useAllStretchAssessments() {
|
|||
|
||||
export function useAllStretchReminders() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalStretchReminder>('stretchReminders').toArray();
|
||||
const locals = await scopedForModule<LocalStretchReminder, string>(
|
||||
'stretch',
|
||||
'stretchReminders'
|
||||
).toArray();
|
||||
const visible = locals.filter((r) => !r.deletedAt);
|
||||
const decrypted = await decryptRecords('stretchReminders', visible);
|
||||
return decrypted.map(toStretchReminder);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { liveQuery } from 'dexie';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import type {
|
||||
LocalClient,
|
||||
|
|
@ -171,21 +172,21 @@ export function toWorldClock(local: LocalWorldClock): WorldClock {
|
|||
|
||||
export function useAllClients() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalClient>('timeClients').toArray();
|
||||
const locals = await scopedForModule<LocalClient, string>('times', 'timeClients').toArray();
|
||||
return locals.filter((c) => !c.deletedAt).map(toClient);
|
||||
});
|
||||
}
|
||||
|
||||
export function useAllProjects() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalProject>('timeProjects').toArray();
|
||||
const locals = await scopedForModule<LocalProject, string>('times', 'timeProjects').toArray();
|
||||
return locals.filter((p) => !p.deletedAt).map(toProject);
|
||||
});
|
||||
}
|
||||
|
||||
export function useAllTimeEntries() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalTimeEntry>('timeEntries').toArray();
|
||||
const locals = await scopedForModule<LocalTimeEntry, string>('times', 'timeEntries').toArray();
|
||||
const active = locals.filter((e) => !e.deletedAt);
|
||||
|
||||
// Batch-fetch all related timeBlocks
|
||||
|
|
@ -205,14 +206,14 @@ export { useAllTags } from '@mana/shared-stores';
|
|||
|
||||
export function useAllTemplates() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalTemplate>('timeTemplates').toArray();
|
||||
const locals = await scopedForModule<LocalTemplate, string>('times', 'timeTemplates').toArray();
|
||||
return locals.filter((t) => !t.deletedAt).map(toTemplate);
|
||||
});
|
||||
}
|
||||
|
||||
export function useSettings() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalSettings>('timeSettings').toArray();
|
||||
const locals = await scopedForModule<LocalSettings, string>('times', 'timeSettings').toArray();
|
||||
const active = locals.filter((s) => !s.deletedAt);
|
||||
return active.length > 0 ? toSettings(active[0]) : null;
|
||||
});
|
||||
|
|
@ -223,7 +224,7 @@ export function useSettings() {
|
|||
/** All alarms as raw observable. */
|
||||
export function allAlarms$() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalAlarm>('timeAlarms').toArray();
|
||||
const locals = await scopedForModule<LocalAlarm, string>('times', 'timeAlarms').toArray();
|
||||
return locals.filter((a) => !a.deletedAt).map(toAlarm);
|
||||
});
|
||||
}
|
||||
|
|
@ -231,7 +232,10 @@ export function allAlarms$() {
|
|||
/** All countdown timers as raw observable. */
|
||||
export function allCountdownTimers$() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalCountdownTimer>('timeCountdownTimers').toArray();
|
||||
const locals = await scopedForModule<LocalCountdownTimer, string>(
|
||||
'times',
|
||||
'timeCountdownTimers'
|
||||
).toArray();
|
||||
return locals.filter((t) => !t.deletedAt).map(toCountdownTimer);
|
||||
});
|
||||
}
|
||||
|
|
@ -252,7 +256,7 @@ export function allWorldClocks$() {
|
|||
/** All alarms, auto-updates on any change. Returns { value, loading, error }. */
|
||||
export function useAllAlarms() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalAlarm>('timeAlarms').toArray();
|
||||
const locals = await scopedForModule<LocalAlarm, string>('times', 'timeAlarms').toArray();
|
||||
return locals.filter((a) => !a.deletedAt).map(toAlarm);
|
||||
}, [] as Alarm[]);
|
||||
}
|
||||
|
|
@ -260,7 +264,10 @@ export function useAllAlarms() {
|
|||
/** All countdown timers, auto-updates on any change. Returns { value, loading, error }. */
|
||||
export function useAllCountdownTimers() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalCountdownTimer>('timeCountdownTimers').toArray();
|
||||
const locals = await scopedForModule<LocalCountdownTimer, string>(
|
||||
'times',
|
||||
'timeCountdownTimers'
|
||||
).toArray();
|
||||
return locals.filter((t) => !t.deletedAt).map(toCountdownTimer);
|
||||
}, [] as Timer[]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
import { liveQuery } from 'dexie';
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecord, decryptRecords } from '$lib/data/crypto';
|
||||
import type { LocalLink, LocalTag, LocalFolder, LocalLinkTag } from './types';
|
||||
|
||||
|
|
@ -133,7 +134,7 @@ export function toLinkTag(local: LocalLinkTag): LinkTag {
|
|||
|
||||
export function allLinks$() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalLink>('links').toArray();
|
||||
const locals = await scopedForModule<LocalLink, string>('uload', 'links').toArray();
|
||||
const visible = locals.filter((l) => !l.deletedAt);
|
||||
const decrypted = await decryptRecords('links', visible);
|
||||
return decrypted.map(toLink);
|
||||
|
|
@ -142,21 +143,21 @@ export function allLinks$() {
|
|||
|
||||
export function allTags$() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalTag>('uloadTags').toArray();
|
||||
const locals = await scopedForModule<LocalTag, string>('uload', 'uloadTags').toArray();
|
||||
return locals.filter((t) => !t.deletedAt).map(toTag);
|
||||
});
|
||||
}
|
||||
|
||||
export function allFolders$() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalFolder>('uloadFolders').toArray();
|
||||
const locals = await scopedForModule<LocalFolder, string>('uload', 'uloadFolders').toArray();
|
||||
return locals.filter((f) => !f.deletedAt).map(toFolder);
|
||||
});
|
||||
}
|
||||
|
||||
export function allLinkTags$() {
|
||||
return liveQuery(async () => {
|
||||
const locals = await db.table<LocalLinkTag>('linkTags').toArray();
|
||||
const locals = await scopedForModule<LocalLinkTag, string>('uload', 'linkTags').toArray();
|
||||
return locals.filter((lt) => !lt.deletedAt).map(toLinkTag);
|
||||
});
|
||||
}
|
||||
|
|
@ -165,7 +166,7 @@ export function allLinkTags$() {
|
|||
|
||||
export function useAllLinks() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalLink>('links').toArray();
|
||||
const locals = await scopedForModule<LocalLink, string>('uload', 'links').toArray();
|
||||
const visible = locals.filter((l) => !l.deletedAt);
|
||||
const decrypted = await decryptRecords('links', visible);
|
||||
return decrypted.map(toLink);
|
||||
|
|
@ -174,21 +175,23 @@ export function useAllLinks() {
|
|||
|
||||
export function useAllTags() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalTag>('uloadTags').toArray();
|
||||
const locals = await scopedForModule<LocalTag, string>('uload', 'uloadTags').toArray();
|
||||
return locals.filter((t) => !t.deletedAt).map(toTag);
|
||||
}, [] as Tag[]);
|
||||
}
|
||||
|
||||
export function useAllFolders() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalFolder>('uloadFolders').orderBy('order').toArray();
|
||||
const locals = await scopedForModule<LocalFolder, string>('uload', 'uloadFolders').sortBy(
|
||||
'order'
|
||||
);
|
||||
return locals.filter((f) => !f.deletedAt).map(toFolder);
|
||||
}, [] as Folder[]);
|
||||
}
|
||||
|
||||
export function useAllLinkTags() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalLinkTag>('linkTags').toArray();
|
||||
const locals = await scopedForModule<LocalLinkTag, string>('uload', 'linkTags').toArray();
|
||||
return locals.filter((lt) => !lt.deletedAt).map(toLinkTag);
|
||||
}, [] as LinkTag[]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import type { WeatherLocation, WeatherSettings } from './types';
|
||||
|
||||
export function useLocations() {
|
||||
return useLiveQueryWithDefault(
|
||||
() => db.table<WeatherLocation>('wetterLocations').orderBy('order').toArray(),
|
||||
() => scopedForModule<WeatherLocation, string>('wetter', 'wetterLocations').sortBy('order'),
|
||||
[] as WeatherLocation[]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import { useLiveQueryWithDefault } from '@mana/local-store/svelte';
|
||||
import { db } from '$lib/data/database';
|
||||
import { scopedForModule } from '$lib/data/scope';
|
||||
import { decryptRecords } from '$lib/data/crypto';
|
||||
import type {
|
||||
LocalWish,
|
||||
|
|
@ -68,7 +69,9 @@ export function toPriceCheck(local: LocalPriceCheck): PriceCheck {
|
|||
|
||||
export function useAllWishes() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalWish>('wishesItems').orderBy('order').toArray();
|
||||
const locals = await scopedForModule<LocalWish, string>('wishes', 'wishesItems').sortBy(
|
||||
'order'
|
||||
);
|
||||
const visible = locals.filter((w) => !w.deletedAt);
|
||||
const decrypted = await decryptRecords('wishesItems', visible);
|
||||
return decrypted.map(toWish);
|
||||
|
|
@ -77,7 +80,9 @@ export function useAllWishes() {
|
|||
|
||||
export function useAllLists() {
|
||||
return useLiveQueryWithDefault(async () => {
|
||||
const locals = await db.table<LocalWishList>('wishesLists').orderBy('order').toArray();
|
||||
const locals = await scopedForModule<LocalWishList, string>('wishes', 'wishesLists').sortBy(
|
||||
'order'
|
||||
);
|
||||
const visible = locals.filter((l) => !l.deletedAt && !l.isArchived);
|
||||
return visible.map(toWishList);
|
||||
}, [] as WishList[]);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue