@aotter/mantle 0.2.1-alpha.2 → 0.2.1-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +16 -177
  2. package/dist/build/compiler.js +3 -3
  3. package/dist/infrastructure/help.js +1 -3
  4. package/dist/usecase/adminDescriptors.js +1 -1
  5. package/dist/usecase/generate.js +20 -4
  6. package/dist/usecase/rest.js +2 -4
  7. package/docs/examples/README.md +2 -2
  8. package/docs/examples/app-shell/README.md +1 -1
  9. package/docs/examples/app-shell/accept.mjs +12 -2
  10. package/docs/examples/app-shell/package.json +3 -3
  11. package/docs/handbook/cloudflare/authentication.md +1 -1
  12. package/docs/handbook/cloudflare/deploy-and-operate.md +20 -8
  13. package/docs/handbook/cloudflare/media-r2.md +31 -0
  14. package/docs/handbook/examples/hub.md +1 -1
  15. package/docs/handbook/guides/agent-setup.md +25 -67
  16. package/docs/handbook/guides/agent-workflow-acceptance.md +33 -4
  17. package/docs/handbook/guides/mcp-apps.md +3 -1
  18. package/docs/{skills/performance/SKILL.md → handbook/guides/performance.md} +55 -32
  19. package/docs/handbook/guides/size-and-startup.md +2 -2
  20. package/docs/handbook/guides/typed-queries.md +12 -0
  21. package/docs/handbook/navigation.json +4 -0
  22. package/docs/handbook/releases/index.md +63 -2
  23. package/docs/{upgrade-0.1-to-0.2.md → handbook/releases/upgrade-0.1-to-0.2.md} +13 -13
  24. package/docs/handbook/start/agents.md +43 -6
  25. package/docs/handbook/start/quickstart-worker.md +1 -1
  26. package/package.json +1 -1
  27. package/skills/README.md +7 -69
  28. package/skills/mantle/SKILL.md +16 -81
  29. package/docs/skills/develop/SKILL.md +0 -100
  30. package/docs/skills/integrate/SKILL.md +0 -51
  31. package/docs/skills/media-gc/SKILL.md +0 -109
  32. package/docs/skills/provision/SKILL.md +0 -44
  33. package/docs/skills/update/SKILL.md +0 -42
package/README.md CHANGED
@@ -12,180 +12,19 @@ how to combine stock, own-records, approvals, callbacks, public pages and email
12
12
 
13
13
  Three packages: `@aotter/mantle` is the SDK with bin `mantle`; `@aotter/mantle-ui` is pure UI without an SDK dependency; `@aotter/mantle-admin` is the optional product with the SDK as a peer. Use matching installed versions and their own docs.
14
14
 
15
- Select `--admin` / `admin: true` for [Native Admin](./docs/handbook/guides/native-admin.md).
16
- Its generated adapter mounts with `entries(bindings.schemas, bindings.adapter)`;
17
- shared read templates and generated Procedure fragments preserve the native
18
- row policy and checks without importing generic Store into initial Admin reads.
19
-
20
- Build and contributor checks: [CONTRIBUTING](https://github.com/aotter/mantle/blob/develop/CONTRIBUTING.md).
21
-
22
- Outputs include `generated.ts`, `schema.sql` and direct operation entries.
23
- Commit generated output and Wrangler edits; keep `dist/` untracked. Run the same
24
- generate command with `--check` in CI. Never hand-edit generated files; merge
25
- manifest/options changes and regenerate. See [service composition](./docs/handbook/cloudflare/service-entry.md)
26
- for app-owned routing, assets, scheduling, Bun and the generated-output workflow.
27
- Import `views/<encoded-name>.ts` or `procedures/<encoded-name>.ts` (default export
28
- and types) to exclude other operations. Apply initial DDL to an empty development
29
- database; it is not a production migration. Generation performs no database I/O.
30
- Call `views[name](db, caller, input)` or `procedures[name](db, caller, input)` with
31
- driver-ready inputs, a native handle (Bun.SQL, bun:sqlite Database or D1 binding)
32
- and a verified Caller.
33
-
34
- Validate untrusted input before calling queries and redact native errors at application
35
- transports. The [query contract](./docs/handbook/guides/native-execution.md#query-inputs-values-and-outcomes)
36
- defines driver-ready inputs, native results, date-time/date wire forms and failure handling.
37
-
38
- For transports, `paged/views/<name>.ts` returns `{ rows, nextCursor? }` with keyset paging and
39
- `validation/<kind>/<name>.ts` checks input against the declared JSON Schema subset; the
40
- [surface deltas](./docs/handbook/reference/surface.md) define the REST/MCP wire contract.
41
- Proved internal Views also get paging without a public route/tool: one SELECT
42
- per page, validated scalar cursor keys and hidden-key removal. Schema tuples
43
- need indexed order after fixed equality prefixes ([index prefixes](./docs/handbook/reference/schema.md#index-prefixes-for-paged-views)); complete groups and singleton
44
- joins are supported. Grouping still scans/aggregates its source: inspect EXPLAIN.
45
- Unsupported internal SQL retains its bare module.
46
-
47
- Every Schema is a typed **Store** collection:
48
- `store(db, caller).collection("purchase_requests")` with `findById`, `find` (AND-only `where`, `{ rows, cursor }` keyset pages), `first`,
49
- `count`, `insert(values)`, OCC `update(id, set, { lock })` and `delete(id, { lock })`. Rows, `where`, `set` and `orderBy` use the
50
- table's storage column names, lower-case (`requestnumber`, `created_at`), the keys a generated View returns; the generated types
51
- state column names, value types and the writable columns, and the Store enforces the Schema's row rules (scope, TTL, version) but
52
- **not** a View's or Procedure's `requires`: authorize before calling it. Design, limits and what the runtime still refuses are in
53
- [Store guide](./docs/handbook/guides/typed-queries.md).
54
-
55
- For simple creates and partial updates, prefer a declared Store-backed ref
56
- Procedure: await the caller-bound insert/update, return an allowlist with the
57
- actual returned `id`/`version`, and preserve omitted fields. Keep Procedure
58
- `requires` and boundary validation; Store row policy is not operation
59
- permission. Retain SQL Procedures for atomic conditional/multi-entity writes
60
- such as stock/order changes and additive upserts. D1 batches cannot consume a
61
- prior step's result and have no interactive transaction callback. See the
62
- [write design guidance](./docs/handbook/guides/typed-queries.md#prefer-store-backed-ref-procedures-for-simple-writes).
63
-
64
- Importing generated modules does not initialize the Store. The first `store()`
65
- call prepares its metadata factory once; every call binds its own database,
66
- Caller and handlers. Unused Stores still tree-shake out of direct operations.
67
-
68
- `find({ search: "text" })` and `first({ search: "text" })` match an exact id or
69
- the Schema's `searchableFields`. Search is trimmed, must be non-empty and cannot contain NUL; it
70
- combines with `where`, scope, TTL and publication rules. SQLite/D1 use the
71
- generated FTS5 trigram index with maintenance triggers (queries shorter than
72
- three characters use LIKE); PostgreSQL uses ILIKE without requiring an extension.
73
- `%`, `_`, quotes and FTS operators are literal text. Schemas without search fields
74
- match id only. Non-ASCII case folding follows the dialect: SQLite/D1 FTS5
75
- trigram folds searchable text for queries of three or more characters, while
76
- shorter SQLite/D1 LIKE queries fold ASCII only; PostgreSQL ILIKE follows the
77
- database locale/collation. These are the same native differences as 0.2.
78
- Generated Views reuse Core's `mantle.search(alias, input.q)` and
79
- `mantle.search_rank(alias)`; ranking requires search on the same alias/query.
80
- Rank-ordered exposed Views still need supported keyset ordering; use an internal
81
- View for arbitrary rank ordering. Applying changed search DDL remains the app's
82
- migration responsibility; no request runs DDL or rebuilds indexes.
83
-
84
- ## Independently accept user-facing work
85
-
86
- Before reporting any user-facing deliverable as done, follow the version-matched
87
- [independent acceptance guide](./docs/handbook/guides/agent-workflow-acceptance.md)
88
- with a fresh agent on the surface its user uses. For MCP work, also run the
89
- guide's design audit before implementing tools; scripted checks remain separate
90
- evidence.
91
-
92
- ## Publishing
93
-
94
- Schemas default to `lifecycle: operational`. Opt-in `lifecycle: publishing` adds status
95
- (`draft` default, `published`, `archived`), nullable `published_at` and a scope-aware
96
- `(published_at, id)` index; `published_at` is selectable in Views and orders Store `find`
97
- (`NULLS LAST`). Generated `<table>.publish`, `.unpublish` and `.archive` Procedures take
98
- `{ id, expectedVersion }`, gate admin/system callers and run one atomic UPDATE; a failed guard is
99
- `CONFLICT`. Store writes cannot set status or `published_at`. Public Views see published rows only;
100
- other reads expose drafts only to admin or system callers.
101
-
102
- ## Ref Procedures
103
-
104
- A Procedure with a `ref` handler generates a typed `Handlers` interface. `mantle generate` lists the
105
- handlers to implement; pass them at `store(db, caller, { handlers })` (required by type when the
106
- manifest declares ref Procedures) and run `tsc --noEmit`. A handler receives `{ caller, db, store }`
107
- bound to the same caller and transaction; the exported `procedures` map holds SQL Procedures only.
108
-
109
- ## Workers build
110
-
111
- In an application, run generation:
112
-
113
- ```sh
114
- pnpm exec mantle generate cloudflare-d1 generated manifests/*.yaml --auth src/auth.ts
115
- pnpm exec wrangler deploy
116
- # or: pnpm exec wrangler dev --local
117
- ```
118
-
119
- For `cloudflare-d1` and `cloudflare-postgres`, generation configures Wrangler to run
120
- `mantle bundle <entry> <outdir>` automatically. Node 22.22 or newer is required. Run from the project root;
121
- regenerate after manifest or auth option changes.
122
-
123
- `--entry` defaults to `src/worker.ts`, `--outdir` to `dist`; with `--admin`, `--assets` (Wrangler's `assets.directory`) defaults to `<outdir>/client`. `--wrangler` defaults to the
124
- existing `wrangler.jsonc`, `wrangler.json` or `wrangler.toml`, otherwise `wrangler.jsonc`.
125
- JSONC edits preserve comments and unrelated settings and are idempotent. A new config
126
- needs its `name`, `compatibility_date` and bindings filled in. TOML only prints instructions.
127
-
128
- esbuild emits minified split ESM into `<outdir>/worker`; Wrangler uploads it with `no_bundle`,
129
- `find_additional_modules`, `base_dir` and an ESModule rule. Generation ensures
130
- `nodejs_compat` and defaults to `global_fetch_strictly_public`, including explicit
131
- environment flag overrides; see [Workers deployment](./docs/handbook/cloudflare/deploy-and-operate.md).
132
- The metafile guard rejects `better-auth` / `@better-auth/*` in the static startup graph:
133
- use `authLoader(() => import(...))` ([Auth](./docs/handbook/cloudflare/authentication.md#worker-entry)).
134
- The Worker directory is cleaned first; keep source and generated code elsewhere. A Worker that imports
135
- `@aotter/mantle-admin/server` also gets Admin, built with Vite into `<assets>/admin` (default `<outdir>/client/admin`)
136
- from `admin.tsx` beside the entry or the built-in entry. The built-in entry is skipped while the installed
137
- Admin and its direct dependencies are unchanged; an `admin.tsx` entry builds every time.
138
-
139
- ## D1 Sessions
140
-
141
- D1's session handle already satisfies generated Views/Procedures and the Store's structural `db` type:
142
-
143
- ```ts
144
- const bookmark = request.headers.get("x-d1-bookmark");
145
- const session = env.DB.withSession(bookmark ?? "first-unconstrained");
146
- const rows = await views.catalog(session, caller, {});
147
- const data = store(session, caller); // use the same handle for Store operations
148
- return Response.json(rows, { headers: { "x-d1-bookmark": session.getBookmark() ?? "" } });
149
- ```
150
-
151
- Return `session.getBookmark()` in a header or cookie and have the client pass it back on the next request.
152
- Keep `resolveCaller` and Better Auth on `env.DB`: revocation and roles must read the primary.
153
- Enable [read replication](https://developers.cloudflare.com/d1/best-practices/read-replication/)
154
- on the database (dashboard or REST); writes always go to the primary.
155
-
156
- ## Store transactions
157
-
158
- Writes are lazy thenables: await `collection.insert/update/delete(...)` to execute once,
159
- or pass unused Writes from the same Store to `store.batch([...])` for atomic results in input order;
160
- a stale lock, excluded row or unique clash rolls back the whole batch with `CONFLICT`.
161
- A batch step cannot use a previous step's result. D1 supports only batch.
162
- On bun:sqlite and PostgreSQL, `store.transaction(async tx => { ... })` binds `collection`, `batch`, `views`
163
- and `procedures` to one transaction: resolve commits, throw rolls back; nested transactions are refused.
164
- `tx.batch` and a ref handler's `ctx.store.batch` join that same transaction, without a savepoint or another BEGIN.
165
- A rejected batch makes the whole outer transaction rollback-only: even if the callback catches the error and returns,
166
- its transaction rejects with the first batch failure and rolls back every write. This includes batch validation errors.
167
- Ref handlers can use `ctx.store.batch` on every target, including D1, without creating another Store.
168
- PostgreSQL defaults to serializable; `{ isolation: "read committed" }` selects another level. There is no automatic retry.
169
- SQLite uses BEGIN IMMEDIATE and queues all Store/generated driver calls on the same Database until COMMIT/ROLLBACK;
170
- Inside a transaction callback the outer Store or handle passed to a Mantle driver throws `INPUT_VALIDATION_FAILED`; use `tx`.
171
-
172
- Views return rows; Procedures return `{ results }`. See the [query contract](./docs/handbook/guides/native-execution.md#query-inputs-values-and-outcomes)
173
- for atomicity and uncertain writes.
174
-
175
- PostgreSQL handles (Bun.SQL, postgres.js) satisfy the two-method `Postgres` shape as they are; see the [contract](./docs/handbook/guides/native-execution.md).
176
- Unsupported declarations fail generation with diagnostics;
177
- see the [supported/refused list](./docs/handbook/reference/features.md) for current scope and planned features.
178
-
179
- Native contributor checks run all four hosts with independent SQL oracles and
180
- fresh PostgreSQL schemas; behavior follows each engine. Local Cloudflare checks
181
- create no cloud resources. Performance claims need a quiet machine and raw samples.
182
- The [size and startup gates](./docs/handbook/guides/size-and-startup.md) cover the
183
- bundle and package budgets. The private compiler ships in this SDK and stays outside request imports.
184
-
185
- ## Data paths and migrations
186
-
187
- Writes use Store or declared Procedures, never raw SQL writes that bypass scope, TTL, publishing and system columns. Internal Views are for joins, aggregates, OR and reusable reads. Store findById/find/first remain useful for simple handler lookups and partial adoption in existing TypeScript/Node apps using their own native handle and verified Caller.
188
-
189
- The runtime never creates, alters or checks tables; boot and requests run no DDL. Apply initial schema.sql plus selected auth/site DDL to an empty database. For each later change, the app's agent diffs regenerated SQL, writes a native migration, rehearses it on a copy and applies it before deploying code. Destructive/type changes need explicit data migration; Mantle drops nothing.
190
-
191
- [Drivers are open structural handles; dialects are exactly postgres and sqlite](./docs/handbook/concepts/runtime-and-adapters.md#drivers-and-dialects).
15
+ ## Where things are
16
+
17
+ `mantle help topics` lists every page. The ones most work starts from:
18
+
19
+ | Task | Topic |
20
+ | --- | --- |
21
+ | Build or change an app with an agent | `mantle help` (entry page) |
22
+ | Commands, outputs and targets | `mantle help project-and-cli` |
23
+ | Query from TypeScript, Store and adoption in an existing app | `mantle help typed-queries` |
24
+ | Native inputs, results and failure handling | `mantle help native-execution` |
25
+ | Admin | `mantle help native-admin` |
26
+ | Deploy, schema changes and operations | `mantle help deploy-and-operate` |
27
+ | Upgrade | `mantle help releases/index` |
28
+
29
+ The same pages ship as Markdown under [`docs/handbook/`](./docs/handbook/start/agents.md). Contributor checks:
30
+ [CONTRIBUTING](https://github.com/aotter/mantle/blob/develop/CONTRIBUTING.md).