@ai-matrx/data 0.25.0 → 0.26.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.26.0 — callAll: every row of a set-returning function
4
+
5
+ - **`callAll(db, fn, args, { order })`** — the complete read of a set-returning database function:
6
+ `rpc(…, { count: "exact" })` paged by `range` over the named `order` (`"id"` or
7
+ `{ column, ascending, nullsFirst }`; end on a key), past the 1,000-row cap; a `DatabaseError` keeps the
8
+ database's own error (code kept); a short read throws `IncompleteReadError`; an empty order is refused.
9
+ - `SupabaseLike.rpc` takes PostgREST's optional third argument (`{ count }`).
10
+
11
+ Consumer action: none (additive). Packages that paged `.rpc(...).order().range()` by hand move to `callAll`.
12
+
3
13
  ## 0.25.0 — created_by stamped; listAll keeps the database's error
4
14
 
5
15
  - **A signed-in `insert` stamps `created_by`** with the session's person when the table has a
package/dist/db.cjs CHANGED
@@ -36,6 +36,7 @@ __export(db_exports, {
36
36
  assertDoor: () => assertDoor,
37
37
  assertWriteLanded: () => assertWriteLanded,
38
38
  call: () => call,
39
+ callAll: () => callAll,
39
40
  changesOf: () => changesOf,
40
41
  count: () => count,
41
42
  createActiveOrgCookie: () => createActiveOrgCookie,
@@ -1203,6 +1204,27 @@ async function call(db, fn, args) {
1203
1204
  }
1204
1205
  return check(door, await db.client.schema(fn.schema).rpc(fn.name, args));
1205
1206
  }
1207
+ async function callAll(db, fn, args, opts) {
1208
+ const door = `callAll ${fn.schema}.${fn.name}`;
1209
+ const role = db.role === "service" ? "service_role" : "authenticated";
1210
+ if (!fn.roles.includes(role) && !(role === "authenticated" && fn.roles.includes("anon"))) {
1211
+ throw new DoorRefusedError(door, `not executable by ${role} (executable by: ${fn.roles.join(", ") || "nobody"})`);
1212
+ }
1213
+ if (!opts.order.length) throw new DoorRefusedError(door, "a paged read needs an order (end on a key) \u2014 pages over no order can skip or repeat rows");
1214
+ return readAllRows(
1215
+ ({ from: lo, to: hi }) => {
1216
+ let q = db.client.schema(fn.schema).rpc(fn.name, args, { count: "exact" });
1217
+ for (const o of opts.order) {
1218
+ q = typeof o === "string" ? q.order(o) : q.order(o.column, { ascending: o.ascending ?? true, ...o.nullsFirst !== void 0 ? { nullsFirst: o.nullsFirst } : {} });
1219
+ }
1220
+ return Promise.resolve(q.range(lo, hi)).then((res) => {
1221
+ if (res.error) throw new DatabaseError(door, res.error);
1222
+ return res;
1223
+ });
1224
+ },
1225
+ { label: door, ...opts.pageSize !== void 0 ? { pageSize: opts.pageSize } : {}, ...opts.maxRows !== void 0 ? { maxRows: opts.maxRows } : {} }
1226
+ );
1227
+ }
1206
1228
  function tableByName(index, name) {
1207
1229
  const t = index[name];
1208
1230
  if (!t) throw new DoorRefusedError(`tableByName ${name}`, "no such table in the database description (schema-qualify it: schema.table)");