Skip to content

Commit 46c26c6

Browse files
committed
fix(search): log clipboard copy failures and make fuzzy positions read-only
- Copy workflow link now logs on clipboard write failure instead of silently swallowing the error, matching the sidebar's copy-link convention. - FuzzyResult.positions is now readonly and the NO_MATCH singleton's array is frozen, so the shared instance can never be mutated by a caller.
1 parent af30525 commit 46c26c6

3 files changed

Lines changed: 15 additions & 5 deletions

File tree

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/search-modal/components/command-items/command-items.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ interface Segment {
1616
hit: boolean
1717
}
1818

19-
function buildSegments(text: string, positions: number[]): Segment[] {
19+
function buildSegments(text: string, positions: readonly number[]): Segment[] {
2020
const hits = new Set(positions)
2121
const segments: Segment[] = []
2222
for (let i = 0; i < text.length; i++) {

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/search-modal/search-modal.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use client'
22

33
import { useCallback, useDeferredValue, useEffect, useMemo, useRef, useState } from 'react'
4+
import { createLogger } from '@sim/logger'
45
import { Command } from 'cmdk'
56
import { useParams, useRouter } from 'next/navigation'
67
import { useTheme } from 'next-themes'
@@ -72,6 +73,8 @@ import type {
7273
} from './utils'
7374
import { filterAndSort } from './utils'
7475

76+
const logger = createLogger('SearchModal')
77+
7578
export type { SearchModalProps } from './utils'
7679

7780
export function SearchModal({
@@ -257,7 +260,9 @@ export function SearchModal({
257260
icon: Link,
258261
context: 'workflow',
259262
run: () => {
260-
navigator.clipboard.writeText(window.location.href).catch(() => {})
263+
navigator.clipboard.writeText(window.location.href).catch((error) => {
264+
logger.error('Failed to copy workflow link to clipboard', { error })
265+
})
261266
},
262267
})
263268
list.push({

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/search-modal/utils.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,16 @@ export interface FuzzyResult {
112112
matched: boolean
113113
/** Relative ranking score; higher sorts first. Only meaningful when matched. */
114114
score: number
115-
/** Indices into the candidate string that matched, ascending. */
116-
positions: number[]
115+
/** Indices into the candidate string that matched, ascending. Read-only. */
116+
positions: readonly number[]
117117
}
118118

119-
const NO_MATCH: FuzzyResult = { matched: false, score: 0, positions: [] }
119+
/**
120+
* Shared singleton for the no-match case. The frozen empty array makes the
121+
* read-only contract explicit and guarantees the shared instance can never be
122+
* mutated by a caller.
123+
*/
124+
const NO_MATCH: FuzzyResult = { matched: false, score: 0, positions: Object.freeze([]) }
120125

121126
function isCamelBoundary(text: string, index: number): boolean {
122127
if (index === 0) return false

0 commit comments

Comments
 (0)