Skip to content

Commit

Permalink
feature: support gzipped rdoc
Browse files Browse the repository at this point in the history
For dynamic mode, even if the rdoc is gzipped, parsing it can result in
a big performance hit. For example if a user load a 1MB gzipped archive,
which then decompresses into a >70MB JSON object, this can result in
slower parsing. We need to think about how to streamline large rdocs.

This commit adds a restriction on the number of matches to show in
dynamic mode (maxMatches = 1)
  • Loading branch information
fariss committed Aug 1, 2024
1 parent 9107819 commit 8e9eadf
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 146 deletions.
6 changes: 6 additions & 0 deletions webui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions webui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"dependencies": {
"@highlightjs/vue-plugin": "^2.1.0",
"@primevue/themes": "^4.0.0-rc.2",
"pako": "^2.1.0",
"plotly.js-dist": "^2.34.0",
"primeflex": "^3.3.1",
"primeicons": "^7.0.0",
Expand Down
10 changes: 3 additions & 7 deletions webui/src/components/UploadOptions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<FileUpload
mode="basic"
name="model[]"
accept="application/json"
:max-file-size="100000000"
accept=".json,.gz"
:max-file-size="10000000"
:auto="true"
:custom-upload="true"
choose-label="Upload from local"
Expand All @@ -27,11 +27,7 @@
<InputText id="url" type="text" v-model="loadURL" />
<label for="url">Load from URL</label>
</FloatLabel>
<Button
icon="pi pi-arrow-right"
@click="$emit('load-from-url', loadURL)"
:disabled="!loadURL"
/>
<Button icon="pi pi-arrow-right" @click="$emit('load-from-url', loadURL)" :disabled="!loadURL" />
</div>

<Divider layout="vertical" class="hidden-mobile">
Expand Down
12 changes: 3 additions & 9 deletions webui/src/composables/useRdocLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ export function useRdocLoader() {
const checkVersion = (rdoc) => {
const version = rdoc.meta.version
if (version < MIN_SUPPORTED_VERSION) {
console.error(
`Version ${version} is not supported. Please use version ${MIN_SUPPORTED_VERSION} or higher.`
)
console.error(`Version ${version} is not supported. Please use version ${MIN_SUPPORTED_VERSION} or higher.`)
toast.add({
severity: 'error',
summary: 'Unsupported Version',
Expand All @@ -41,11 +39,7 @@ export function useRdocLoader() {
try {
let data

if (source instanceof File) {
// Load from File
const text = await source.text()
data = JSON.parse(text)
} else if (typeof source === 'string') {
if (typeof source === 'string') {
// Load from URL
const response = await fetch(source)
if (!response.ok) {
Expand Down Expand Up @@ -78,7 +72,7 @@ export function useRdocLoader() {
toast.add({
severity: 'error',
summary: 'Error',
detail: error.message,
detail: "Failed to process the file. Please ensure it's a valid JSON or gzipped JSON file.",
life: 3000,
group: 'bc' // bottom-center
})
Expand Down
38 changes: 38 additions & 0 deletions webui/src/utils/fileUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import pako from 'pako'

/**
* Checks if the given file is gzipped
* @param {File} file - The file to check
* @returns {Promise<boolean>} - True if the file is gzipped, false otherwise
*/
export const isGzipped = async (file) => {
const arrayBuffer = await file.arrayBuffer()
const uint8Array = new Uint8Array(arrayBuffer)
return uint8Array[0] === 0x1f && uint8Array[1] === 0x8b
}

/**
* Decompresses a gzipped file
* @param {File} file - The gzipped file to decompress
* @returns {Promise<string>} - The decompressed file content as a string
*/
export const decompressGzip = async (file) => {
const arrayBuffer = await file.arrayBuffer()
const uint8Array = new Uint8Array(arrayBuffer)
const decompressed = pako.inflate(uint8Array, { to: 'string' })
return decompressed
}

/**
* Reads a file as text
* @param {File} file - The file to read
* @returns {Promise<string>} - The file content as a string
*/
export const readFileAsText = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = (event) => resolve(event.target.result)
reader.onerror = (error) => reject(error)
reader.readAsText(file)
})
}
Loading

0 comments on commit 8e9eadf

Please sign in to comment.