Skip to content

Commit

Permalink
Current commit management
Browse files Browse the repository at this point in the history
  • Loading branch information
csansoon committed Jul 16, 2024
1 parent 393a84f commit e7f7735
Show file tree
Hide file tree
Showing 16 changed files with 194 additions and 71 deletions.
11 changes: 11 additions & 0 deletions apps/web/src/app/(private)/[commitUuid]/editor/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { DocumentEditor } from '@latitude-data/web-ui'

export const dynamic = 'force-dynamic'

export default function Editor() {
return (
<div className='w-full h-full relative'>
<DocumentEditor document={`This is a commit`} />
</div>
)
}
32 changes: 32 additions & 0 deletions apps/web/src/app/(private)/[commitUuid]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { ReactNode } from 'react'

// import Sidebar from '$/components/Sidebar'
import { CommitProvider } from '@latitude-data/web-ui'
import { getNextCommitId, getPreviousCommitId } from '$core/data-access'

// import { getIsCommitEditableAction } from '$/actions/commits'

export default async function PrivateLayout({
children,
params,
}: {
children: ReactNode
params: { commitUuid: string }
}) {
const commitUuid = params.commitUuid

const nextCommitId = await getNextCommitId({ uuid: commitUuid })
const previousCommitId = await getPreviousCommitId({ uuid: commitUuid })

const isDraft =
nextCommitId.unwrap() === null && previousCommitId.unwrap() === null

return (
<CommitProvider commitUuid={commitUuid} isDraft={isDraft}>
<main className='flex flex-row w-full'>
<div className='w-[280px]'>{/* <Sidebar /> */}</div>
<div className='flex-1'>{children}</div>
</main>
</CommitProvider>
)
}
10 changes: 1 addition & 9 deletions apps/web/src/app/(private)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ReactNode } from 'react'

import Sidebar from '$/components/Sidebar'
import { getSession } from '$/services/auth/getSession'
import { ROUTES } from '$/services/routes'
import { redirect } from 'next/navigation'
Expand All @@ -14,12 +13,5 @@ export default async function PrivateLayout({
if (!data.session) {
return redirect(ROUTES.auth.login)
}
return (
<main className='flex flex-row w-full'>
<div className='w-[280px]'>
<Sidebar />
</div>
<div className='flex-1'>{children}</div>
</main>
)
return children
}
5 changes: 2 additions & 3 deletions apps/web/src/app/api/commits/[commitUuid]/documents/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import { materializeDocumentsAtCommit } from '@latitude-data/core'
import { NextRequest, NextResponse } from 'next/server'

export async function GET(
req: NextRequest,
_: NextRequest,
{ commitUuid }: { commitUuid: string },
) {
try {
const staged = Boolean(req.nextUrl.searchParams.get('staged') || false)
const documents = await materializeDocumentsAtCommit({ commitUuid, staged })
const documents = await materializeDocumentsAtCommit({ commitUuid })

return NextResponse.json(documents)
} catch (err: unknown) {
Expand Down
24 changes: 18 additions & 6 deletions apps/web/src/components/Sidebar/DocumentTree/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { faker } from '@faker-js/faker'
import type { DocumentType, DocumentVersion } from '@latitude-data/core'
import { useCurrentCommit } from '@latitude-data/web-ui'
import useDocumentVersions from '$/stores/documentVersions'

import { Node, useTree } from '../toTree'
Expand All @@ -20,26 +21,36 @@ export function CreateNode({ parentId }: { parentId?: number }) {
}

function CreateFolder({ parentId }: { parentId?: number }) {
const { create } = useDocumentVersions({ staged: true })
const { commitUuid, isDraft } = useCurrentCommit()
const { create } = useDocumentVersions({ commitUuid: commitUuid })
return (
<button
onClick={() =>
disabled={!isDraft}
onClick={() => {
if (!isDraft) return
create({
parentId,
documentType: 'folder' as DocumentType.Folder,
name: generateName(),
})
}
}}
>
+F
</button>
)
}

function CreateDocument({ parentId }: { parentId?: number }) {
const { create } = useDocumentVersions({ staged: true })
const { commitUuid, isDraft } = useCurrentCommit()
const { create } = useDocumentVersions({ commitUuid: commitUuid })
return (
<button onClick={() => create({ parentId, name: generateName() })}>
<button
disabled={!isDraft}
onClick={() => {
if (!isDraft) return
create({ parentId, name: generateName() })
}}
>
+D
</button>
)
Expand Down Expand Up @@ -74,8 +85,9 @@ export default function DocumentTree({
}: {
documents: DocumentVersion[]
}) {
const { commitUuid } = useCurrentCommit()
const { documents } = useDocumentVersions(
{ staged: true },
{ commitUuid },
{ fallbackData: serverDocuments },
)
const rootNode = useTree({ documents })
Expand Down
1 change: 0 additions & 1 deletion apps/web/src/components/Sidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import DocumentTree, { CreateNode } from './DocumentTree'
export default async function Sidebar() {
const documents = await materializeDocumentsAtCommit({
commitUuid: HEAD_COMMIT,
staged: true,
})

return (
Expand Down
13 changes: 3 additions & 10 deletions apps/web/src/stores/documentVersions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,13 @@ import { useServerAction } from 'zsa-react'
const FIXME_HARDCODED_PROJECT_ID = 1
export default function useDocumentVersions(
{
commitUuid = HEAD_COMMIT,
staged = false,
commitUuid,
}: {
commitUuid?: string
staged?: boolean
},
opts?: SWRConfiguration,
) {
const key =
`/api/commits/${commitUuid}/documents?` +
new URLSearchParams({
staged: String(staged),
}).toString()
const key = `/api/commits/${commitUuid ?? HEAD_COMMIT}/documents`

const { mutate, data, ...rest } = useSWR<DocumentVersion[]>(
key,
Expand All @@ -34,7 +28,6 @@ export default function useDocumentVersions(
const { execute } = useServerAction(createDocumentVersionAction)
const create = useCallback(
async (payload: {
commitUuid?: string
name: string
documentType?: DocumentType
parentId?: number
Expand All @@ -43,7 +36,7 @@ export default function useDocumentVersions(
...payload,
projectId: FIXME_HARDCODED_PROJECT_ID,
name: payload.name!,
commitUuid: payload.commitUuid || HEAD_COMMIT,
commitUuid: commitUuid || HEAD_COMMIT,
})
const prev = documents ?? []

Expand Down
92 changes: 80 additions & 12 deletions packages/core/src/data-access/commits.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,94 @@
import { database } from '$core/client'
import { HEAD_COMMIT } from '$core/constants'
import { HEAD_COMMIT, Result, TypedResult } from '$core/constants'
import { LatitudeError, NotFoundError } from '$core/lib/errors'
import { commits } from '$core/schema'
import { desc, eq, isNull } from 'drizzle-orm'
import { and, desc, eq, isNotNull, isNull } from 'drizzle-orm'

const selectCondition = (uuid?: Exclude<string, 'HEAD'>) => {
if (!uuid) return isNull(commits.nextCommitId)
export async function findHeadCommit(
tx = database,
): Promise<TypedResult<number, LatitudeError>> {
// Commits that are being pointed at by other commits.
const childCommits = tx
.$with('child_commits')
.as(
tx
.select({ id: commits.nextCommitId })
.from(commits)
.where(isNotNull(commits.nextCommitId))
.orderBy(desc(commits.id))
.limit(1),
)

return eq(commits.uuid, uuid)
}
// Commits that have previous commits but no next commits.
const headCommits = await tx
.with(childCommits)
.select({ id: commits.id })
.from(commits)
.leftJoin(childCommits, eq(commits.id, childCommits.id))
.where(and(isNull(commits.nextCommitId), isNotNull(childCommits.id)))

if (headCommits.length < 1) {
return Result.error(new NotFoundError('No head commit found'))
}

export async function findCommit({ uuid }: { uuid?: string }, tx = database) {
if (uuid === HEAD_COMMIT) {
return tx.query.commits.findFirst({ orderBy: desc(commits.id) })
if (headCommits.length > 1) {
return Result.error(new LatitudeError('Multiple head commits found'))
}

return tx.query.commits.findFirst({ where: selectCondition(uuid) })
const headCommit = headCommits[0]!
return Result.ok(headCommit.id)
}

export async function findCommit(
{ uuid }: { uuid: string },
tx = database,
): Promise<TypedResult<number, LatitudeError>> {
if (uuid === HEAD_COMMIT) return findHeadCommit(tx)

const res = await tx
.select()
.from(commits)
.where(eq(commits.uuid, uuid))
.limit(1)

if (!res.length) return Result.error(new NotFoundError('Commit not found'))
const commit = res[0]!
return Result.ok(commit.id)
}

export async function listCommits() {
return database.select().from(commits)
}

export async function listStagedCommits() {
return database.select().from(commits).where(isNull(commits.nextCommitId))
export async function getNextCommitId(
{ uuid }: { uuid: string },
tx = database,
): Promise<TypedResult<number | null, LatitudeError>> {
if (uuid === HEAD_COMMIT) return Result.ok(null)
const res = await tx
.select({ nextCommitId: commits.nextCommitId })
.from(commits)
.where(eq(commits.uuid, uuid))
.limit(1)

if (!res.length) return Result.error(new NotFoundError('Commit not found'))

return Result.ok(res[0]!.nextCommitId)
}

export async function getPreviousCommitId(
{ uuid }: { uuid: string },
tx = database,
): Promise<TypedResult<number | null, LatitudeError>> {
const commitIdResult = await findCommit({ uuid }, tx)
if (!Result.isOk(commitIdResult)) return commitIdResult
const commitId = commitIdResult.unwrap()

const res = await tx
.select({ id: commits.id })
.from(commits)
.where(eq(commits.nextCommitId, commitId))

if (!res.length) return Result.ok(null)
return Result.ok(res[0]!.id)
}
17 changes: 0 additions & 17 deletions packages/core/src/data-access/documentVersions.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,6 @@
import { commits, database, documentVersions } from '@latitude-data/core'
import { desc, eq, inArray, lte } from 'drizzle-orm'

import { listStagedCommits } from './commits'

export async function listStagedDocuments() {
const commits = await listStagedCommits()
if (!commits.length) return []

return database
.select()
.from(documentVersions)
.where(
inArray(
documentVersions.commitId,
commits.map((c) => c.id),
),
)
}

export async function getDocumentsAtCommit(commitUuid: string) {
const referenceCommitId = await database
.select({ id: commits.id })
Expand Down
15 changes: 2 additions & 13 deletions packages/core/src/services/documentVersions/materializeAtCommit.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
import { uniqBy } from 'lodash-es'

import { HEAD_COMMIT } from '$core/constants'
import {
getDocumentsAtCommit,
listdocumentSnapshots,
listStagedDocuments,
} from '$core/data-access'
import { getDocumentsAtCommit, listdocumentSnapshots } from '$core/data-access'

export async function materializeDocumentsAtCommit({
commitUuid = HEAD_COMMIT,
staged = true,
}: {
commitUuid: string
staged: boolean
}) {
if (commitUuid === HEAD_COMMIT) {
const snapshots = (await listdocumentSnapshots()).map(
(snap) => snap.document_versions,
)
if (!staged) return snapshots

const versions = await listStagedDocuments()
return uniqBy([...versions, ...snapshots], (doc) => doc.documentUuid)
return snapshots
} else {
return await getDocumentsAtCommit(commitUuid)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export function DocumentTextEditor({
value,
metadata,
onChange,
disabled,
}: DocumentTextEditorProps) {
const editorRef = useRef<editor.IStandaloneCodeEditor | null>(null)
const monacoRef = useRef<Monaco | null>(null)
Expand Down Expand Up @@ -94,6 +95,10 @@ export function DocumentTextEditor({
onChange={handleValueChange}
options={{
lineNumbers: 'off',
readOnly: disabled,
readOnlyMessage: {
value: 'Create a new draft to edit this document',
},
minimap: {
enabled: false,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export type DocumentTextEditorProps = {
value: string
metadata?: ConversationMetadata
onChange?: (value: string) => void
disabled?: boolean
}

const DocumentTextEditor = lazy(() =>
Expand Down
1 change: 1 addition & 0 deletions packages/web-ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './ds/atoms'
export * from './ds/molecules'
export * from './layouts'
export * from './sections'
export * from './providers'
Loading

0 comments on commit e7f7735

Please sign in to comment.