odroe 0.1.0-dev.2
odroe: ^0.1.0-dev.2 copied to clipboard
A full-stack meta-framework for Dart and Flutter products.
Changelog #
0.1.0-dev.2 #
-
Update same-key Query options across parent rebuilds without redundant refetches or cancelling infinite queries and page requests. Preserve cached pages and subscriptions while applying updated query functions and policies to future requests. Immediately remounting after cancellation now starts a valid replacement request; late results cannot overwrite it. Real key/client changes, mounts, and disabled-to-enabled transitions retain their fetch behavior.
-
Let
QueryClientProvidercreate and own a client without App/modules setup. Keep it across rebuilds and clear it on disposal; use a new widget key for a fresh lifetime. Borrow existing clients withQueryClientProvider.value. Existingclient:constructor calls must migrate to.value, and mounted clients are read withof(context)instead of the removed widget field. Add a tested incremental Flutter path through Query, manual routing, and a real HTTP RPC server without initialization or generation. -
Let
odroe create <directory>use its own exact hosted package version by default, with--version <exact-version>and--odroe-pathas optional overrides. Resolve the requested version, verify its lockfile, and run its installed initializer from the staged application so templates and generated code match the selected package. Keep--odroe-pathas the exclusive source-development alternative, reject floating versions before staging, and preserve target protection and rollback across resolution and initialization failures. Hosted initialization uses the selected Flutter SDK's Dart executable, including when the invoking CLI is an AOT executable; a missing SDK Dart fails before staging. -
Make direct Flutter dependency usage the getting-started path, with a tested App/Query/manual-routing example and standard Flutter release build. Keep create/init scaffolding optional and describe generation only for features that need generated source.
0.1.0-dev.1 #
Framework preview and migration #
- Start a new full-stack framework generation under the existing
odroename. This is a breaking change from the former 0.0.8 UI package:setup,signal, reactive props and UI lifecycle APIs are not compatibility exports. See MIGRATION.md; existing published versions remain available. - Restore the project's original MIT license and Odroe Inc. copyright notice.
- Validate stable Dart 3.10.0 with stock Flutter 3.38.1 as the minimum pair. Resolve analyzer/formatter/test versions normally without overrides and keep declaration names, generated codecs and exact diagnostic contracts across supported toolchains.
- Consume the exact hosted preview in an empty Flutter application, then run
odroe init --full-stackandodroe generate. Sourcecreate --odroe-pathremains available for checkout-based development.
Integrated platform #
-
Integrate the existing full-stack platform in one batch from the prior development branch, retaining public-main prerender ownership, real-path protection, recovery diagnostics, and HTTP configuration validation. Preserve relative client RPC namespaces while keeping server namespaces absolute; reject invalid paths before constructing an owned HTTP client. Keep
ODROE_RPC_ORIGINas the starter's public native-client configuration name. This preview does not establish signed mobile, remote database, or Cloudflare deployment support. -
Publish Native full-stack builds as one complete, rollback-safe artifact. Odroe now keeps the AOT server staged through Flutter Web compilation and prerendering, layers the actual Flutter and static outputs into
<bundle>/build/web, then replaces the owned bundle once. A failed client build or prerender leaves the previous server and client together;--server-onlydeliberately omits Web output instead of carrying stale assets forward. Flutter and prerender roots may match or remain disjoint, but newly rejected nested roots no longer produce ambiguous artifact trees. Odroe-managed Flutter Web output must now resolve inside the projectbuild/tree; each build uses a clean sibling stage and atomically replaces that output so removed routes and assets cannot survive a rebuild. -
Generate symmetric typed RPC codecs for project-local enums, including direct values, non-generic aliases, nullable values, collections, named records, and stream items. Enum cases cross the wire by declaration name; unknown input fails with HTTP 400 before the handler, while invalid output is normalized to
RpcProtocolException. This generated path takes precedence overSerializationAdapterfor directly declared project enums; dependency and otherwise opaque nominal values remain adapter-owned. Renaming or removing a shipped enum case is a breaking wire change. -
Make owned Native bundles resolve their runtime root from the compiled executable before application creation. A validated bundle marker now makes relative SQLite, migration, static, and application resource paths independent of the caller's working directory, while source and development runs keep the caller-selected project directory. CLI-managed prerender also keeps the project directory for build-time source resources. Reject a missing, non-regular, or damaged marker in compiled bundles before touching application state.
-
Initialize
odroe createstarters in the current CLI process after dependency resolution and canonical checkout identity validation. Keep only Flutter scaffold creation and dependency resolution as child processes, avoiding a redundant Dart startup and native build-hook cost while preserving staged rollback, interruption handling, and no-replace publication. Commit buffered initializer output only after publication, using the final project path. -
Enable and verify SQLite foreign-key enforcement whenever a native in-memory or file connection opens. Reject a connection that cannot enable the safety setting, keep violations on the existing
SqlErrorCode.constraintpath, and leave historical orphan detection or repair to explicit application work. Reject migrations that try to change the connection-owned setting. -
Define typed SQL projections with named
columnsanddecodearguments, then decode throughSqlProjectionRow.read(selection)so application records no longer depend on hand-maintained result indices. Resolve selections by exact identity, reject missing or repeated selections, and validate the complete row width before decoding. Keep positionalSqlRowaccess only for the explicit raw-SQL transport path. -
Add the application-owned
odroe.yamlwith one explicitsqlite_migrationspath. Full-stack starters now build and develop against their SQLite history without repeating a CLI flag, while--sqlite-migrationsremains the one-command override. Keep projects without this config unselected and ignore it for Cloudflare-only builds so generic PostgreSQL or MySQL migration directories are never guessed. -
Build Native servers with
dart build cliso dependency build and link hooks run in clean consumer projects. Publish the completebin/,lib/, and optionalmigrations/bundle as one owned, rollback-safe directory, run prerender from its executable, preserve previous outputs on failure, and refuse to silently drop an already selected SQLite history. Preserve legacy standalone outputs for explicit operator cleanup instead of guessing how to migrate an adjacent history sidecar. -
Add an owned, lazy, bounded
MysqlDatabase.poolwithout new dependencies or automatic retries. Bound physical connections, pending operations, and queue wait time independently; reject saturation asSqlErrorCode.unavailable. Keep transactions on one UTC connection, advance queued callers after failed opens, drain accepted work before close, preserve user errors, and retire any connection whose transaction state cannot be cleaned. Verify concurrency, backpressure, rollback, connection retirement, and shutdown against MariaDB 11.8 while retaining the lower-cost serializedopenpath. -
Classify Cloudflare's documented D1 network, storage-reset, code-update-reset, and transient remote-node failures as
SqlErrorCode.unavailablewithout exposing raw errors or retrying writes. Keep capacity, overload, resource, and large-write timeout failures classified asdriveruntil a safer contract exists. -
Add type-safe atomic numeric updates through numeric
SqlTableColumn.incrementBy, while keeping derived assignments out of INSERT APIs. Compile one boundcolumn = column + deltastatement across SQLite, PostgreSQL, MySQL/MariaDB, and D1, with negative deltas for decrement and explicit rejection of provider-dependent zero-delta no-ops. -
Replace the full-stack starter and reference app's unbounded post list with a typed ID-cursor page from SQL through generated RPC to Flutter
InfiniteQueryBuilder. Enforce a 1–50 row request budget and uselimit + 1to report the next cursor without an implicit count query. -
Add an append-only native SQLite migration runner with strict numbered SQL loading, exact applied-source verification, per-file atomic execution, and concurrent-startup locking. Let Native and Wrangler D1 consume the same application-owned history while keeping separate ledgers; explicitly select the SQLite source for Native bundles and prerender, watch it in development, and wire the contract through the full-stack starter and reference product. Validate route, migration, bundle, and prerender paths before any generated write, and serialize Native bundle publication across processes.
-
Add provider-neutral
SqlQueries.countRowsfor typedCOUNT(*)over the existing table, join, and predicate path across SQLite, PostgreSQL, MySQL/MariaDB, and D1. Joined duplicates count as relation rows; ordering, pagination, grouping, and a general aggregate DSL remain outside the API. -
Add type-safe
SqlTableColumn.isInandisNotInpredicates across SQLite, PostgreSQL, MySQL/MariaDB, and D1. Non-null candidates are encoded eagerly; emptyisInand explicit Dartnullcandidates compile to portable predicates, while emptyisNotInis rejected before it can expose a full-table mutation. -
Add
odroe create <directory>as the guarded source-stage product path from a nonexistent target through Flutter scaffold, Odroe dependency resolution, and the full-stack starter. Reject existing targets and remove only the private same-parent staging directory when any subprocess fails; publish the requested target only after the complete product succeeds. -
Make
odroe_flutter.dartthe selective Flutter composition root forQueryModule,RpcModule,DocumentModule,RouterModule, androuterKey. Generate one Odroe import in applicationmain.dartwhile keeping route, server, and database source on narrow product entrypoints; atomically upgrade untouched starters that used the previous imports. -
Let adapter-neutral
server.dartexpose the platform-neutral application core its public server contracts already use. Generated server trees now need one Odroe server import instead of repeatingodroe.dart. -
Add
odroe dev --server-target cloudflare --server-onlywith a project-local Wrangler runtime, required initial route generation and source-to-Worker compilation, Dart source watching, atomic server JavaScript replacement, and last-known-good service when a subsequent generation or compilation fails. -
Bind each Query cache identity to an exact
QueryKey<T>data type across options, reads, writes, infinite queries, hydration, and pending server handoff. Reject covariant or same-canonical type conflicts without replacing the existing cache entry. -
Add provider-neutral
SqlQueries.insertManyfor one typed multi-row INSERT, with complete shape validation before SQL construction and SQLite, PostgreSQL, MySQL/MariaDB, and Cloudflare D1 provider contracts. -
Generate symmetric typed RPC codecs for project-local named-record typedefs, including record inputs, outputs, collections, nullable values, and stream items. Upgrade the full-stack starter from a scalar read to typed post list and create flows across Flutter Query, ServerFunction, SQLite, and D1; the reference app additionally exercises typed post detail reads.
-
Fail record RPC generation for ambiguous aliases, private or unsupported shapes, conditional or missing model imports, platform-specific shared libraries, and protocol-only values in collections or streams. Emit const generated function references backed by hot-reload-safe static codecs, deduplicate forwarded model imports, and avoid duplicate collection copies before serialization.
-
Keep an active
MutationBuilderexecution and result attached when its options change; the new definition applies to the next execution. Reuse Query and Mutation options in the starter so unrelated widget rebuilds do not refetch stale lists or re-enable an in-flight create action. -
Add typed conflict-target
insertOnConflictDoNothingfor SQLite, Cloudflare D1, and PostgreSQL, with exact pre-I/O rejection on MySQL. Make the full-stack starter decode a completePostrecord through the same typed projection used by its application writes. -
Add exact-cardinality
SqlRead.oneandoneOrNullterminals. Typed selects probe at most two rows while preserving offsets and explicit limits up to two; mutationRETURNINGkeeps its original statement and validates the returned rows. -
Persist the full-stack starter's native SQLite data at
.odroe/app.sqlite3, allowODROE_SQLITE_PATHandODROE_MIGRATIONS_PATHoverrides, and preserve existing rows through append-only migrations. Give prerender an isolated temporary database and remove it after the build. -
Return a controlled HTTP 400 for strict typed search decoding failures without invoking the route or server error reporter. Keep handler, loader, and codec encoding failures classified as unexpected server errors.
-
Require exactly one encoded function ID segment under the RPC namespace, preserving
%2Finside IDs while rejecting empty or extra path segments before a function can run. Validate and canonicalize custom function paths consistently on clients and servers. -
Add
odroe init --full-stackas an atomic user-project starter spanning Flutter, Query, typed RPC, Server, typed SQL, native SQLite, and Cloudflare D1. Preserve the small default starter, allow untouched starters to upgrade, and reject custom files, unsafe paths, or partial writes without--force. -
Make the full-stack reference application's local Cloudflare path reproducible with its own locked Wrangler toolchain, Node and npm engine gates, D1 migration and development scripts, and a direct Getting Started handoff. Keep installed Node and Wrangler state out of the Dart publication archive.
-
Rebuild odroe.dev documentation as 17 product-first pages across start, tutorial, concepts, guides, and reference. Make the generated full-stack project the primary onboarding path, preserve old documentation URLs with redirects, and move website-only deployment operations out of public docs.
-
Keep the full-stack reference application product-focused by removing uncalled demonstration RPCs, including a custom
PostIdfunction that had no registered serialization adapter. Preserve stream, collection, and prefixed custom-type generation coverage in compiler tests instead. -
Make
server.dartthe complete server product entrypoint. MoveServerFunction,ServerFunctionBinding,ServerFunctionContext, andServerFunctionHandlerout ofrpc.dart; server files now importserver.dart, whilerpc.dartkeeps client/shared protocol APIs includingNoServerInputandValueDecoder. -
Run the example post page through Flutter Query, generated typed RPC, a real
DatabaseModule, typed SQL, native SQLite, and local Cloudflare D1. Keep the drivers platform-isolated, track one shared SQLite/D1 SQL history, and exportNotFoundandRedirectfrom the RPC product entrypoint. Validate typed frame versions, reject empty typed responses, and require control-frame status to match HTTP status. Raise the minimum server frame budget from 16 to 28 bytes so even the terminal fallback carriesversion: 1. -
Let routed Flutter apps select path or hash URLs explicitly from
AppbeforerunApp, including when a lazy module iterable yields the Router later, while preserving the host's URL strategy by default. Reject stale prerender handoff when the live browser pathname or search differs, preserving typed search during JavaScript and WebAssembly startup. -
Export the PostgreSQL connection and pool types plus the HTTP client required by Odroe's own public driver and transport constructors.
-
Pin the documentation site's Wrangler deployment tool, add a no-upload dry-run gate, and document authorized deploy, version readback, and HTTP smoke checks.
-
Select browser DOM handoff and external navigation through JS interop so Flutter Web keeps the same behavior in JavaScript and WebAssembly builds.
-
Freeze nested
QueryKeylist and map parts at construction so cache, hydration, and persistence identities cannot diverge after caller mutation. -
Cancel destroyed mutations while they are paused for connectivity or serial scope, release their wait listeners, and keep
QueryClient.clear()safe. -
Return current state from unsubscribed manual refetches and let interval polling reuse active work instead of repeatedly cancelling slow requests.
-
Add typed SQL, typed inner and left joins, and SQLite, PostgreSQL, MySQL/MariaDB, and Cloudflare D1 entrypoints.
-
Preserve the dialect on typed
BoundSqlstatements and reject explicit driver mismatches before statement I/O. Handwritten statements remain unpinned unlessdialectis supplied. -
Add request invocation lifetimes and a Fetch adapter for local Cloudflare Workers builds.
-
Serialize completed and pending Query handoff state through the application
Serializer, so built-in and custom values round-trip through Document SSR instead of failing during JSON encoding. -
Add optional stable
ServerFunction.idwire identifiers, reject empty, non-literal, and duplicate IDs in file routes, and preserve the existing path-and-variable fallback when an ID is omitted. -
Add a per-request asynchronous RPC
headersProvider, keep protocol headers framework-owned, and classify non-protocol HTTP failures by status instead of leaking JSON parsing errors. -
Reject non-HTTP(S), hostless, and credential-bearing
RpcModule.httpbase URIs during setup, while keeping omitted URIs for same-origin Web RPC. Cross-platform examples now require an explicit native API origin. -
Add preflight-safe RPC cancellation across asynchronous headers, request bodies, response setup, typed value bodies, and streams, with direct Query cancellation bridging and no automatic timeout or retry policy.
-
Limit typed RPC responses to 1 MiB per value or stream frame by default, before UTF-8 decoding. Applications can configure
RpcClient.maxResponseFrameBytesorRpcModule.http, while cumulative stream size and explicitServerResponsebodies remain caller-owned. -
Limit server-generated typed response frames to 1 MiB by default, encode them directly into bounded UTF-8 output, and expose request and response budgets through generated
createServer. Oversized values return a bounded 500 error frame; oversized stream items terminate with one bounded error. -
Make the default HTTP transport's 10 MiB pre-send request body buffer configurable through
HttpTransportandRpcModule.http, exportPayloadTooLargeExceptionfromrpc.dart, and keep content framing owned by the transport. -
Report unexpected module, request execution, RPC encoding, and response stream failures through configurable
Server.onError, with a dependency-free Zone logger by default. Module setup failures remain rethrown, request and stream outcomes remain unchanged, and synchronous or asynchronous reporter failures cannot replace the original outcome. Malformed server-function inputs remain controlled HTTP 400 results instead of producing error logs. -
Reuse
Server.onErrorfrom the generated native bootstrap for IO-owned static, development-proxy, response-metadata, framing, and raw omitted-body failures without duplicating handler or source-stream reports. Metadata failures now discard partially applied status, reason, headers, cookies, and content framing before returning a fixed 500; for a supported method, malformed forwarded authority remains a controlled 400 before static or proxy dispatch. Bodyless framing is now status-aware: 1xx and 204 omitContent-LengthandTransfer-Encoding, 205 emits zero length, and HEAD preserves representation framing only where the protocol permits it. -
Reuse
Server.onErrorfrom the generated Fetch bootstrap for adapter-owned response metadata, construction, and byte-conversion failures. Keep handler and source-stream reporting Server-owned, register asynchronous reporters with hostwaitUntil, and document Cloudflare'senable_request_signalflag for real incoming-client cancellation. -
Make application context, route capability, and request context keys identity-based so independent modules cannot collide through equal constant type/name pairs. This is source-breaking: replace
const ContextKey(...),const RouteCapability(...), andconst RequestKey(...)declarations with one shared top-levelfinalinstance per key, then reuse it at every provider and consumer. Registration now useskey.provide(registry, value)orkey.provideFactory(registry, create); optional route values usekey.attach(route, value); request values usekey.set(context, value). These key-first instance methods reject incompatible values both statically and through widened generic views at runtime. -
Add Press collections, dynamic prerender locations, and the Odroe-built documentation website.
-
Change prerender defaults to fixed concurrency 4, at most 1000 routes and 1 MiB per HTML response. Link crawling is now opt-in with
--prerender-crawlorcrawlLinks: true; raise the matching CLI or SDK limits for larger applications. SDK seed routes must be absolute local paths without queries or fragments. -
Resolve application prerender locations before compilation, preserve the previous document-only output until a replacement succeeds, and avoid duplicate native compilation for Cloudflare builds.
-
Let
build --no-serverprerender through the generated Dart server source without emitting an unused native or Cloudflare artifact, so assets-only deployments and their tests avoid deployment-only compilation. -
Revalidate native static assets with weak ETags and Last-Modified, stream eligible responses with optional gzip, reject ambiguous or escaped paths on every request, serve prerendered indexes at canonical routes with media-quality negotiation, and stop inferring immutable caching from filenames.
-
Mount source
public/assets during development while isolating prerender and development server-only runs from stale Flutter origins and static build output. -
Release unread Fetch request bodies, return 501 consistently for unsupported methods, and keep normal IO response completion distinct from cancellation.
-
Freeze server, route, and server-function configuration snapshots and include the required Allow header in 405 route responses.