<html lang="en">
<head></head>
<body>

<form id="mainForm" method="post" action="https://stackblitz.com/run" target="_self">
<input type="hidden" name="project[files][CHANGELOG.md]" value="# @tanstack/db-example-paced-mutations-demo

## 0.0.7

### Patch Changes

- Updated dependencies [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45), [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a), [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)]:
  - @tanstack/db@0.4.20
  - @tanstack/react-db@0.1.43

## 0.0.6

### Patch Changes

- Updated dependencies [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)]:
  - @tanstack/db@0.4.19
  - @tanstack/react-db@0.1.42

## 0.0.5

### Patch Changes

- Updated dependencies [[`5b6437b`](https://github.com/TanStack/db/commit/5b6437b5c316740c77b7ab7ebd41565a375c7f2e)]:
  - @tanstack/react-db@0.1.41

## 0.0.4

### Patch Changes

- Updated dependencies [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9), [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)]:
  - @tanstack/db@0.4.18
  - @tanstack/react-db@0.1.40

## 0.0.3

### Patch Changes

- Updated dependencies [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)]:
  - @tanstack/db@0.4.17
  - @tanstack/react-db@0.1.39

## 0.0.2

### Patch Changes

- Updated dependencies [[`979a66f`](https://github.com/TanStack/db/commit/979a66f2f6eff0ffe44dfde7c67feea933ee6110), [`f8a979b`](https://github.com/TanStack/db/commit/f8a979ba3aa90ac7e85f7a065fc050bda6589b4b), [`cb25623`](https://github.com/TanStack/db/commit/cb256234c9cd8df7771808b147e5afc2be56f51f)]:
  - @tanstack/db@0.4.16
  - @tanstack/react-db@0.1.38
">
<input type="hidden" name="project[files][index.html]" value="&lt;!doctype html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Paced Mutations Demo&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
    &lt;script type=&quot;module&quot; src=&quot;/src/main.tsx&quot;&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
">
<input type="hidden" name="project[files][package.json]" value="{&quot;name&quot;:&quot;@tanstack/db-example-paced-mutations-demo&quot;,&quot;version&quot;:&quot;0.0.7&quot;,&quot;private&quot;:true,&quot;type&quot;:&quot;module&quot;,&quot;scripts&quot;:{&quot;dev&quot;:&quot;vite&quot;,&quot;build&quot;:&quot;vite build&quot;,&quot;preview&quot;:&quot;vite preview&quot;},&quot;dependencies&quot;:{&quot;@tanstack/db&quot;:&quot;https://pkg.pr.new/TanStack/db/@tanstack/db@4ccb9543a89033bbaecc8b25cb1b7616e694285f&quot;,&quot;@tanstack/react-db&quot;:&quot;https://pkg.pr.new/TanStack/db/@tanstack/react-db@4ccb9543a89033bbaecc8b25cb1b7616e694285f&quot;,&quot;mitt&quot;:&quot;^3.0.1&quot;,&quot;react&quot;:&quot;^19.2.4&quot;,&quot;react-dom&quot;:&quot;^19.2.4&quot;},&quot;devDependencies&quot;:{&quot;@types/react&quot;:&quot;^19.2.13&quot;,&quot;@types/react-dom&quot;:&quot;^19.2.3&quot;,&quot;@vitejs/plugin-react&quot;:&quot;^5.1.3&quot;,&quot;typescript&quot;:&quot;^5.9.2&quot;,&quot;vite&quot;:&quot;^7.3.0&quot;}}">
<input type="hidden" name="project[files][tsconfig.json]" value="{
  &quot;compilerOptions&quot;: {
    &quot;target&quot;: &quot;ES2020&quot;,
    &quot;useDefineForClassFields&quot;: true,
    &quot;lib&quot;: [&quot;ES2020&quot;, &quot;DOM&quot;, &quot;DOM.Iterable&quot;],
    &quot;module&quot;: &quot;ESNext&quot;,
    &quot;skipLibCheck&quot;: true,
    &quot;moduleResolution&quot;: &quot;bundler&quot;,
    &quot;allowImportingTsExtensions&quot;: true,
    &quot;isolatedModules&quot;: true,
    &quot;moduleDetection&quot;: &quot;force&quot;,
    &quot;noEmit&quot;: true,
    &quot;jsx&quot;: &quot;react-jsx&quot;,
    &quot;strict&quot;: true,
    &quot;noUnusedLocals&quot;: true,
    &quot;noUnusedParameters&quot;: true,
    &quot;noFallthroughCasesInSwitch&quot;: true,
    &quot;noUncheckedSideEffectImports&quot;: true
  },
  &quot;include&quot;: [&quot;src&quot;, &quot;vite.config.ts&quot;]
}
">
<input type="hidden" name="project[files][vite.config.ts]" value="import { defineConfig } from &#39;vite&#39;
import react from &#39;@vitejs/plugin-react&#39;

export default defineConfig({
  plugins: [react()],
})
">
<input type="hidden" name="project[files][src/App.tsx]" value="import { useEffect, useMemo, useState } from &#39;react&#39;
import mitt from &#39;mitt&#39;
import {
  createCollection,
  debounceStrategy,
  queueStrategy,
  throttleStrategy,
  usePacedMutations,
} from &#39;@tanstack/react-db&#39;
import type { PendingMutation, Transaction } from &#39;@tanstack/react-db&#39;

interface Item {
  id: number
  value: number
  timestamp: number
}

// Create event emitter for fake server communication
const serverEmitter = mitt()

// Fake server store - initialize with a single item
const fakeServer = new Map&lt;number, Item&gt;([
  [1, { id: 1, value: 0, timestamp: Date.now() }],
])

// Create a collection with fake sync
const itemCollection = createCollection&lt;Item&gt;({
  id: `items`,
  getKey: (item) =&gt; item.id,
  startSync: true,
  sync: {
    sync: ({ begin, write, commit, markReady }) =&gt; {
      // Initial sync - load the initial item from fake server
      begin()
      fakeServer.forEach((item) =&gt; {
        write({
          type: `insert`,
          value: item,
        })
      })
      commit()
      markReady()

      // Listen for server updates and sync them back
      // @ts-expect-error mitt typing
      serverEmitter.on(`*`, (_, changes: Array&lt;PendingMutation&lt;Item&gt;&gt;) =&gt; {
        begin()
        changes.forEach((change) =&gt; {
          if (change.type === `update`) {
            write({
              type: change.type,
              // @ts-expect-error pending mutation type
              value: change.modified,
            })
          } else {
            write({
              type: change.type,
              // @ts-expect-error pending mutation type
              value: change.changes,
            })
          }
        })
        commit()
      })
    },
  },
})

// Track transaction state for visualization
interface TrackedTransaction {
  id: string
  transaction: Transaction
  state: `pending` | `executing` | `completed` | `failed`
  mutations: Array&lt;PendingMutation&lt;Item&gt;&gt;
  createdAt: number
  executingAt?: number
  completedAt?: number
}

type StrategyType = `debounce` | `queue` | `throttle`

export function App() {
  const [strategyType, setStrategyType] = useState&lt;StrategyType&gt;(`debounce`)
  const [wait, setWait] = useState(300)
  const [leading, setLeading] = useState(false)
  const [trailing, setTrailing] = useState(true)

  const [transactions, setTransactions] = useState&lt;Array&lt;TrackedTransaction&gt;&gt;(
    [],
  )
  const [optimisticState, setOptimisticState] = useState&lt;Item | null&gt;(null)
  const [syncedState, setSyncedState] = useState&lt;Item&gt;(fakeServer.get(1)!)

  // Initialize optimistic state from collection when ready
  useEffect(() =&gt; {
    itemCollection.stateWhenReady().then(() =&gt; {
      setOptimisticState(itemCollection.get(1))
    })
  }, [])

  // Create the strategy based on current settings
  // Memoize to prevent recreation on every render
  const strategy = useMemo(() =&gt; {
    if (strategyType === `debounce`) {
      return debounceStrategy({ wait, leading, trailing })
    } else if (strategyType === `queue`) {
      return queueStrategy({ wait })
    } else {
      return throttleStrategy({ wait, leading, trailing })
    }
  }, [strategyType, wait, leading, trailing])

  // Create the paced mutations hook with onMutate for optimistic updates
  const mutate = usePacedMutations&lt;number&gt;({
    onMutate: (newValue) =&gt; {
      // Apply optimistic update immediately
      itemCollection.update(1, (draft) =&gt; {
        draft.value = newValue
        draft.timestamp = Date.now()
      })
    },
    mutationFn: async ({ transaction }) =&gt; {
      console.log(`mutationFn called with transaction:`, transaction)

      // Update transaction state to executing when commit starts
      const executingAt = Date.now()
      setTransactions((prev) =&gt;
        prev.map((t) =&gt; {
          if (t.id === transaction.id) {
            return { ...t, state: `executing` as const, executingAt }
          }
          return t
        }),
      )

      // Simulate network delay to fake server (random 100-600ms)
      const delay = Math.random() * 500 + 100
      await new Promise((resolve) =&gt; setTimeout(resolve, delay))

      // Write mutations to fake server
      transaction.mutations.forEach((mutation) =&gt; {
        console.log(`Processing mutation:`, mutation)
        if (mutation.type === `insert`) {
          const item = mutation.changes as Item
          fakeServer.set(item.id, item)
        } else if (mutation.type === `update`) {
          const item = mutation.modified as Item
          fakeServer.set(item.id, item)
        } else {
          // delete
          fakeServer.delete(mutation.key as number)
        }
      })

      // Update synced state
      setSyncedState(fakeServer.get(1)!)

      console.log(`Emitting sync event`)
      // Sync back from server
      serverEmitter.emit(`sync`, transaction.mutations)
    },
    strategy,
  })

  // Trigger a mutation with a specific value
  const triggerMutation = (newValue: number) =&gt; {
    // Pass the value directly - onMutate will apply the optimistic update
    const tx = mutate(newValue)

    // Update optimistic state after onMutate has been called
    setOptimisticState(itemCollection.get(1))

    // Track this transaction
    const tracked: TrackedTransaction = {
      id: tx.id,
      transaction: tx,
      state: `pending`,
      mutations: tx.mutations,
      createdAt: Date.now(),
    }

    setTransactions((prev) =&gt; {
      // Only add if this transaction ID isn&#39;t already tracked
      if (prev.some((t) =&gt; t.id === tx.id)) {
        return prev
      }
      return [...prev, tracked]
    })

    // Listen for completion
    tx.isPersisted.promise
      .then(() =&gt; {
        setTransactions((prev) =&gt;
          prev.map((t) =&gt; {
            if (t.id === tx.id) {
              return {
                ...t,
                state: `completed` as const,
                completedAt: Date.now(),
              }
            }
            return t
          }),
        )
        // Update optimistic state after completion
        setOptimisticState(itemCollection.get(1))
      })
      .catch((error) =&gt; {
        console.error(`Transaction failed:`, error)
        setTransactions((prev) =&gt;
          prev.map((t) =&gt; {
            if (t.id === tx.id) {
              return { ...t, state: `failed` as const, completedAt: Date.now() }
            }
            return t
          }),
        )
        // Update optimistic state after failure
        setOptimisticState(itemCollection.get(1))
      })
  }

  const pending = transactions.filter((t) =&gt; t.state === `pending`)
  const executing = transactions.filter((t) =&gt; t.state === `executing`)
  const completed = transactions.filter((t) =&gt; t.state === `completed`)

  return (
    &lt;div className=&quot;app&quot;&gt;
      &lt;h1&gt;Paced Mutations Demo&lt;/h1&gt;
      &lt;p className=&quot;subtitle&quot;&gt;
        Drag the slider to trigger mutations and see how different strategies
        batch, queue, and persist changes
      &lt;/p&gt;

      &lt;div className=&quot;stats&quot;&gt;
        &lt;div className=&quot;stat-card&quot;&gt;
          &lt;div className=&quot;stat-value&quot;&gt;{optimisticState?.value ?? 0}&lt;/div&gt;
          &lt;div className=&quot;stat-label&quot;&gt;Optimistic Value&lt;/div&gt;
        &lt;/div&gt;
        &lt;div className=&quot;stat-card&quot;&gt;
          &lt;div className=&quot;stat-value&quot;&gt;{syncedState.value}&lt;/div&gt;
          &lt;div className=&quot;stat-label&quot;&gt;Synced Value&lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div className=&quot;stats&quot;&gt;
        &lt;div className=&quot;stat-card&quot;&gt;
          &lt;div className=&quot;stat-value&quot;&gt;{pending.length}&lt;/div&gt;
          &lt;div className=&quot;stat-label&quot;&gt;Pending&lt;/div&gt;
        &lt;/div&gt;
        &lt;div className=&quot;stat-card&quot;&gt;
          &lt;div className=&quot;stat-value&quot;&gt;{executing.length}&lt;/div&gt;
          &lt;div className=&quot;stat-label&quot;&gt;Executing&lt;/div&gt;
        &lt;/div&gt;
        &lt;div className=&quot;stat-card&quot;&gt;
          &lt;div className=&quot;stat-value&quot;&gt;{completed.length}&lt;/div&gt;
          &lt;div className=&quot;stat-label&quot;&gt;Completed&lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div className=&quot;grid&quot;&gt;
        &lt;div className=&quot;panel&quot;&gt;
          &lt;h2&gt;Strategy Configuration&lt;/h2&gt;

          &lt;div className=&quot;control-group&quot;&gt;
            &lt;label&gt;Strategy Type&lt;/label&gt;
            &lt;select
              value={strategyType}
              onChange={(e) =&gt; setStrategyType(e.target.value as StrategyType)}
            &gt;
              &lt;option value=&quot;debounce&quot;&gt;Debounce&lt;/option&gt;
              &lt;option value=&quot;queue&quot;&gt;Queue&lt;/option&gt;
              &lt;option value=&quot;throttle&quot;&gt;Throttle&lt;/option&gt;
            &lt;/select&gt;
          &lt;/div&gt;

          &lt;div className=&quot;control-group&quot;&gt;
            &lt;label&gt;Wait Time (ms)&lt;/label&gt;
            &lt;input
              type=&quot;number&quot;
              value={wait}
              onChange={(e) =&gt; setWait(Number(e.target.value))}
              min={0}
              step={100}
            /&gt;
          &lt;/div&gt;

          {(strategyType === `debounce` || strategyType === `throttle`) &amp;&amp; (
            &lt;&gt;
              &lt;div className=&quot;checkbox-group&quot;&gt;
                &lt;input
                  type=&quot;checkbox&quot;
                  id=&quot;leading&quot;
                  checked={leading}
                  onChange={(e) =&gt; setLeading(e.target.checked)}
                /&gt;
                &lt;label htmlFor=&quot;leading&quot;&gt;Leading edge execution&lt;/label&gt;
              &lt;/div&gt;

              &lt;div className=&quot;checkbox-group&quot;&gt;
                &lt;input
                  type=&quot;checkbox&quot;
                  id=&quot;trailing&quot;
                  checked={trailing}
                  onChange={(e) =&gt; setTrailing(e.target.checked)}
                /&gt;
                &lt;label htmlFor=&quot;trailing&quot;&gt;Trailing edge execution&lt;/label&gt;
              &lt;/div&gt;
            &lt;/&gt;
          )}

          &lt;div className=&quot;control-group&quot;&gt;
            &lt;label&gt;Slider Value: {optimisticState?.value ?? 0}&lt;/label&gt;
            &lt;input
              type=&quot;range&quot;
              min={0}
              max={100}
              value={optimisticState?.value ?? 0}
              onChange={(e) =&gt; triggerMutation(Number(e.target.value))}
              style={{ width: `100%` }}
            /&gt;
            &lt;div
              style={{
                display: `flex`,
                justifyContent: `space-between`,
                fontSize: `12px`,
                color: `#999`,
              }}
            &gt;
              &lt;span&gt;0&lt;/span&gt;
              &lt;span&gt;50&lt;/span&gt;
              &lt;span&gt;100&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;

          &lt;div style={{ marginTop: `20px`, fontSize: `13px`, color: `#666` }}&gt;
            &lt;h3 style={{ fontSize: `14px`, marginBottom: `8px` }}&gt;
              Strategy Info:
            &lt;/h3&gt;
            {strategyType === `debounce` &amp;&amp; (
              &lt;p&gt;
                &lt;strong&gt;Debounce:&lt;/strong&gt; Waits for {wait}ms of inactivity
                before persisting.
                {leading &amp;&amp; ` Executes immediately on first call.`}
                {trailing &amp;&amp; ` Executes after wait period.`}
              &lt;/p&gt;
            )}
            {strategyType === `queue` &amp;&amp; (
              &lt;p&gt;
                &lt;strong&gt;Queue:&lt;/strong&gt; Processes mutations sequentially in
                order received (FIFO) with {wait}ms between each.
              &lt;/p&gt;
            )}
            {strategyType === `throttle` &amp;&amp; (
              &lt;p&gt;
                &lt;strong&gt;Throttle:&lt;/strong&gt; Ensures at least {wait}ms between
                executions.
                {leading &amp;&amp; ` Executes immediately on first call.`}
                {trailing &amp;&amp; ` Executes after wait period.`}
              &lt;/p&gt;
            )}
          &lt;/div&gt;
        &lt;/div&gt;

        &lt;div className=&quot;panel&quot;&gt;
          &lt;h2&gt;Transaction Timeline&lt;/h2&gt;

          {transactions.length === 0 ? (
            &lt;div className=&quot;empty-state&quot;&gt;
              No mutations yet. Drag the slider to start!
            &lt;/div&gt;
          ) : (
            &lt;div className=&quot;transaction-list&quot;&gt;
              {[...transactions].reverse().map((tracked) =&gt; (
                &lt;div
                  key={tracked.id}
                  className={`transaction-card ${tracked.state}`}
                &gt;
                  &lt;div className=&quot;transaction-header&quot;&gt;
                    &lt;span className=&quot;transaction-id&quot;&gt;
                      ID: {tracked.id.slice(0, 8)}
                    &lt;/span&gt;
                    &lt;span className={`transaction-status ${tracked.state}`}&gt;
                      {tracked.state}
                    &lt;/span&gt;
                  &lt;/div&gt;
                  &lt;div className=&quot;transaction-details&quot;&gt;
                    &lt;div&gt;
                      Created:{` `}
                      {new Date(tracked.createdAt).toLocaleTimeString()}
                    &lt;/div&gt;
                    {tracked.executingAt &amp;&amp; (
                      &lt;div&gt;
                        Started Executing:{` `}
                        {new Date(tracked.executingAt).toLocaleTimeString()}
                        {` `}(pending: {tracked.executingAt - tracked.createdAt}
                        ms)
                      &lt;/div&gt;
                    )}
                    {tracked.completedAt &amp;&amp; (
                      &lt;div&gt;
                        Completed:{` `}
                        {new Date(tracked.completedAt).toLocaleTimeString()}
                        {tracked.executingAt &amp;&amp; (
                          &lt;&gt;
                            {` `}(persisting:{` `}
                            {tracked.completedAt - tracked.executingAt}ms)
                          &lt;/&gt;
                        )}
                      &lt;/div&gt;
                    )}
                    {tracked.completedAt &amp;&amp; (
                      &lt;div style={{ fontWeight: `bold`, marginTop: `4px` }}&gt;
                        Total Duration:{` `}
                        {tracked.completedAt - tracked.createdAt}ms
                      &lt;/div&gt;
                    )}
                  &lt;/div&gt;
                  &lt;div className=&quot;transaction-mutations&quot;&gt;
                    &lt;div style={{ fontWeight: `bold`, marginBottom: `4px` }}&gt;
                      Mutations ({tracked.mutations.length}):
                    &lt;/div&gt;
                    {tracked.mutations.map((mut, idx) =&gt; {
                      if (mut.type === `update`) {
                        const item = mut.modified
                        return (
                          &lt;div key={idx} className=&quot;mutation&quot;&gt;
                            &lt;span className=&quot;mutation-type&quot;&gt;{mut.type}&lt;/span&gt;
                            &lt;&gt;: value = {item.value}&lt;/&gt;
                          &lt;/div&gt;
                        )
                      }
                      return (
                        &lt;div key={idx} className=&quot;mutation&quot;&gt;
                          &lt;span className=&quot;mutation-type&quot;&gt;{mut.type}&lt;/span&gt;
                        &lt;/div&gt;
                      )
                    })}
                  &lt;/div&gt;
                &lt;/div&gt;
              ))}
            &lt;/div&gt;
          )}
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  )
}
">
<input type="hidden" name="project[files][src/index.css]" value="* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family:
    -apple-system, BlinkMacSystemFont, &#39;Segoe UI&#39;, &#39;Roboto&#39;, &#39;Oxygen&#39;, &#39;Ubuntu&#39;,
    &#39;Cantarell&#39;, &#39;Fira Sans&#39;, &#39;Droid Sans&#39;, &#39;Helvetica Neue&#39;, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background: #f5f5f5;
  padding: 20px;
}

code {
  font-family:
    source-code-pro, Menlo, Monaco, Consolas, &#39;Courier New&#39;, monospace;
  background: #f0f0f0;
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 0.9em;
}

.app {
  max-width: 1400px;
  margin: 0 auto;
}

h1 {
  margin-bottom: 8px;
  color: #333;
}

.subtitle {
  color: #666;
  margin-bottom: 24px;
  font-size: 14px;
}

.grid {
  display: grid;
  grid-template-columns: 400px 1fr;
  gap: 20px;
  margin-bottom: 20px;
}

.panel {
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.panel h2 {
  margin-bottom: 16px;
  font-size: 18px;
  color: #333;
  border-bottom: 2px solid #e0e0e0;
  padding-bottom: 8px;
}

.control-group {
  margin-bottom: 20px;
}

.control-group label {
  display: block;
  margin-bottom: 6px;
  font-weight: 500;
  color: #555;
  font-size: 14px;
}

.control-group select,
.control-group input[type=&#39;number&#39;] {
  width: 100%;
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

.checkbox-group {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.checkbox-group input[type=&#39;checkbox&#39;] {
  width: 16px;
  height: 16px;
}

.checkbox-group label {
  margin: 0 !important;
  font-weight: normal !important;
}

.action-buttons {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 20px;
}

button {
  padding: 12px 20px;
  border: none;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;
}

.btn-primary {
  background: #007bff;
  color: white;
}

.btn-primary:hover {
  background: #0056b3;
}

.btn-secondary {
  background: #6c757d;
  color: white;
}

.btn-secondary:hover {
  background: #545b62;
}

.btn-danger {
  background: #dc3545;
  color: white;
}

.btn-danger:hover {
  background: #c82333;
}

.transaction-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.transaction-card {
  background: #f8f9fa;
  border-radius: 6px;
  padding: 12px;
  border-left: 4px solid #ccc;
}

.transaction-card.pending {
  border-left-color: #ffc107;
  background: #fff3cd;
}

.transaction-card.executing {
  border-left-color: #17a2b8;
  background: #d1ecf1;
}

.transaction-card.completed {
  border-left-color: #28a745;
  background: #d4edda;
}

.transaction-card.failed {
  border-left-color: #dc3545;
  background: #f8d7da;
}

.transaction-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.transaction-id {
  font-weight: 600;
  font-size: 12px;
  color: #666;
  font-family: monospace;
}

.transaction-status {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
}

.transaction-status.pending {
  background: #ffc107;
  color: #856404;
}

.transaction-status.executing {
  background: #17a2b8;
  color: #0c5460;
}

.transaction-status.completed {
  background: #28a745;
  color: #155724;
}

.transaction-status.failed {
  background: #dc3545;
  color: #721c24;
}

.transaction-details {
  font-size: 13px;
  color: #555;
}

.transaction-mutations {
  margin-top: 8px;
  padding: 8px;
  background: white;
  border-radius: 4px;
  font-size: 12px;
}

.mutation {
  padding: 4px 0;
  border-bottom: 1px solid #eee;
}

.mutation:last-child {
  border-bottom: none;
}

.mutation-type {
  font-weight: 600;
  color: #007bff;
  text-transform: uppercase;
  font-size: 11px;
}

.empty-state {
  text-align: center;
  padding: 40px 20px;
  color: #999;
  font-style: italic;
}

.stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-bottom: 20px;
}

.stat-card {
  background: white;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  text-align: center;
}

.stat-value {
  font-size: 32px;
  font-weight: 700;
  color: #333;
}

.stat-label {
  font-size: 12px;
  color: #666;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-top: 4px;
}
">
<input type="hidden" name="project[files][src/main.tsx]" value="import React from &#39;react&#39;
import ReactDOM from &#39;react-dom/client&#39;
import { App } from &#39;./App&#39;
import &#39;./index.css&#39;

ReactDOM.createRoot(document.getElementById(`root`)!).render(
  &lt;React.StrictMode&gt;
    &lt;App /&gt;
  &lt;/React.StrictMode&gt;,
)
">
<input type="hidden" name="project[description]" value="generated by https://pkg.pr.new">
<input type="hidden" name="project[template]" value="node">
<input type="hidden" name="project[title]" value="@tanstack/db-example-paced-mutations-demo">
</form>
<script>document.getElementById("mainForm").submit();</script>

</body></html>