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..aabae76 100644 --- a/__brick__/web/flutter_bootstrap.js +++ b/__brick__/web/flutter_bootstrap.js @@ -2,18 +2,51 @@ {{=<% %>=}}{{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 + // 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); + 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; } @@ -29,15 +62,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() { @@ -76,10 +110,7 @@ async function loadBatch(urls) { } _flutter.loader.load({ - serviceWorkerSettings: { - serviceWorkerVersion: {{=<% %>=}}{{flutter_service_worker_version}}<%={{ }}=%>, - }, - onEntrypointLoaded: async function(engineInitializer) { + onEntrypointLoaded: async function (engineInitializer) { await Promise.all([ beginPreloading(), engineInitializer.initializeEngine(), diff --git a/brick.yaml b/brick.yaml index 6c5e727..4037fca 100644 --- a/brick.yaml +++ b/brick.yaml @@ -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..2e341c2 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.3 dev_dependencies: - mocktail: ^1.0.0 - test: ^1.22.2 - very_good_analysis: ^5.1.0 + mocktail: ^1.0.4 + test: ^1.30.0 + very_good_analysis: ^10.2.0