Skip to content

fix(share): links use only the browser's own Compression Streams; the bundled pure-JS zlib is removed (v0.17.1) - #316

Merged
MerciHanrim merged 1 commit into
mainfrom
fix/share-native-compression
Oct 4, 2026
Merged

MerciHanrim merged 1 commit into
mainfrom
fix/share-native-compression

Conversation

@MerciHanrim

Copy link
Copy Markdown
Owner

Part of #301 — decision 1, the first separate pull request of that issue.

Why

The pure-JS inflate in src/model/share.ts said it was adapted from "tiny inflate (public domain)". tinf is under the zlib licence, not in the public domain, and the repository's own record does not establish where the code came from: the commit that added it cites no source. A notice cannot be listed for code whose origin is unknown, so the fallback is removed instead. The pure-JS deflate written beside it has the same record and goes with it.

Every browser the build targets has the browser's own Compression Streams: Vite's default target is Chrome and Edge 111, Firefox 114 and Safari 16.4, and those streams shipped in Chrome and Edge 80, Firefox 113 and Safari 16.4. The fallback therefore ran only below the build target. Measured here: Chromium 151 on a file:// page has both streams, so the portable file does not use the fallback either.

What changes

  • Making and opening share links use only CompressionStream / DecompressionStream ('deflate', the zlib wrapper), in every build.
  • Making a link on a page without them: nothing is made and nothing is copied. A plain link alerts one sentence; the protected-link dialog says it inline, before any key derivation.
  • Opening a link on a page without them: a #g1= or a #p1= link shows a notice with the same sentence, asks for no password, leaves the working diagram untouched and keeps the fragment in the address bar, so the address opens in another browser. A broken protected link is still reported as damaged first.
  • One new string in all 18 languages: "This browser cannot create or open share links. Try again in a current browser." / "이 브라우저에서는 공유 링크를 만들거나 열 수 없습니다. 최신 브라우저에서 다시 시도하세요."
  • docs/specs/SEMANTICS-U.md is amended in place (U1.3, U6, D2, U11, U12.8, U12.10, new U12.18) and records the change in a new U13. The link format, the size limits, the opening order and the fragment grammar do not change.
  • Release 0.17.1, dated 2026-10-04, declared user-facing, with three release-note lines in all 18 languages: "Share links now use the browser’s built-in compression.", "If that feature is unavailable, Loop Studio keeps your current diagram unchanged and explains that a current browser is required." and "Existing share links remain compatible; the link format has not changed." The release-note rule of three to five lines is unchanged.

Links made by the removed encoder still open

src/model/shareLegacy.fixture.ts holds seven payloads made by the removed encoders as they shipped on main at 938aae3: fixed-Huffman blocks (a 40-node diagram with Hangul, CJK, emoji, Cyrillic and Arabic labels, long runs, literal-heavy text, one byte, empty), stored blocks, and the 18-node risky-factory diagram. The unit test opens every one through the native path and compares the text exactly. The end-to-end tests open the 18-node one as a #g1= link on the hosted build and in the portable file.

Links this build makes open in the previous build

Measured outside the repository, with no server and every other request blocked: the 18-node risky-factory diagram was imported into this build and a #g1= link was made with its Share button. That link was opened in the build of main at 938aae3, each time in a fresh profile, in four ways: the web build and its portable file, each with DecompressionStream and with it removed so that the old build used its own pure-JS inflater. All four opened the same 18 nodes, removed the fragment and wrote no warning. The old fallback code is not added back to the product or its tests.

Verification (local, at the head of this branch)

  • npx tsc -b, oxlint (39 warnings, the existing baseline, 0 errors), 2,964 unit tests, and all 23 check scripts pass.
  • Related end-to-end specs at the final tree (What's new, protected and plain share, portable file): 144 passed, none failed or retried; the production-bundle suite: 15 passed. An earlier run that also covered the mobile spec passed 199 of 199. The full five-shard suite is left to this pull request's CI.
  • New end-to-end tests: without CompressionStream no plain or protected link is made and nothing is copied; without DecompressionStream a plain and a protected link show the notice and keep the fragment; the old-encoder link opens on the hosted build and in the portable file; without CompressionStream the portable file makes no link.
  • A mutation that removes the opening check fails the unit test for the plain link.

Not verified

  • Firefox and WebKit on file://: neither browser is installed here, and they were not downloaded for this change.
  • The versions that first shipped Compression Streams come from public compatibility data and were not measured.
  • The 16 translations other than English and Korean, of the new message and of the release-note line, follow each catalog's existing terms and have had no native review.

Not in this pull request

… bundled pure-JS zlib is removed (v0.17.1)

Part of #301, decision 1. The pure-JS inflate in src/model/share.ts said it
was adapted from "tiny inflate (public domain)". tinf is not public domain, and
the repository's record does not establish where the code came from, so it
could not be listed with a notice. The deflate written beside it has the same
record. Both are removed.

Every browser the build targets (Vite's default: Chrome and Edge 111, Firefox
114, Safari 16.4) has CompressionStream and DecompressionStream, so making and
opening links does not change there. Chromium on a file:// page has both, so
the portable file is unaffected there too.

- src/model/share.ts: the pure-JS inflate, the fixed-Huffman deflate and the
  stored-block wrapper are gone (about 500 lines). shareCompressionAvailable()
  is read at call time; zlibDeflate / zlibInflate throw
  ShareError('unavailable') without the streams.
- Making a link without Compression Streams: prepareShareLink and
  prepareProtectedShareLink return 'no-compression' before any work (for a
  protected link, before the key derivation). The plain path alerts the one
  sentence, the protected dialog says it inline. Nothing is copied.
- Opening a link without Compression Streams: a plain g1 link and a protected
  p1 link both show a notice with the same sentence ("Share link" / "Protected
  link" as the title), ask for no password, leave the working graph untouched
  and KEEP the fragment, so the address opens in another browser. A broken
  protected link is still reported as damaged first.
- One new string, share.unavailable, in all 18 languages. English and Korean
  are Lumi's; the other 16 follow each catalog's existing terms and have had
  no native review.
- Links made by the removed encoder still open: src/model/shareLegacy.fixture.ts
  holds 7 payloads made by those encoders as they shipped on main 938aae3
  (fixed-Huffman and stored blocks, including an 18-node diagram). The unit
  test opens each through the native path; the e2e opens the diagram as a
  #g1= link on the hosted build and in the portable file.
- docs/specs/SEMANTICS-U.md amended in place (U1.3, U6, D2, U11, U12.8,
  U12.10, new U12.18) with a change record (U13). The link format, limits,
  opening order and fragment grammar are unchanged.
- Locale guards: the pinned counts move by the one key (977 to 978, 1199 to
  1200); pt-PT and es-ES declare the new key as a real regional difference.
  No bound is widened.
- Release 0.17.1, dated 2026-10-04, declared user-facing: three release-note
  lines in all 18 languages (the built-in compression; a page without it
  keeps the diagram and says a current browser is required; existing links
  stay compatible and the format is unchanged). English and Korean are
  Lumi's; the other 16 have had no native review. The release-note rule of
  three to five lines is unchanged.
- The other direction holds too, measured outside the repository: a #g1= link
  made through this build's Share button opens the same 18-node document in
  the build of main 938aae3, in fresh profiles, on the web and in its portable
  file, with DecompressionStream and with it removed (the old build's own
  pure-JS inflater).

Not measured: Firefox and WebKit on file:// (not installed here), and the
browser versions that first shipped Compression Streams (known compatibility
data, not measured).
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying cozy-loop-studio with  Cloudflare Pages  Cloudflare Pages

Latest commit: e063545
Status: ✅  Deploy successful!
Preview URL: https://5d1c1650.cozy-loop-studio.pages.dev
Branch Preview URL: https://fix-share-native-compression.cozy-loop-studio.pages.dev

View logs

@MerciHanrim
MerciHanrim merged commit 44af9a4 into main Oct 4, 2026
10 checks passed
@MerciHanrim
MerciHanrim deleted the fix/share-native-compression branch October 4, 2026 11:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant