eagle_parse 0.1.0-dev.1
eagle_parse: ^0.1.0-dev.1 copied to clipboard
Typed, loss-aware parsing and read-only loading for Eagle 4.0 asset libraries.
eagle_parse #
eagle_parse is a typed, loss-aware Dart parser for observed Eagle 4.0 asset
libraries. It reads metadata into immutable values, preserves unknown JSON fields
for round trips, loads coherent library snapshots, and can observe native
libraries through immutable differential updates.
The package is read-only with respect to Eagle libraries. It never writes or repairs library files.
Supported layout #
A minimum loadable library contains:
example.library/
├── metadata.json
└── images/
The images/ directory may be empty. Supported root auxiliary documents are
optional; a missing optional document is accepted, while a present malformed
document fails inspection or loading. Item directories use Eagle's direct
images/<id>.info/ layout and payload name name + "." + ext (or name when
ext is empty).
This release supports versions matching 4.0.x. Later versions fail closed
until their real format has been observed and implemented behind a private
version boundary. The canonical root field is tagsGroups; a noncanonical
tagGroups field is retained only as unknown JSON.
Core API #
Use eagle_parse.dart for codecs and storage-neutral loading. It does not
import dart:io.
import 'dart:convert';
import 'package:eagle_parse/eagle_parse.dart';
Future<void> main() async {
final source = InMemoryEagleSource.fromBytes(<String, List<int>>{
'metadata.json': utf8.encode(
'{"applicationVersion":"4.0.0","folders":[],"tagsGroups":[]}',
),
});
final report = await inspectEagleLibrary(source);
if (!report.isLoadEligible) {
for (final diagnostic in report.errors) {
print(diagnostic);
}
}
}
An in-memory source infers directories from file paths, so an empty images/
directory requires a source that can represent empty directories. The complete
example/core.dart
uses a populated in-memory library.
Codecs expose expected failures as EagleFailure, with a stable code, relative
document path, and JSON pointer. Successful decoding retains unrecognized
members in immutable extras; encoding overlays known fields so stale unknown
members cannot override typed values.
Native loading and observation #
Use eagle_parse_io.dart on hosts with dart:io:
import 'dart:io';
import 'package:eagle_parse/eagle_parse_io.dart';
Future<void> main() async {
final result = await EagleWatchedLibrary.open(Directory('assets.library'));
switch (result) {
case EagleSuccess<EagleWatchedLibrary>(:final value):
final watched = value;
final subscription = watched.updates.listen((update) {
if (!update.applied) {
print(update.diagnostics);
return; // update.snapshot is still the last valid snapshot.
}
print('changed: ${update.changes.changedItemIds}');
});
try {
print('items: ${watched.current.items.length}');
} finally {
await subscription.cancel();
await watched.close();
}
case EagleFailure<EagleWatchedLibrary>(:final diagnostics):
print(diagnostics);
}
}
Native observation settles event bursts, serializes refreshes, and reloads only
affected root documents or direct item boundaries when safe. Malformed refreshes
retain the last valid snapshot. Ambiguous events and explicit reconcile() calls
perform a full load. Nested directories inside an item are application-owned:
the parser does not traverse or watch their contents.
Deleted Eagle items remain in snapshots with isDeleted == true; consumers
choose whether to filter them when projecting their own views.
See
example/native.dart
and the
eagle-diskproxy migration contract.
Compatibility note #
This package is a new composition-oriented API. It uses the historical
eagle_org_layer package and real Eagle 4.0 libraries as format evidence, but
does not retain that package's API. Consumers should depend on immutable models,
EagleResult, EagleDocumentSource, and the snapshot/watch composition points
instead of implementation classes.
Licensed under the MIT License.