Add assets interface
diff --git a/pkgs/assets/.gitignore b/pkgs/assets/.gitignore
new file mode 100644
index 0000000..3cceda5
--- /dev/null
+++ b/pkgs/assets/.gitignore
@@ -0,0 +1,7 @@
+# https://dart.dev/guides/libraries/private-files
+# Created by `dart pub`
+.dart_tool/
+
+# Avoid committing pubspec.lock for library packages; see
+# https://dart.dev/guides/libraries/private-files#pubspeclock.
+pubspec.lock
diff --git a/pkgs/assets/CHANGELOG.md b/pkgs/assets/CHANGELOG.md
new file mode 100644
index 0000000..d8fa5ba
--- /dev/null
+++ b/pkgs/assets/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 0.0.2
+
+- Initial version.
diff --git a/pkgs/assets/LICENSE b/pkgs/assets/LICENSE
new file mode 100644
index 0000000..4fd5739
--- /dev/null
+++ b/pkgs/assets/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2023, the Dart project authors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkgs/assets/README.md b/pkgs/assets/README.md
new file mode 100644
index 0000000..62a1719
--- /dev/null
+++ b/pkgs/assets/README.md
@@ -0,0 +1 @@
+This is a placeholder for a Dart asset bundle system.
\ No newline at end of file
diff --git a/pkgs/assets/analysis_options.yaml b/pkgs/assets/analysis_options.yaml
new file mode 100644
index 0000000..dee8927
--- /dev/null
+++ b/pkgs/assets/analysis_options.yaml
@@ -0,0 +1,30 @@
+# This file configures the static analysis results for your project (errors,
+# warnings, and lints).
+#
+# This enables the 'recommended' set of lints from `package:lints`.
+# This set helps identify many issues that may lead to problems when running
+# or consuming Dart code, and enforces writing Dart using a single, idiomatic
+# style and format.
+#
+# If you want a smaller set of lints you can change this to specify
+# 'package:lints/core.yaml'. These are just the most critical lints
+# (the recommended set includes the core lints).
+# The core lints are also what is used by pub.dev for scoring packages.
+
+include: package:lints/recommended.yaml
+
+# Uncomment the following section to specify additional rules.
+
+# linter:
+# rules:
+# - camel_case_types
+
+# analyzer:
+# exclude:
+# - path/to/excluded/files/**
+
+# For more information about the core and recommended set of lints, see
+# https://dart.dev/go/core-lints
+
+# For additional information about configuring this file, see
+# https://dart.dev/guides/language/analysis-options
diff --git a/pkgs/assets/lib/assets.dart b/pkgs/assets/lib/assets.dart
new file mode 100644
index 0000000..fe7d6a2
--- /dev/null
+++ b/pkgs/assets/lib/assets.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export 'src/assets_bundle.dart';
diff --git a/pkgs/assets/lib/src/assets_bundle.dart b/pkgs/assets/lib/src/assets_bundle.dart
new file mode 100644
index 0000000..79e938e
--- /dev/null
+++ b/pkgs/assets/lib/src/assets_bundle.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:typed_data';
+
+/// A collection of resources used by the application.
+///
+/// Asset bundles contain resources, such as images and strings, that can be
+/// used by an application. Access to these resources is asynchronous so that
+/// they can be transparently loaded over a network (e.g., from a
+/// [NetworkAssetBundle]) or from the local file system without blocking the
+/// application's user interface.
+///
+/// Applications have a [rootBundle], which contains the resources that were
+/// packaged with the application when it was built. To add resources to the
+/// [rootBundle] for your application, add them to the `assets` subsection of
+/// the `flutter` section of your application's `pubspec.yaml` manifest.
+///
+/// For example:
+///
+/// ```yaml
+/// name: my_awesome_application
+/// flutter:
+/// assets:
+/// - images/hamilton.jpeg
+/// - images/lafayette.jpeg
+/// ```
+///
+/// Rather than accessing the [rootBundle] global static directly, consider
+/// obtaining the [AssetBundle] for the current [BuildContext] using
+/// [DefaultAssetBundle.of]. This layer of indirection lets ancestor widgets
+/// substitute a different [AssetBundle] (e.g., for testing or localization) at
+/// runtime rather than directly replying upon the [rootBundle] created at build
+/// time. For convenience, the [WidgetsApp] or [MaterialApp] widget at the top
+/// of the widget hierarchy configures the [DefaultAssetBundle] to be the
+/// [rootBundle].
+///
+/// See also:
+///
+/// * [DefaultAssetBundle]
+/// * [NetworkAssetBundle]
+/// * [rootBundle]
+abstract class AssetBundle {
+ /// Retrieve a binary resource from the asset bundle as a data stream.
+ ///
+ /// Throws an exception if the asset is not found.
+ ///
+ /// The returned [ByteData] can be converted to a [Uint8List] (a list of bytes)
+ /// using [Uint8List.sublistView]. Lists of bytes can be used with APIs that
+ /// accept [Uint8List] objects, such as [decodeImageFromList], as well as any
+ /// API that accepts a [List<int>], such as [File.writeAsBytes] or
+ /// [Utf8Codec.decode] (accessible via [utf8]).
+ Future<ByteData> load(String key);
+
+ /// Retrieve a string from the asset bundle.
+ ///
+ /// Throws an exception if the asset is not found.
+ ///
+ /// If the `cache` argument is set to false, then the data will not be
+ /// cached, and reading the data may bypass the cache. This is useful if the
+ /// caller is going to be doing its own caching. (It might not be cached if
+ /// it's set to true either, depending on the asset bundle implementation.)
+ ///
+ /// The function expects the stored string to be UTF-8-encoded as
+ /// [Utf8Codec] will be used for decoding the string. If the string is
+ /// larger than 50 KB, the decoding process is delegated to an
+ /// isolate to avoid jank on the main thread.
+ Future<String> loadString(String key, {bool cache = true});
+
+ /// Retrieve a string from the asset bundle, parse it with the given function,
+ /// and return that function's result.
+ ///
+ /// The result is not cached by the default implementation; the parser is run
+ /// each time the resource is fetched. However, some subclasses may implement
+ /// caching (notably, subclasses of [CachingAssetBundle]).
+ Future<T> loadStructuredData<T>(
+ String key, Future<T> Function(String value) parser) async {
+ return parser(await loadString(key));
+ }
+
+ /// Retrieve [ByteData] from the asset bundle, parse it with the given function,
+ /// and return that function's result.
+ ///
+ /// The result is not cached by the default implementation; the parser is run
+ /// each time the resource is fetched. However, some subclasses may implement
+ /// caching (notably, subclasses of [CachingAssetBundle]).
+ Future<T> loadStructuredBinaryData<T>(
+ String key, FutureOr<T> Function(ByteData data) parser) async {
+ return parser(await load(key));
+ }
+
+ /// If this is a caching asset bundle, and the given key describes a cached
+ /// asset, then evict the asset from the cache so that the next time it is
+ /// loaded, the cache will be reread from the asset bundle.
+ void evict(String key) {}
+
+ /// If this is a caching asset bundle, clear all cached data.
+ void clear() {}
+}
diff --git a/pkgs/assets/pubspec.yaml b/pkgs/assets/pubspec.yaml
new file mode 100644
index 0000000..70b3018
--- /dev/null
+++ b/pkgs/assets/pubspec.yaml
@@ -0,0 +1,15 @@
+name: assets
+description: Placeholder for a Dart asset bundle system.
+version: 0.0.2
+repository: https://github.com/mosuem/assets
+
+environment:
+ sdk: ^3.0.0
+
+# Add regular dependencies here.
+dependencies:
+ path: ^1.8.0
+
+dev_dependencies:
+ lints: ^2.1.0
+ test: ^1.24.0