refactor: separate mobile note projection

This commit is contained in:
lucaronin
2026-05-04 00:42:40 +02:00
parent e0887c6d71
commit 5afd1ca62a
4 changed files with 96 additions and 24 deletions

View File

@@ -1,19 +1,8 @@
import { countWords, deriveDisplayTitleState, extractSnippet } from '@tolaria/markdown'
import { projectMobileNotes, type MobileNote, type MobileNoteSource } from './mobileNoteProjection'
export interface MobileNote {
id: string
type: string
icon: string
date: string
modified: string
content: string
title: string
snippet: string
words: number
tags: string[]
}
export type { MobileNote } from './mobileNoteProjection'
const noteContent = [
const noteContent: MobileNoteSource[] = [
{
id: 'workflow',
type: 'Essay',
@@ -76,15 +65,7 @@ const noteContent = [
},
]
export const notes: MobileNote[] = noteContent.map((note) => {
const titleState = deriveDisplayTitleState({ content: note.content, filename: note.filename })
return {
...note,
title: titleState.title,
snippet: extractSnippet(note.content),
words: countWords(note.content),
}
})
export const notes: MobileNote[] = projectMobileNotes(noteContent)
export const sidebarSections = [
{

View File

@@ -0,0 +1,44 @@
import { describe, expect, it } from 'vitest'
import { projectMobileNote, projectMobileNotes, type MobileNoteSource } from './mobileNoteProjection'
const sourceNote: MobileNoteSource = {
id: 'workflow',
type: 'Essay',
icon: 'pen-nib',
date: 'May 13, 2026',
modified: '6h ago',
filename: 'workflow-orchestration-kestra.md',
tags: ['Design Inspiration', 'Tolaria MVP'],
content: [
'---',
'title: Workflow Orchestration Essay',
'type: Essay',
'---',
'',
'# Workflow Orchestration Essay',
'',
'The current narrative / temptation is everything routed through an LLM.',
].join('\n'),
}
describe('mobile note projection', () => {
it('derives list and editor metadata from markdown content', () => {
const note = projectMobileNote(sourceNote)
expect(note).toMatchObject({
id: 'workflow',
title: 'Workflow Orchestration Essay',
snippet: 'The current narrative / temptation is everything routed through an LLM.',
words: 11,
})
})
it('keeps projection order stable for note lists', () => {
const notes = projectMobileNotes([
sourceNote,
{ ...sourceNote, id: 'release', filename: 'release.md' },
])
expect(notes.map((note) => note.id)).toEqual(['workflow', 'release'])
})
})

View File

@@ -0,0 +1,42 @@
import { countWords, deriveDisplayTitleState, extractSnippet } from '@tolaria/markdown'
export type MobileNoteSource = {
id: string
type: string
icon: string
date: string
modified: string
filename: string
content: string
tags: string[]
}
export type MobileNote = Omit<MobileNoteSource, 'filename'> & {
title: string
snippet: string
words: number
}
export function projectMobileNote(source: MobileNoteSource): MobileNote {
const titleState = deriveDisplayTitleState({
content: source.content,
filename: source.filename,
})
return {
id: source.id,
type: source.type,
icon: source.icon,
date: source.date,
modified: source.modified,
content: source.content,
tags: source.tags,
title: titleState.title,
snippet: extractSnippet(source.content),
words: countWords(source.content),
}
}
export function projectMobileNotes(sources: MobileNoteSource[]): MobileNote[] {
return sources.map(projectMobileNote)
}

View File

@@ -8,7 +8,7 @@ This file is the resumable working log for Tolaria mobile. The strategy and road
- Branch: `codex/mobile`
- Active phase: Phase 2 - Mobile Shell
- Active slice: Prepare compact navigation for gesture-driven phone shell
- Active slice: Separate mobile note projection from fixtures
- Push policy: commit locally; do not push unless explicitly requested
- Validation target: iPad/iOS simulator first
@@ -35,6 +35,7 @@ This file is the resumable working log for Tolaria mobile. The strategy and road
- Split mobile styles into small panel-specific StyleSheet modules so new mobile code starts at CodeScene `10.0`.
- Pinned Expo runtime dependencies to the versions expected by Expo 55 after the initial generated versions failed iOS bundle export (`react-native@0.83.6`, `react@19.2.0`, matching safe-area/svg versions).
- Extracted compact phone navigation into a pure tested state machine so future swipe gestures can dispatch explicit events instead of mutating panels ad hoc.
- Extracted mobile note projection into a pure module that turns raw vault-like note records into the list/editor shape used by the mobile shell.
## Next Action
@@ -85,6 +86,10 @@ Continue Phase 2 with the next mobile shell slice:
- `pnpm --filter @tolaria/mobile typecheck` passed after compact navigation extraction.
- CodeScene after compact navigation extraction: `apps/mobile/src/compactNavigation.ts`, `apps/mobile/src/compactNavigation.test.ts`, and the touched `apps/mobile/src/MobileApp.tsx` scored `10`.
- `pnpm --filter @tolaria/mobile exec expo export --platform ios --output-dir /tmp/tolaria-mobile-export` passed after compact navigation extraction.
- `pnpm --filter @tolaria/mobile test` passed after note projection extraction: 3 files / 8 tests.
- `pnpm --filter @tolaria/mobile typecheck` passed after note projection extraction.
- CodeScene after note projection extraction: `apps/mobile/src/mobileNoteProjection.ts` and `apps/mobile/src/mobileNoteProjection.test.ts` scored `10`; `apps/mobile/src/demoData.ts` returned no scorable code and no findings.
- `pnpm --filter @tolaria/mobile exec expo export --platform ios --output-dir /tmp/tolaria-mobile-export` passed after note projection extraction.
## Risks / Watch Items