Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
8b0e1e6
feat(web): virtualize large file previews
maria-rcks Oct 19, 2026
907526b
fix(web): reduce large file preview startup work
maria-rcks Oct 19, 2026
ed77dfa
chore: merge office file preview base
maria-rcks Oct 20, 2026
eed1efa
chore: merge t3/office-file-previews
maria-rcks Oct 20, 2026
d9ce5f9
fix(web): recover large file previews and incomplete pages
maria-rcks Oct 20, 2026
b2bfd08
fix(web): preserve large file line reveals and indexed pages
maria-rcks Oct 20, 2026
8f62604
fix(web): scroll through a single tall preview row
maria-rcks Oct 20, 2026
cb56109
fix(web): keep native scrolling for short row tracks
maria-rcks Oct 20, 2026
0bc4d78
fix(web): scroll through all trailing wrapped rows
maria-rcks Oct 20, 2026
36093f3
chore: merge t3/office-file-previews
maria-rcks Oct 20, 2026
172042b
chore: merge t3/office-file-previews
maria-rcks Oct 20, 2026
f7b426c
fix(web): bound worksheet targets and recover large previews
maria-rcks Oct 20, 2026
91bbede
fix(web): refresh streamed workspace files without empty fallbacks
maria-rcks Oct 20, 2026
941c594
fix(web): include worksheet parser dependency notices
maria-rcks Oct 20, 2026
c4be2f2
chore: merge office previews into large file previews
maria-rcks Oct 21, 2026
210c7d9
test(web): allow empty previews to finish worker startup
maria-rcks Oct 21, 2026
4ea87f3
chore: merge office previews
maria-rcks Oct 21, 2026
de18577
chore: merge lazy office previews into large file previews
maria-rcks Oct 21, 2026
f84bcc2
chore: merge inline audio pills
maria-rcks Oct 21, 2026
d495266
fix(web): merge audio duration readiness into large file previews
maria-rcks Oct 21, 2026
fc310ef
fix(web): improve large file table readability and metadata
maria-rcks Oct 25, 2026
38667e7
fix(web): merge office engines into large file previews
maria-rcks Oct 25, 2026
4e0cf34
chore: merge office preview fixes
maria-rcks Oct 25, 2026
fd2a19e
chore: merge office CI refresh
maria-rcks Oct 25, 2026
230e400
fix(web): preserve file position as indexing grows
maria-rcks Oct 25, 2026
3506f60
chore: merge office review fixes
maria-rcks Oct 25, 2026
3806c95
chore: merge office metadata fixes
maria-rcks Oct 25, 2026
ea11e45
fix(web): wait for wrapped file tails before ending scroll
maria-rcks Oct 25, 2026
e7ad7ef
chore: merge t3/office-file-previews
maria-rcks Oct 25, 2026
75d3153
chore: merge t3/office-file-previews
maria-rcks Oct 25, 2026
ab678ed
chore: merge t3/office-file-previews
maria-rcks Oct 25, 2026
790ed91
fix(web): preserve mixed-height rows as indexing grows
maria-rcks Oct 25, 2026
cc90119
style(web): format the scroll offset regression
maria-rcks Oct 25, 2026
3c12c1c
chore: merge t3/office-file-previews
maria-rcks Oct 25, 2026
37ad08b
chore: merge t3/office-file-previews
maria-rcks Oct 25, 2026
bd32a88
chore: merge Office preview fixes
maria-rcks Oct 25, 2026
2093ff5
chore: merge Office preview fixes
maria-rcks Oct 25, 2026
e1b69fb
chore: merge latest Office base
maria-rcks Oct 25, 2026
e99a8f7
chore: retain mobile audio compatibility
maria-rcks Oct 25, 2026
aea3eda
chore: merge office preview base
maria-rcks Oct 25, 2026
94ab34e
Merge branch 't3/office-file-previews' into t3/large-file-previews
maria-rcks Oct 25, 2026
d401a33
chore: merge office preview updates
maria-rcks Oct 25, 2026
d359115
fix(web): preserve unchanged large file previews
maria-rcks Oct 25, 2026
7ba6c39
fix(web): retry failed large file authorization
maria-rcks Oct 25, 2026
f9f91a3
chore: merge office previews into large file previews
maria-rcks Oct 26, 2026
7bf6099
chore(web): large file viewer effects state their reasons
maria-rcks Oct 26, 2026
850ccff
chore: merge current office preview base into large file previews
maria-rcks Oct 26, 2026
cacc99c
style(web): table preview layout uses tailwind classes
maria-rcks Oct 26, 2026
221302d
fix(web): failed copies no longer block the next copy in large text f…
maria-rcks Oct 26, 2026
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
3 changes: 2 additions & 1 deletion apps/server/src/assets/AssetAccess.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,7 @@ describe("AssetAccess", () => {
}).pipe(Effect.provide(layerTest)),
);

it.effect("issues exact workspace URLs for image, office, and font previews", () =>
it.effect("issues exact workspace URLs for every non-HTML preview", () =>
Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
Expand All @@ -1009,6 +1009,7 @@ describe("AssetAccess", () => {
"private document",
);
for (const extension of [
"pdf",
"png",
"bmp",
"heic",
Expand Down
36 changes: 15 additions & 21 deletions apps/server/src/assets/AssetAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ import {
} from "@t3tools/contracts";
import {
hostPreviewMimeTypeFromExtension,
officePreviewKind,
isWorkspaceAudioPreviewPath,
isWorkspaceImagePreviewPath,
isWorkspaceFontPreviewPath,
isWorkspacePreviewEntryPath,
isWorkspaceVideoPreviewPath,
WORKSPACE_BROWSER_PREVIEW_EXTENSIONS,
Expand Down Expand Up @@ -517,24 +514,21 @@ const finalizeWorkspaceFileAsset = Effect.fn("AssetAccess.finalizeWorkspaceFileA
? yield* readImageDimensionsFromHeader(canonicalFile)
: null;
return {
claims:
isWorkspaceImagePreviewPath(resolved.relativePath) ||
isWorkspaceFontPreviewPath(resolved.relativePath) ||
officePreviewKind({ name: resolved.relativePath }) !== null
? {
version: 1 as const,
kind: "workspace-file-exact" as const,
workspaceRoot: canonicalWorkspaceRoot,
relativePath: resolved.relativePath,
expiresAt: input.expiresAt,
}
: {
version: 1 as const,
kind: "workspace-file" as const,
workspaceRoot: canonicalWorkspaceRoot,
baseRelativePath: path.dirname(resolved.relativePath),
expiresAt: input.expiresAt,
},
claims: !/\.html?$/i.test(resolved.relativePath)
? {
version: 1 as const,
kind: "workspace-file-exact" as const,
workspaceRoot: canonicalWorkspaceRoot,
relativePath: resolved.relativePath,
expiresAt: input.expiresAt,
}
: {
version: 1 as const,
kind: "workspace-file" as const,
workspaceRoot: canonicalWorkspaceRoot,
baseRelativePath: path.dirname(resolved.relativePath),
expiresAt: input.expiresAt,
},
fileName: path.basename(resolved.relativePath),
imageDimensions,
fileRevision: undefined,
Expand Down
19 changes: 16 additions & 3 deletions apps/server/src/http.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -630,9 +630,22 @@ describe("video asset byte ranges", () => {
const image = HttpServerResponse.toWeb(
yield* assetFileResponse({ path: file, mimeType: "image/png" }, "bytes=0-1"),
);
expect(image.status).toBe(200);
expect(image.headers.has("accept-ranges")).toBe(false);
expect(yield* Effect.promise(() => image.text())).toBe("0123456789");
expect(image.status).toBe(206);
expect(image.headers.get("accept-ranges")).toBe("bytes");
expect(yield* Effect.promise(() => image.text())).toBe("01");
for (const mimeType of ["text/plain", "text/csv", "application/octet-stream"]) {
for (const [range, expected, status] of [
["bytes=2-5", "2345", 206],
["bytes=-3", "789", 206],
["bytes=10-", "", 416],
] as const) {
const result = HttpServerResponse.toWeb(
yield* assetFileResponse({ path: file, mimeType }, range),
);
expect(result.status).toBe(status);
expect(yield* Effect.promise(() => result.text())).toBe(expected);
}
}
}).pipe(Effect.provide(layerFileResponse)),
);

Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export const assetFileResponse = Effect.fn("assetFileResponse")(function* (
let status = 200;
let offset = 0n;
let bytesToRead: bigint | undefined;
if (isMedia) {
{
headers["Accept-Ranges"] = "bytes";
// If-Range requires a matching validator. A full response is safe when we cannot validate it.
if (method === "GET" && rangeHeader && ifRangeHeader === undefined) {
Expand Down
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"culori": "^4.0.2",
"dompurify": "^3.4.16",
"effect": "catalog:",
"fast-xml-parser": "5.7.3",
"hast-util-to-html": "^9.0.5",
"hast-util-to-jsx-runtime": "^2.3.6",
"heic-to": "^1.5.2",
Expand Down
Loading
Loading