From ab2201b153ad1e1a936bb6c372831cf761d6a294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Gonz=C3=A1lez=20Viegas?= Date: Sat, 27 Jun 2026 17:20:59 +0200 Subject: [PATCH 1/3] feat(client): add getHiddenFileSignedUrl for ranged streaming Adds EngineServicesClient.getHiddenFileSignedUrl(hiddenId, expiresIn?), which returns a short-lived signed URL ({ url, expiresAt }) for a hidden file. This lets the browser fetch large hidden files directly with native HTTP Range requests (e.g. streaming a point cloud's octree.bin) instead of downloading the whole object. Re-call to refresh the URL when it nears expiry. Co-Authored-By: Claude Opus 4.8 --- src/core/client.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/core/client.ts b/src/core/client.ts index a08883f..a7dca4a 100644 --- a/src/core/client.ts +++ b/src/core/client.ts @@ -1257,6 +1257,31 @@ export class EngineServicesClient { ); } + /** + * Mints a short-lived presigned URL for a hidden file so the browser can + * stream it directly from storage with native HTTP `Range` requests (e.g. a + * point-cloud `octree.bin`), instead of proxying the whole object through the + * API. Re-call to re-mint when the URL nears/passes `expiresAt`; coalesce + * concurrent re-mints into a single in-flight call. + * + * The storage bucket's CORS must allow the `Range` request header and expose + * `Content-Range`, `Accept-Ranges` and `Content-Length` for the ranged fetch + * to succeed cross-origin. + * + * @param hiddenId - The hidden file's unique identifier. + * @param expiresIn - Desired URL lifetime in seconds (60–3600). Defaults to + * 900 (15 min) server-side; values are clamped to that range. + * @returns `{ url, expiresAt }` — `url` is the presigned GET URL, `expiresAt` + * an ISO timestamp when it stops working. + */ + async getHiddenFileSignedUrl(hiddenId: string, expiresIn?: number) { + return await this.#requestApi<{ url: string; expiresAt: string }>( + 'GET', + `${ITEM_PATH}/${HIDDEN_PATH}/${hiddenId}/signed-url`, + { ...(expiresIn != null && { query: { expiresIn } }) }, + ); + } + /** * Lists all hidden files attached to a parent item. * @param parentFileId - The parent item's unique identifier. From 9ae13fcfe125530939b389d001151faa2e78e4d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Gonz=C3=A1lez=20Viegas?= Date: Mon, 29 Jun 2026 13:46:10 +0200 Subject: [PATCH 2/3] chore(release): @thatopen/services 0.3.6 Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9abb790..f5cdcd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # thatopen-services +## 0.3.6 + +### Patch Changes + +- Add `getHiddenFileSignedUrl(hiddenId, expiresIn?)` to the client — returns a short-lived signed URL so large hidden files (e.g. a point cloud's `octree.bin`) can be fetched directly with native HTTP `Range` requests instead of downloading the whole object. + ## 0.2.0 ### Minor Changes diff --git a/package.json b/package.json index 5bad919..7567eb1 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "access": "public" }, "private": false, - "version": "0.3.5", + "version": "0.3.6", "main": "dist/index.cjs.js", "module": "dist/index.es.js", "types": "dist/index.d.ts", From 02bef59bb484de20e71fd428124aaa5907ba1358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Gonz=C3=A1lez=20Viegas?= Date: Mon, 29 Jun 2026 18:13:35 +0200 Subject: [PATCH 3/3] fix: sync yarn.lock with the three >=0.182.0 range MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit package.json declares three (dep + peer) as >=0.182.0, but the committed lockfile was keyed three@^0.182.0 at 0.182.0 — a pre-existing mismatch that makes `yarn install --frozen-lockfile` fail on CI. Regenerates the lockfile so the key matches and three resolves to 0.185.0 (latest satisfying the range). three is a peer dep, so this only affects the repo's own build/test, not consumers. tsc stays green. Co-Authored-By: Claude Opus 4.8 --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index e938324..5243c67 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3026,10 +3026,10 @@ three-mesh-bvh@0.9.9: resolved "https://registry.yarnpkg.com/three-mesh-bvh/-/three-mesh-bvh-0.9.9.tgz#273be4a3d4a4a287e6be2d947237e47657f84183" integrity sha512-FJKitcjvbALmeQRK+Sc+nLGorCpkrZBrbgJZFzhdyWboak37DZikn46hvQkNqSbJPm227ahYmS6k3N/GXaAyXw== -three@^0.182.0: - version "0.182.0" - resolved "https://registry.npmjs.org/three/-/three-0.182.0.tgz" - integrity sha512-GbHabT+Irv+ihI1/f5kIIsZ+Ef9Sl5A1Y7imvS5RQjWgtTPfPnZ43JmlYI7NtCRDK9zir20lQpfg8/9Yd02OvQ== +three@>=0.182.0: + version "0.185.0" + resolved "https://registry.yarnpkg.com/three/-/three-0.185.0.tgz#1b60dc42a042712a79961b2a654617fd6bb2503b" + integrity sha512-+yRrcRO2iZa8uzvNNl0d7cL4huhgKgBvVJ0njcTe8xFqZ6DMAFZdCKDP91SEAuj25bNAj7k1QQdf+srZywVK6w== tinybench@^2.9.0: version "2.9.0"