@tscircuit/fake-snippets 0.0.91 → 0.0.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -387,7 +387,8 @@ var loadPackageWithDependencies = async (db, owner, name, loadedPackages = /* @_
387
387
  ...pkg,
388
388
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
389
389
  updated_at: (/* @__PURE__ */ new Date()).toISOString(),
390
- latest_package_release_id: release.package_release_id
390
+ latest_package_release_id: release.package_release_id,
391
+ star_count: Math.floor(Math.random() * 11)
391
392
  });
392
393
  db.addPackageRelease({
393
394
  ...release,
@@ -118,6 +118,7 @@ const loadPackageWithDependencies = async (
118
118
  created_at: new Date().toISOString(),
119
119
  updated_at: new Date().toISOString(),
120
120
  latest_package_release_id: release.package_release_id,
121
+ star_count: Math.floor(Math.random() * 11),
121
122
  })
122
123
 
123
124
  db.addPackageRelease({
@@ -118,7 +118,6 @@ export default withRouteSpec({
118
118
  prediction: z.string(),
119
119
  }),
120
120
  })(async (req, ctx) => {
121
- return ctx.json({ prediction: "mock" })
122
121
  const openai = getOpenAIClient()
123
122
  const { prefix, suffix, model, language } = req.jsonBody
124
123
 
@@ -24,7 +24,7 @@ export default withRouteSpec({
24
24
  })
25
25
 
26
26
  // Filter out packages with no stars and sort by star count
27
- const trendingPackages = packagesWithStars
27
+ const trendingPackages = ctx.db.packages
28
28
  .filter((p) => p.star_count > 0)
29
29
  .sort((a, b) => b.star_count - a.star_count)
30
30
  .slice(0, 50)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/fake-snippets",
3
- "version": "0.0.91",
3
+ "version": "0.0.92",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -76,25 +76,27 @@ export const CodeEditor = ({
76
76
  showImportAndFormatButtons?: boolean
77
77
  onFileContentChanged?: (path: string, content: string) => void
78
78
  currentFile: string | null
79
- onFileSelect: (path: string) => void
79
+ onFileSelect: (path: string, lineNumber?: number) => void
80
80
  }) => {
81
81
  const editorRef = useRef<HTMLDivElement>(null)
82
82
  const viewRef = useRef<EditorView | null>(null)
83
83
  const ataRef = useRef<ReturnType<typeof setupTypeAcquisition> | null>(null)
84
84
  const lastReceivedTsFileTimeRef = useRef<number>(0)
85
85
  const apiUrl = usePackagesBaseApiUrl()
86
- const codeCompletionApi = useCodeCompletionApi()
87
86
  const [cursorPosition, setCursorPosition] = useState<number | null>(null)
88
87
  const [code, setCode] = useState(files[0]?.content || "")
89
88
  const [fontSize, setFontSize] = useState(14)
90
89
  const [showQuickOpen, setShowQuickOpen] = useState(false)
91
90
  const [showGlobalFindReplace, setShowGlobalFindReplace] = useState(false)
91
+ const [highlightedLine, setHighlightedLine] = useState<number | null>(null)
92
+ const highlightTimeoutRef = useRef<number | null>(null)
92
93
 
93
94
  const { highlighter } = useShikiHighlighter()
94
95
 
95
96
  // Get URL search params for file_path
96
97
  const urlParams = new URLSearchParams(window.location.search)
97
98
  const filePathFromUrl = urlParams.get("file_path")
99
+ const lineNumberFromUrl = urlParams.get("line")
98
100
  const [aiAutocompleteEnabled, setAiAutocompleteEnabled] = useState(false)
99
101
 
100
102
  const entryPointFileName = useMemo(() => {
@@ -109,10 +111,13 @@ export const CodeEditor = ({
109
111
 
110
112
  const targetFile = findTargetFile(files, filePathFromUrl)
111
113
  if (targetFile) {
112
- handleFileChange(targetFile.path)
114
+ const lineNumber = lineNumberFromUrl
115
+ ? parseInt(lineNumberFromUrl, 10)
116
+ : undefined
117
+ handleFileChange(targetFile.path, lineNumber)
113
118
  setCode(targetFile.content)
114
119
  }
115
- }, [filePathFromUrl, pkgFilesLoaded])
120
+ }, [filePathFromUrl, lineNumberFromUrl, pkgFilesLoaded])
116
121
 
117
122
  const fileMap = useMemo(() => {
118
123
  const map: Record<string, string> = {}
@@ -309,6 +314,14 @@ export const CodeEditor = ({
309
314
  ".cm-content": {
310
315
  fontSize: `${fontSize}px`,
311
316
  },
317
+ ".cm-line-highlight": {
318
+ backgroundColor: "#dbeafe !important",
319
+ animation: "lineHighlightFade 3s ease-in-out forwards",
320
+ },
321
+ "@keyframes lineHighlightFade": {
322
+ "0%": { backgroundColor: "#93c5fd" },
323
+ "100%": { backgroundColor: "transparent" },
324
+ },
312
325
  }),
313
326
  EditorView.domEventHandlers({
314
327
  wheel: (event) => {
@@ -325,6 +338,21 @@ export const CodeEditor = ({
325
338
  return false
326
339
  },
327
340
  }),
341
+ EditorView.decorations.of((view) => {
342
+ const decorations = []
343
+ if (highlightedLine) {
344
+ const doc = view.state.doc
345
+ if (highlightedLine >= 1 && highlightedLine <= doc.lines) {
346
+ const line = doc.line(highlightedLine)
347
+ decorations.push(
348
+ Decoration.line({
349
+ class: "cm-line-highlight",
350
+ }).range(line.from),
351
+ )
352
+ }
353
+ }
354
+ return Decoration.set(decorations)
355
+ }),
328
356
  ]
329
357
  if (aiAutocompleteEnabled) {
330
358
  baseExtensions.push(
@@ -546,6 +574,11 @@ export const CodeEditor = ({
546
574
 
547
575
  return () => {
548
576
  view.destroy()
577
+ // Clean up any pending highlight timeout
578
+ if (highlightTimeoutRef.current) {
579
+ window.clearTimeout(highlightTimeoutRef.current)
580
+ highlightTimeoutRef.current = null
581
+ }
549
582
  }
550
583
  }, [
551
584
  !isStreaming,
@@ -555,6 +588,7 @@ export const CodeEditor = ({
555
588
  isSaving,
556
589
  fontSize,
557
590
  aiAutocompleteEnabled,
591
+ highlightedLine,
558
592
  ])
559
593
 
560
594
  const updateCurrentEditorContent = (newContent: string) => {
@@ -574,6 +608,35 @@ export const CodeEditor = ({
574
608
  }
575
609
  }
576
610
 
611
+ const navigateToLine = (lineNumber: number) => {
612
+ if (!viewRef.current) return
613
+
614
+ const view = viewRef.current
615
+ const doc = view.state.doc
616
+
617
+ if (lineNumber < 1 || lineNumber > doc.lines) return
618
+
619
+ if (highlightTimeoutRef.current) {
620
+ window.clearTimeout(highlightTimeoutRef.current)
621
+ highlightTimeoutRef.current = null
622
+ }
623
+
624
+ const line = doc.line(lineNumber)
625
+ const pos = line.from
626
+
627
+ view.dispatch({
628
+ selection: { anchor: pos, head: pos },
629
+ effects: EditorView.scrollIntoView(pos, { y: "center" }),
630
+ })
631
+
632
+ setHighlightedLine(lineNumber)
633
+
634
+ highlightTimeoutRef.current = window.setTimeout(() => {
635
+ setHighlightedLine(null)
636
+ highlightTimeoutRef.current = null
637
+ }, 3000)
638
+ }
639
+
577
640
  const updateEditorToMatchCurrentFile = () => {
578
641
  const currentContent = fileMap[currentFile || ""] || ""
579
642
  updateCurrentEditorContent(currentContent)
@@ -590,14 +653,26 @@ export const CodeEditor = ({
590
653
  }
591
654
  }, [codeImports])
592
655
 
593
- const handleFileChange = (path: string) => {
594
- onFileSelect(path)
656
+ const handleFileChange = (path: string, lineNumber?: number) => {
657
+ onFileSelect(path, lineNumber)
595
658
  try {
596
- // Set url query to file path
659
+ // Set url query to file path and line number
597
660
  const urlParams = new URLSearchParams(window.location.search)
598
661
  urlParams.set("file_path", path)
662
+ if (lineNumber) {
663
+ urlParams.set("line", lineNumber.toString())
664
+ } else {
665
+ urlParams.delete("line")
666
+ }
599
667
  window.history.replaceState(null, "", `?${urlParams.toString()}`)
600
668
  } catch {}
669
+
670
+ // Navigate to line after a short delay to ensure editor is ready
671
+ if (lineNumber) {
672
+ setTimeout(() => {
673
+ navigateToLine(lineNumber)
674
+ }, 100)
675
+ }
601
676
  }
602
677
 
603
678
  const updateFileContent = (path: FileName | null, newContent: string) => {
@@ -656,7 +731,7 @@ export const CodeEditor = ({
656
731
  fileSidebarState={
657
732
  [sidebarOpen, setSidebarOpen] as ReturnType<typeof useState<boolean>>
658
733
  }
659
- onFileSelect={handleFileChange}
734
+ onFileSelect={(path) => handleFileChange(path)}
660
735
  handleCreateFile={handleCreateFile}
661
736
  handleDeleteFile={handleDeleteFile}
662
737
  />
@@ -694,7 +769,7 @@ export const CodeEditor = ({
694
769
  <QuickOpen
695
770
  files={files.filter((f) => !isHiddenFile(f.path))}
696
771
  currentFile={currentFile}
697
- onFileSelect={handleFileChange}
772
+ onFileSelect={(path) => handleFileChange(path)}
698
773
  onClose={() => setShowQuickOpen(false)}
699
774
  />
700
775
  )}
@@ -371,13 +371,6 @@ export default function EditorNav({
371
371
  </Button>
372
372
  </DropdownMenuTrigger>
373
373
  <DropdownMenuContent>
374
- <DropdownMenuItem
375
- className="text-xs"
376
- onClick={() => openupdateDescriptionDialog()}
377
- >
378
- <FilePenLine className="mr-2 h-3 w-3" />
379
- Edit Description
380
- </DropdownMenuItem>
381
374
  <DropdownMenuItem
382
375
  className="text-xs"
383
376
  onClick={() => openViewTsFilesDialog()}
@@ -387,6 +380,13 @@ export default function EditorNav({
387
380
  </DropdownMenuItem>
388
381
  {session?.github_username === pkg.owner_github_username && (
389
382
  <>
383
+ <DropdownMenuItem
384
+ className="text-xs"
385
+ onClick={() => openupdateDescriptionDialog()}
386
+ >
387
+ <FilePenLine className="mr-2 h-3 w-3" />
388
+ Edit Description
389
+ </DropdownMenuItem>
390
390
  <DropdownMenuSub>
391
391
  <DropdownMenuSubTrigger
392
392
  className="text-xs"
@@ -436,15 +436,15 @@ export default function EditorNav({
436
436
  </DropdownMenuItem>
437
437
  </DropdownMenuSubContent>
438
438
  </DropdownMenuSub>
439
- <DropdownMenuItem
440
- className="text-xs text-red-600"
441
- onClick={() => openDeleteDialog()}
442
- >
443
- <Trash2 className="mr-2 h-3 w-3" />
444
- Delete Package
445
- </DropdownMenuItem>
446
439
  </>
447
440
  )}
441
+ <DropdownMenuItem
442
+ className="text-xs text-red-600"
443
+ onClick={() => openDeleteDialog()}
444
+ >
445
+ <Trash2 className="mr-2 h-3 w-3" />
446
+ Delete Package
447
+ </DropdownMenuItem>
448
448
  <DropdownMenuItem className="text-xs text-gray-500" disabled>
449
449
  @tscircuit/core@{tscircuitCorePkg.version}
450
450
  </DropdownMenuItem>
@@ -44,7 +44,7 @@ interface FileMatch {
44
44
  interface GlobalFindReplaceProps {
45
45
  files: PackageFile[]
46
46
  currentFile: string | null
47
- onFileSelect: (path: string) => void
47
+ onFileSelect: (path: string, lineNumber?: number) => void
48
48
  onFileContentChanged?: (path: string, content: string) => void
49
49
  onClose: () => void
50
50
  }
@@ -217,7 +217,7 @@ const GlobalFindReplace = ({
217
217
 
218
218
  const goToMatch = useCallback(
219
219
  (fileMatch: FileMatch, match: Match) => {
220
- onFileSelect(fileMatch.file.path)
220
+ onFileSelect(fileMatch.file.path, match.line)
221
221
  onClose()
222
222
  },
223
223
  [onFileSelect, onClose],