@monlite/core 0.3.0 → 0.5.0
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.
- package/README.md +64 -0
- package/dist/index.cjs +637 -82
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +198 -9
- package/dist/index.d.ts +198 -9
- package/dist/index.js +634 -83
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -277,6 +277,70 @@ await users.distinct("tags"); // ["a", "b", "c"]
|
|
|
277
277
|
|
|
278
278
|
---
|
|
279
279
|
|
|
280
|
+
## Structured collections (the SQL skin)
|
|
281
|
+
|
|
282
|
+
By default a collection is **document mode** — schema-free, every field stored
|
|
283
|
+
as JSON. Pass a `schema` to make it a **structured collection**: the declared
|
|
284
|
+
fields become real, typed SQL columns (fast, indexable, joinable, constrainable)
|
|
285
|
+
and any *other* fields overflow into a JSON column. **The CRUD/query API is
|
|
286
|
+
identical** — `find`, `where`, `orderBy`, `groupBy`, `distinct`, updates — only
|
|
287
|
+
the storage underneath changes.
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
const orders = db.collection("orders", {
|
|
291
|
+
schema: {
|
|
292
|
+
user_id: { type: "TEXT", index: true, references: "users(_id)" },
|
|
293
|
+
amount: "REAL",
|
|
294
|
+
status: { type: "TEXT", notNull: true, default: "pending" },
|
|
295
|
+
meta: "JSON", // objects/arrays, transparently (de)serialized
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
// Same API as document collections — but `amount`/`status` are real columns:
|
|
300
|
+
await orders.create({ data: { user_id: "u1", amount: 100, status: "paid", note: "rush" } });
|
|
301
|
+
await orders.findMany({ where: { amount: { gte: 50 }, status: "paid" } });
|
|
302
|
+
await orders.groupBy({ by: ["status"], _sum: { amount: true } });
|
|
303
|
+
|
|
304
|
+
// Undeclared fields (like `note`) still work — they overflow into JSON.
|
|
305
|
+
await orders.findMany({ where: { note: { contains: "rush" } } });
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Because the columns are native, they join, constrain, and index like any SQL
|
|
309
|
+
table — including from the raw SQL hatch with no `json_extract`:
|
|
310
|
+
|
|
311
|
+
```ts
|
|
312
|
+
await db.$queryRaw`
|
|
313
|
+
SELECT u.name, SUM(o.amount) AS revenue
|
|
314
|
+
FROM users u JOIN orders o ON o.user_id = u._id
|
|
315
|
+
GROUP BY u._id
|
|
316
|
+
`;
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Column types: `"TEXT" | "INTEGER" | "REAL" | "BLOB" | "JSON"`. A full column
|
|
320
|
+
definition supports `index`, `unique`, `notNull`, `default`, and `references`.
|
|
321
|
+
|
|
322
|
+
### Do I have to care: JSON vs native columns?
|
|
323
|
+
|
|
324
|
+
- **For correctness — no.** Both modes return identical results through the same API.
|
|
325
|
+
- **For performance & SQL interop — a little.** Native columns + native indexes are
|
|
326
|
+
faster and join/constrain cleanly; JSON is for when the shape is unknown or varies.
|
|
327
|
+
|
|
328
|
+
monlite never hides which is which:
|
|
329
|
+
|
|
330
|
+
```ts
|
|
331
|
+
orders.mode; // "structured" | "document"
|
|
332
|
+
await db.$schema("orders"); // physical columns: [{ name, type, notNull, primaryKey }, …]
|
|
333
|
+
createDb("./app.db", { verbose: (sql) => console.log(sql) }); // see json_extract vs bare columns
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
> **Rule of thumb:** unknown/flexible shape → document (JSON); known/stable shape
|
|
337
|
+
> with heavy joins, reporting, or external SQL tooling → structured (native columns).
|
|
338
|
+
|
|
339
|
+
> Note: structured collections are not yet covered by `@monlite/sync` (document
|
|
340
|
+
> collections are) — that's planned follow-up work.
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
280
344
|
## SQL escape hatch
|
|
281
345
|
|
|
282
346
|
When you need full SQL power — complex joins, analytics, cross-collection
|