Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 63 additions & 37 deletions src/dataEditor/dataEditorClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,37 @@ export class DataEditorClient implements vscode.Disposable {
})
}

private async runProfile(
sessionId: string,
startOffset: number,
length: number
) {
const byteProfile = await profileSession(sessionId, startOffset, length)
const characterCount = await countCharacters(sessionId, startOffset, length)
const contentType = await getContentType(sessionId, startOffset, length)
const language = await getLanguage(
sessionId,
startOffset,
length,
characterCount.getByteOrderMark()
)

return {
byteProfile,
numAscii: numAscii(byteProfile),
language: language.getLanguage(),
contentType: contentType.getContentType(),
characterCount: {
byteOrderMark: characterCount.getByteOrderMark(),
byteOrderMarkBytes: characterCount.getByteOrderMarkBytes(),
singleByteCount: characterCount.getSingleByteChars(),
doubleByteCount: characterCount.getDoubleByteChars(),
tripleByteCount: characterCount.getTripleByteChars(),
quadByteCount: characterCount.getQuadByteChars(),
invalidBytes: characterCount.getInvalidBytes(),
},
}
}
// handle messages from the webview
private async messageReceiver(message: EditorMessage) {
switch (message.command) {
Expand Down Expand Up @@ -549,53 +580,48 @@ export class DataEditorClient implements vscode.Disposable {
})
break

case MessageCommand.profile:
{
const startOffset: number = message.data.startOffset
const length: number = message.data.length
const byteProfile: number[] = await profileSession(
this.omegaSessionId,
startOffset,
length
)
const characterCount = await countCharacters(
this.omegaSessionId,
startOffset,
length
)
const contentTypeResponse = await getContentType(
this.omegaSessionId,
case MessageCommand.profile: {
const startOffset: number = message.data.startOffset
const length: number = message.data.length
const target: string | undefined = message.data.target

let sessionId = this.omegaSessionId
let isDiskProfile = false

try {
if (target === 'disk') {
const tempSession = await createSession(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling the createSession API function is emitting the following error from Omega Edit server:

rejected promise not handled within 1 second: createSession error: 13 INTERNAL: Failed to create session: ALREADY_EXISTS

I don't currently have a resolution off the top of my head so you may have to read up on the exposed API functions to work around this.

this.fileToEdit,
undefined,
checkpointPath
)
sessionId = tempSession.getSessionId()
addActiveSession(sessionId)
isDiskProfile = true
}

const profileData = await this.runProfile(
sessionId,
startOffset,
length
)
const languageResponse = await getLanguage(
this.omegaSessionId,
startOffset,
length,
characterCount.getByteOrderMark()
)

await this.panel.webview.postMessage({
command: MessageCommand.profile,
data: {
startOffset: startOffset,
length: length,
byteProfile: byteProfile,
numAscii: numAscii(byteProfile),
language: languageResponse.getLanguage(),
contentType: contentTypeResponse.getContentType(),
characterCount: {
byteOrderMark: characterCount.getByteOrderMark(),
byteOrderMarkBytes: characterCount.getByteOrderMarkBytes(),
singleByteCount: characterCount.getSingleByteChars(),
doubleByteCount: characterCount.getDoubleByteChars(),
tripleByteCount: characterCount.getTripleByteChars(),
quadByteCount: characterCount.getQuadByteChars(),
invalidBytes: characterCount.getInvalidBytes(),
},
startOffset,
length,
...profileData,
},
})
} finally {
if (isDiskProfile) {
await removeActiveSession(sessionId)
}
}

break
}

case MessageCommand.clearChanges:
if (
Expand Down
29 changes: 24 additions & 5 deletions src/svelte/src/components/DataMetrics/DataMetrics.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<script lang="ts">
let profileTarget: 'editor' | 'disk' = 'editor'
import Button from '../Inputs/Buttons/Button.svelte'
import { vscode } from '../../utilities/vscode'
import { MessageCommand } from '../../utilities/message'
Expand Down Expand Up @@ -73,7 +74,6 @@ limitations under the License.
let errorMessageTimeout: NodeJS.Timeout | null = null
let asciiOverlay: boolean = true
let logScale: boolean = false

$: {
sum = byteProfile.reduce((a, b) => a + b, 0)
mean = sum / byteProfile.length
Expand Down Expand Up @@ -157,20 +157,27 @@ limitations under the License.
})
}

let lastProfileTarget: 'editor' | 'disk' | null = null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that this variable instance type is used in multiple places it should be extracted to a concrete type definition:

type ProfileTarget = 'editor' | 'disk'

Then change the appropriate variable's types:

  let lastProfileTarget: ProfileTarget | undefined = undefined
  let lastRequestedTarget: ProfileTarget = 'editor'

let lastRequestedTarget: 'editor' | 'disk' = 'editor'
function requestSessionProfile(startOffset: number, length: number) {
lastRequestedTarget = profileTarget
setStatusMessage(
`Profiling bytes from ${startOffset} to ${startOffset + length}...`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove the ... tail of the message. The status message indicates as if the profiler is currently loading something.

0
)
vscode.postMessage({
command: MessageCommand.profile,
data: {
Copy link
Contributor

@stricklandrbls stricklandrbls Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a data object above this postMessage call and deconstruct it into the data property:

  type ProfileMsg = {
    startOffset: number,
    length: number,
    target: ProfileTarget
  }

...

const profileTargetData: ProfileMsg = {
 startOffset,
 length,
 target: profileTarget === 'disk' ? 'disk' : 'editor'
}

vscode.postMessage({
...
   data: {...profileTarget}
}

I'm also unsure as to why the target would be set to undefined if the target was 'editor' since there's only 2 requestable types.

startOffset: startOffset,
length: length,
startOffset,
length,
target: profileTarget === 'disk' ? 'disk' : undefined,
},
})
}

$: if (profileTarget !== lastProfileTarget) {
lastProfileTarget = profileTarget
requestSessionProfile(startOffset, length)
}
function handleInputEnter(e: CustomEvent) {
switch (e.detail.id) {
case 'start-offset-input':
Expand Down Expand Up @@ -283,6 +290,10 @@ limitations under the License.
window.addEventListener('message', (msg) => {
switch (msg.data.command) {
case MessageCommand.profile:
if (msg.data.data?.target && msg.data.data.target !== profileTarget) {
// ignore messages not for the current profile target
break
}
numAscii = msg.data.data.numAscii as number
byteProfile = msg.data.data.byteProfile as number[]
language = msg.data.data.language as string
Expand Down Expand Up @@ -313,11 +324,19 @@ limitations under the License.
}
})
endOffset = startOffset + length
requestSessionProfile(startOffset, length)
})
</script>

<div class="container">
<div class="input-container">
<label>
Profile source:
<select bind:value={profileTarget}>
<option value="editor">Current editor</option>
<option value="disk">On-disk file</option>
</select>
</label>
</div>
{#if title.length > 0}
<div class="header">
<h3>{title}</h3>
Expand Down
Loading