MyFSIO v0.2.6 Release #18

Merged
kqjy merged 14 commits from next into main 2026-02-05 16:18:04 +00:00
3 changed files with 44 additions and 6 deletions
Showing only changes of commit 0f750b9d89 - Show all commits

View File

@@ -36,10 +36,11 @@ class GzipMiddleware:
content_type = None
content_length = None
should_compress = False
is_streaming = False
exc_info_holder = [None]
def custom_start_response(status: str, headers: List[Tuple[str, str]], exc_info=None):
nonlocal response_started, status_code, response_headers, content_type, content_length, should_compress
nonlocal response_started, status_code, response_headers, content_type, content_length, should_compress, is_streaming
response_started = True
status_code = int(status.split(' ', 1)[0])
response_headers = list(headers)
@@ -54,6 +55,9 @@ class GzipMiddleware:
elif name_lower == 'content-encoding':
should_compress = False
return start_response(status, headers, exc_info)
elif name_lower == 'x-stream-response':
is_streaming = True
return start_response(status, headers, exc_info)
if content_type and content_type in COMPRESSIBLE_MIMES:
if content_length is None or content_length >= self.min_size:
@@ -61,7 +65,12 @@ class GzipMiddleware:
return None
response_body = b''.join(self.app(environ, custom_start_response))
app_iter = self.app(environ, custom_start_response)
if is_streaming:
return app_iter
response_body = b''.join(app_iter)
if not response_started:
return [response_body]

View File

@@ -711,6 +711,7 @@ def stream_bucket_objects(bucket_name: str):
headers={
'Cache-Control': 'no-cache',
'X-Accel-Buffering': 'no',
'X-Stream-Response': 'true',
}
)

View File

@@ -182,6 +182,9 @@
let visibleItems = [];
let renderedRange = { start: 0, end: 0 };
let memoizedVisibleItems = null;
let memoizedInputs = { objectCount: -1, prefix: null, filterTerm: null };
const createObjectRow = (obj, displayKey = null) => {
const tr = document.createElement('tr');
tr.dataset.objectRow = '';
@@ -340,7 +343,21 @@
}
};
const computeVisibleItems = () => {
const computeVisibleItems = (forceRecompute = false) => {
const currentInputs = {
objectCount: allObjects.length,
prefix: currentPrefix,
filterTerm: currentFilterTerm
};
if (!forceRecompute &&
memoizedVisibleItems !== null &&
memoizedInputs.objectCount === currentInputs.objectCount &&
memoizedInputs.prefix === currentInputs.prefix &&
memoizedInputs.filterTerm === currentInputs.filterTerm) {
return memoizedVisibleItems;
}
const items = [];
const folders = new Set();
@@ -381,6 +398,8 @@
return aKey.localeCompare(bKey);
});
memoizedVisibleItems = items;
memoizedInputs = currentInputs;
return items;
};
@@ -533,6 +552,8 @@
loadedObjectCount = 0;
totalObjectCount = 0;
allObjects = [];
memoizedVisibleItems = null;
memoizedInputs = { objectCount: -1, prefix: null, filterTerm: null };
pendingStreamObjects = [];
streamAbortController = new AbortController();
@@ -643,6 +664,8 @@
loadedObjectCount = 0;
totalObjectCount = 0;
allObjects = [];
memoizedVisibleItems = null;
memoizedInputs = { objectCount: -1, prefix: null, filterTerm: null };
}
if (append && loadMoreSpinner) {
@@ -985,13 +1008,15 @@
};
const navigateToFolder = (prefix) => {
if (streamAbortController) {
streamAbortController.abort();
streamAbortController = null;
}
currentPrefix = prefix;
if (scrollContainer) scrollContainer.scrollTop = 0;
refreshVirtualList();
renderBreadcrumb(prefix);
selectedRows.clear();
if (typeof updateBulkDeleteState === 'function') {
@@ -1001,6 +1026,9 @@
if (previewPanel) previewPanel.classList.add('d-none');
if (previewEmpty) previewEmpty.classList.remove('d-none');
activeRow = null;
isLoadingObjects = false;
loadObjects(false);
};
const renderObjectsView = () => {