From a1c0bdeaca4fc934d071831e185d9db71dffa71f Mon Sep 17 00:00:00 2001 From: Dominik Simonik Date: Thu, 12 Mar 2026 09:15:20 +0100 Subject: [PATCH 1/6] fix: use AssetManifest.bin, remove deprecated canvaskit and serviceWorkerSettings - Parse AssetManifest.bin (Standard Message Codec) instead of deprecated AssetManifest.json - Remove canvaskit brick variable and preloading - Replace deprecated serviceWorkerSettings with flutter_build_config - Update to Dart 3.5+ and latest dependencies --- .github/cspell.json | 1 - README.md | 1 - __brick__/web/flutter_bootstrap.js | 60 +++++++++++++++++++++--------- brick.yaml | 7 +--- hooks/analysis_options.yaml | 2 +- hooks/pubspec.yaml | 12 +++--- 6 files changed, 51 insertions(+), 32 deletions(-) diff --git a/.github/cspell.json b/.github/cspell.json index 22dadf7..0bcf820 100644 --- a/.github/cspell.json +++ b/.github/cspell.json @@ -19,7 +19,6 @@ ], "useGitignore": true, "words": [ - "canvaskit", "Brickhub" ] } diff --git a/README.md b/README.md index ea1f219..184c9a6 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,6 @@ to the user. | `project_title` | The title of the project | `name` attribute in the `pubspec.yaml` | | `project_description` | The project description | `description` attribute in the `pubspec.yaml` | | `batch_size` | How many assets will be loaded at the same time | `20` | -| `canvaskit` | If the app uses `canvaskit` mode or not | `true` | ## FAQ diff --git a/__brick__/web/flutter_bootstrap.js b/__brick__/web/flutter_bootstrap.js index 8b15a18..2d216f6 100644 --- a/__brick__/web/flutter_bootstrap.js +++ b/__brick__/web/flutter_bootstrap.js @@ -2,18 +2,48 @@ {{=<% %>=}}{{flutter_js}}<%={{ }}=%> {{=<% %>=}}{{flutter_build_config}}<%={{ }}=%> -const progressBar = document.querySelector('#progress-bar'); const progressText = document.querySelector('#progress-text'); const progressIndicator = document.querySelector('#progress-indicator'); async function readAssets() { - // NOTE: AssetManifest.json will be deprecated in favour of AssetManifest.bin: - // https://github.com/VeryGoodOpenSource/flutter_web_preloader/issues/28 - const response = await fetch('assets/AssetManifest.json'); - const manifest = await response.json(); - const assets = Object.values(manifest) - .map((list) => list.map((url) => 'assets/' + url)) - .reduce((arr, curr) => [...arr, ...curr], []); + // AssetManifest.bin is encoded with Flutter's Standard Message Codec. + // See: https://docs.flutter.dev/platform-integration/web/initialization + const response = await fetch('assets/AssetManifest.bin'); + const buffer = await response.arrayBuffer(); + const view = new DataView(buffer); + let o = 0; + + const readByte = () => view.getUint8(o++); + const readSize = () => { + const b = readByte(); + if (b < 254) return b; + if (b === 254) { const s = view.getUint16(o, true); o += 2; return s; } + const s = view.getUint32(o, true); o += 4; return s; + }; + const readString = () => { + const n = readSize(); + const s = new TextDecoder().decode(new Uint8Array(buffer, o, n)); + o += n; + return s; + }; + const skip = () => { + const t = readByte(); + if (t <= 2) return; + if (t === 7 || t === 8) { const n = readSize(); o += n; return; } + if (t === 12) { for (let i = readSize(); i > 0; i--) skip(); return; } + if (t === 13) { for (let i = readSize() * 2; i > 0; i--) skip(); } + }; + + // The manifest is a map; we only need its keys (the asset paths). + readByte(); // type 13 (map) + const count = readSize(); + const assets = []; + for (let i = 0; i < count; i++) { + readByte(); // type 7 (string) + const path = readString(); + if (!path.startsWith('packages/')) assets.push(path); + skip(); + } return assets; } @@ -64,21 +94,17 @@ async function load(url) { } async function loadBatch(urls) { - const loadPromises = urls.map(async (url) => { - await load(url); - reportProgress(); - }); try { - return await Promise.all(loadPromises); + await Promise.all(urls.map(async (url) => { + await load(url); + reportProgress(); + })); } catch (error) { - console.error('Error loading one or more asset:', error); + console.error('Error loading asset:', error); } } _flutter.loader.load({ - serviceWorkerSettings: { - serviceWorkerVersion: {{=<% %>=}}{{flutter_service_worker_version}}<%={{ }}=%>, - }, onEntrypointLoaded: async function(engineInitializer) { await Promise.all([ beginPreloading(), diff --git a/brick.yaml b/brick.yaml index 6c5e727..731b44f 100644 --- a/brick.yaml +++ b/brick.yaml @@ -1,7 +1,7 @@ name: flutter_web_preloader description: A brick that creates a smart web entry point for Flutter that preloads its assets before starting the app. repository: https://github.com/VeryGoodOpenSource/flutter_web_preloader -version: 0.4.0 +version: 0.5.0 environment: mason: ">=0.1.1 <0.2.0" @@ -22,8 +22,3 @@ vars: description: The number of concurrent loads that the preload will trigger. default: 20 prompt: Pre load batch size (defaults to 20)? - canvaskit: - type: boolean - description: If the project should pre load canvaskit. - default: true - prompt: Pre load canvas kit (defaults to true)? diff --git a/hooks/analysis_options.yaml b/hooks/analysis_options.yaml index 799268d..f1e567c 100644 --- a/hooks/analysis_options.yaml +++ b/hooks/analysis_options.yaml @@ -1 +1 @@ -include: package:very_good_analysis/analysis_options.5.1.0.yaml +include: package:very_good_analysis/analysis_options.10.0.0.yaml diff --git a/hooks/pubspec.yaml b/hooks/pubspec.yaml index 34551a8..751fa9a 100644 --- a/hooks/pubspec.yaml +++ b/hooks/pubspec.yaml @@ -1,13 +1,13 @@ name: flutter_web_preloader_hooks environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=3.5.0 <4.0.0" dependencies: - mason: ^0.1.1 - yaml: ^3.1.1 + mason: ^0.1.2 + yaml: ^3.1.2 dev_dependencies: - mocktail: ^1.0.0 - test: ^1.22.2 - very_good_analysis: ^5.1.0 + mocktail: ^1.0.4 + test: ^1.25.8 + very_good_analysis: ^10.0.0 From 55649c8c0625e5e1885ecd0ded048107dc81b21d Mon Sep 17 00:00:00 2001 From: Dominik Simonik Date: Thu, 12 Mar 2026 09:17:05 +0100 Subject: [PATCH 2/6] fix: revert brick version bump --- brick.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brick.yaml b/brick.yaml index 731b44f..4037fca 100644 --- a/brick.yaml +++ b/brick.yaml @@ -1,7 +1,7 @@ name: flutter_web_preloader description: A brick that creates a smart web entry point for Flutter that preloads its assets before starting the app. repository: https://github.com/VeryGoodOpenSource/flutter_web_preloader -version: 0.5.0 +version: 0.4.0 environment: mason: ">=0.1.1 <0.2.0" From 336f0d842f5710030552a6582d1160949a7538ef Mon Sep 17 00:00:00 2001 From: Dominik Simonik Date: Thu, 12 Mar 2026 09:17:31 +0100 Subject: [PATCH 3/6] fix: revert load promises --- __brick__/web/flutter_bootstrap.js | 32 ++++++++++++++++-------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/__brick__/web/flutter_bootstrap.js b/__brick__/web/flutter_bootstrap.js index 2d216f6..c5c968a 100644 --- a/__brick__/web/flutter_bootstrap.js +++ b/__brick__/web/flutter_bootstrap.js @@ -1,6 +1,6 @@ "use strict"; -{{=<% %>=}}{{flutter_js}}<%={{ }}=%> -{{=<% %>=}}{{flutter_build_config}}<%={{ }}=%> +{ {=<% %>=} } { { flutter_js } }<%={ { } }=%> + {{=<% %>=}}{ { flutter_build_config } }<%={ { } }=%> const progressText = document.querySelector('#progress-text'); const progressIndicator = document.querySelector('#progress-indicator'); @@ -59,15 +59,16 @@ async function beginPreloading() { return; } - const batchSize = {{batch_size}}; + const batchSize = {{ batch_size } +}; - progressIndicator.style.width = '0%'; - progressText.textContent = `Loaded ${loadedAssets} of ${totalAssets} assets`; +progressIndicator.style.width = '0%'; +progressText.textContent = `Loaded ${loadedAssets} of ${totalAssets} assets`; - for (let i = 0; i < assets.length; i += batchSize) { - const batch = assets.slice(i, i + batchSize); - await loadBatch(batch); - } +for (let i = 0; i < assets.length; i += batchSize) { + const batch = assets.slice(i, i + batchSize); + await loadBatch(batch); +} } function reportProgress() { @@ -94,18 +95,19 @@ async function load(url) { } async function loadBatch(urls) { + const loadPromises = urls.map(async (url) => { + await load(url); + reportProgress(); + }); try { - await Promise.all(urls.map(async (url) => { - await load(url); - reportProgress(); - })); + return await Promise.all(loadPromises); } catch (error) { - console.error('Error loading asset:', error); + console.error('Error loading one or more asset:', error); } } _flutter.loader.load({ - onEntrypointLoaded: async function(engineInitializer) { + onEntrypointLoaded: async function (engineInitializer) { await Promise.all([ beginPreloading(), engineInitializer.initializeEngine(), From 2235534736b4caacd65084b02d93c74f9fe9f133 Mon Sep 17 00:00:00 2001 From: Dominik Simonik Date: Thu, 12 Mar 2026 09:22:09 +0100 Subject: [PATCH 4/6] docs: update information about manifest --- __brick__/web/flutter_bootstrap.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/__brick__/web/flutter_bootstrap.js b/__brick__/web/flutter_bootstrap.js index c5c968a..e9eee73 100644 --- a/__brick__/web/flutter_bootstrap.js +++ b/__brick__/web/flutter_bootstrap.js @@ -8,6 +8,9 @@ const progressIndicator = document.querySelector('#progress-indicator'); async function readAssets() { // AssetManifest.bin is encoded with Flutter's Standard Message Codec. // See: https://docs.flutter.dev/platform-integration/web/initialization + // See also: https://docs.flutter.dev/release/breaking-changes/asset-manifest-dot-json#reading-asset-manifest-information-from-dart-code-outside-of-a-flutter-app + // Keep in mind that AssetManifest.bin is an implementation detail of Flutter. + // Reading this file isn't an officially supported workflow. The contents or format of the file might change in a future Flutter release without an announcement. const response = await fetch('assets/AssetManifest.bin'); const buffer = await response.arrayBuffer(); const view = new DataView(buffer); From 2f16b8b219f823916fbac987c965768a203add2c Mon Sep 17 00:00:00 2001 From: Dominik Simonik Date: Thu, 12 Mar 2026 09:26:55 +0100 Subject: [PATCH 5/6] fix: revert js formatting --- __brick__/web/flutter_bootstrap.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__brick__/web/flutter_bootstrap.js b/__brick__/web/flutter_bootstrap.js index e9eee73..aabae76 100644 --- a/__brick__/web/flutter_bootstrap.js +++ b/__brick__/web/flutter_bootstrap.js @@ -1,6 +1,6 @@ "use strict"; -{ {=<% %>=} } { { flutter_js } }<%={ { } }=%> - {{=<% %>=}}{ { flutter_build_config } }<%={ { } }=%> +{{=<% %>=}}{{flutter_js}}<%={{ }}=%> +{{=<% %>=}}{{flutter_build_config}}<%={{ }}=%> const progressText = document.querySelector('#progress-text'); const progressIndicator = document.querySelector('#progress-indicator'); From 2987b5584aefdb269cbed8453b5cfc0c86295a5c Mon Sep 17 00:00:00 2001 From: Dominik Simonik Date: Thu, 12 Mar 2026 11:35:51 +0100 Subject: [PATCH 6/6] chore: update hooks dependencies to latest versions --- hooks/pubspec.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hooks/pubspec.yaml b/hooks/pubspec.yaml index 751fa9a..2e341c2 100644 --- a/hooks/pubspec.yaml +++ b/hooks/pubspec.yaml @@ -5,9 +5,9 @@ environment: dependencies: mason: ^0.1.2 - yaml: ^3.1.2 + yaml: ^3.1.3 dev_dependencies: mocktail: ^1.0.4 - test: ^1.25.8 - very_good_analysis: ^10.0.0 + test: ^1.30.0 + very_good_analysis: ^10.2.0