managarten/packages/shared-stores/src/toggle-field.ts
Till JS 7df515434e fix: revert tier test patch, widen toggleField, add spiral-db prepare
Three independent fixes grouped because they're each one-line changes:

1. Revert MANA_APPS requiredTier test patch
   Commit e52b6e29f flipped all 36+ apps to requiredTier='guest' for
   local testing. Restored original tiers from before the flip:
   guest-accessible (contacts, calendar, todo), public (who),
   beta (zitare, calc, guides, arcade), alpha (most modules),
   founder (memoro, nutriphi, mail, habits, notes, dreams, cycles,
   events, finance, places, news). Body stays at 'guest' (new module,
   intentional). The memory note "REVERT BEFORE RELEASE" is now done.

2. Widen toggleField to accept IndexableType keys
   `toggleField<T>(table: Table<T, string>, ...)` rejected Dexie
   tables keyed by IndexableType (the default). Changed the second
   generic to IndexableType so callers like images.svelte.ts don't
   need the `as unknown as Parameters<...>[0]` double-cast.

3. Add prepare script to spiral-db
   `"prepare": "pnpm build"` ensures `dist/` is rebuilt after
   `pnpm install` on a fresh clone. Without this, the 209 cascading
   type errors from stale/missing dist files return on every new
   checkout. Also added `prepublishOnly` as a safety net.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 18:35:20 +02:00

42 lines
1.1 KiB
TypeScript

/**
* Generic boolean field toggle for Dexie tables.
*
* Standardizes the common pattern of toggling a boolean field (isFavorite, isPinned, etc.)
* on a record in IndexedDB. Reads current value, flips it, updates with timestamp.
*
* @example
* ```typescript
* import { toggleField } from '@mana/shared-stores';
* import { db } from '$lib/data/database';
*
* // In your store:
* async function toggleFavorite(id: string) {
* return toggleField(db.table('contacts'), id, 'isFavorite');
* }
* ```
*/
import type { IndexableType, Table, UpdateSpec } from 'dexie';
/**
* Toggle a boolean field on a Dexie record.
* @returns The new value of the field after toggling.
*/
export async function toggleField<T>(
table: Table<T, IndexableType>,
id: string,
field: string
): Promise<boolean> {
const record = await table.get(id);
if (!record) throw new Error(`Record ${id} not found`);
const current = !!(record as Record<string, unknown>)[field];
const newValue = !current;
await table.update(id, {
[field]: newValue,
updatedAt: new Date().toISOString(),
} as unknown as UpdateSpec<T>);
return newValue;
}