okmodel 0.5.1 → 0.7.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.
Files changed (233) hide show
  1. package/README.md +100 -1116
  2. package/dist/adapters/capabilities.d.ts +3 -0
  3. package/dist/adapters/failure.d.ts +13 -2
  4. package/dist/adapters/lazy-errors.d.ts +22 -0
  5. package/dist/adapters/pg/bunsql-extra.d.ts +54 -3
  6. package/dist/adapters/pg/bunsql.d.ts +14 -1
  7. package/dist/adapters/pg/cursor.d.ts +17 -0
  8. package/dist/adapters/pg/no-inflight-timeout.d.ts +20 -0
  9. package/dist/adapters/pg/nodepostgres-extra.d.ts +22 -1
  10. package/dist/adapters/pg/nodepostgres.d.ts +12 -0
  11. package/dist/adapters/pg/pglite-wire.d.ts +24 -0
  12. package/dist/adapters/pg/pglite.d.ts +10 -0
  13. package/dist/adapters/pg/postgres-extra.d.ts +41 -3
  14. package/dist/adapters/pg/reserved.d.ts +42 -0
  15. package/dist/adapters/pg/session.d.ts +0 -18
  16. package/dist/contracts/catalog/document.d.ts +19 -5
  17. package/dist/contracts/catalog/object.d.ts +2 -1
  18. package/dist/contracts/catalog/policy.d.ts +48 -0
  19. package/dist/contracts/catalog/types.d.ts +25 -1
  20. package/dist/contracts/catalog/view.d.ts +2 -0
  21. package/dist/contracts/connection.d.ts +7 -6
  22. package/dist/contracts/internal.js +1 -1
  23. package/dist/contracts/location.d.ts +10 -0
  24. package/dist/dialects/pg/column.d.ts +13 -2
  25. package/dist/dialects/pg/ddl.d.ts +37 -1
  26. package/dist/dialects/pg/emit.d.ts +19 -1
  27. package/dist/dialects/pg/errors.d.ts +32 -1
  28. package/dist/dialects/pg/ext/citext.js +1 -1
  29. package/dist/dialects/pg/ext/index.js +1 -1
  30. package/dist/dialects/pg/ext/pg-trgm.js +1 -1
  31. package/dist/dialects/pg/filter-parse.d.ts +5 -4
  32. package/dist/dialects/pg/floor.d.ts +68 -0
  33. package/dist/dialects/pg/fn/index.js +2 -2
  34. package/dist/dialects/pg/index.d.ts +8 -2
  35. package/dist/dialects/pg/index.js +67 -171
  36. package/dist/dialects/pg/introspect.d.ts +7 -0
  37. package/dist/dialects/pg/keys.d.ts +11 -8
  38. package/dist/dialects/pg/model.d.ts +47 -2
  39. package/dist/dialects/pg/morph.d.ts +43 -0
  40. package/dist/dialects/pg/operator-fit.d.ts +2 -2
  41. package/dist/dialects/pg/operators.d.ts +14 -7
  42. package/dist/dialects/pg/ops/bucket.d.ts +65 -0
  43. package/dist/dialects/pg/ops/inc.d.ts +2 -2
  44. package/dist/dialects/pg/ops/matches.d.ts +9 -12
  45. package/dist/dialects/pg/ops/relevance.d.ts +13 -0
  46. package/dist/dialects/pg/ops/search-query.d.ts +22 -0
  47. package/dist/dialects/pg/ops/window.d.ts +103 -0
  48. package/dist/dialects/pg/owner.d.ts +42 -0
  49. package/dist/dialects/pg/path-endpoint.d.ts +20 -0
  50. package/dist/dialects/pg/preset.d.ts +1 -1
  51. package/dist/dialects/pg/relations.d.ts +100 -3
  52. package/dist/dialects/pg/role/check.d.ts +3 -0
  53. package/dist/dialects/pg/role/index.d.ts +71 -6
  54. package/dist/dialects/pg/role/sql.d.ts +11 -0
  55. package/dist/dialects/pg/schema.d.ts +33 -3
  56. package/dist/dialects/pg/table.d.ts +25 -3
  57. package/dist/dialects/pg/tenancy.d.ts +45 -3
  58. package/dist/dialects/pg/view/client.d.ts +19 -1
  59. package/dist/dialects/pg/view/index.d.ts +4 -0
  60. package/dist/dialects/pg/view/index.js +21 -178
  61. package/dist/dialects/pg/view/refresh.d.ts +24 -0
  62. package/dist/runtime/aggregate.d.ts +8 -2
  63. package/dist/runtime/batch.d.ts +1 -1
  64. package/dist/runtime/bucket-group.d.ts +70 -0
  65. package/dist/runtime/conflict.d.ts +24 -6
  66. package/dist/runtime/drift.d.ts +9 -0
  67. package/dist/runtime/include.d.ts +0 -8
  68. package/dist/runtime/inflight.d.ts +14 -0
  69. package/dist/runtime/page.d.ts +4 -1
  70. package/dist/runtime/pg/bun.js +12 -5
  71. package/dist/runtime/pg/pg.js +5 -5
  72. package/dist/runtime/pg/pglite.d.ts +1 -0
  73. package/dist/runtime/pg/pglite.js +9 -8
  74. package/dist/runtime/pg/postgresjs.js +5 -5
  75. package/dist/runtime/plan.d.ts +113 -15
  76. package/dist/runtime/predicate.d.ts +19 -0
  77. package/dist/runtime/read-stream.d.ts +13 -16
  78. package/dist/runtime/result-name.d.ts +17 -0
  79. package/dist/runtime/safety/index.js +1 -1
  80. package/dist/runtime/server-check.d.ts +3 -3
  81. package/dist/runtime/sort-bind.d.ts +21 -0
  82. package/dist/runtime/sort.d.ts +56 -0
  83. package/dist/runtime/sync.d.ts +70 -0
  84. package/dist/runtime/tenancy/composite.d.ts +26 -0
  85. package/dist/runtime/tenancy/context.d.ts +16 -0
  86. package/dist/runtime/tenancy/index.d.ts +9 -5
  87. package/dist/runtime/tenancy/index.js +1511 -38
  88. package/dist/runtime/tenancy/path.d.ts +87 -0
  89. package/dist/runtime/tenancy/rls.d.ts +67 -0
  90. package/dist/runtime/tenancy/via.d.ts +22 -0
  91. package/dist/runtime/text-search.d.ts +20 -0
  92. package/dist/runtime/traits/index.d.ts +80 -0
  93. package/dist/runtime/traits/index.js +187 -17
  94. package/dist/runtime/tree.d.ts +38 -0
  95. package/dist/runtime/types.d.ts +231 -23
  96. package/dist/runtime/validate/index.js +4 -4
  97. package/dist/runtime/version.d.ts +39 -0
  98. package/dist/runtime/window.d.ts +21 -0
  99. package/dist/runtime/write.d.ts +55 -3
  100. package/dist/shared/{krxx77g0.js → 14vx95q4.js} +12 -18
  101. package/dist/shared/1est4ezg.js +313 -0
  102. package/dist/shared/{4az561fn.js → 1qa0qajz.js} +8 -23
  103. package/dist/shared/1w508jbr.js +1611 -0
  104. package/dist/shared/2c13q96h.js +18 -0
  105. package/dist/shared/2d3xq4ps.js +9 -0
  106. package/dist/shared/2shdbn8q.js +23 -0
  107. package/dist/shared/{t4tbsy9h.js → 358zsv4r.js} +1 -1
  108. package/dist/shared/3v7t1yrv.js +208 -0
  109. package/dist/shared/5e3tf63j.js +220 -0
  110. package/dist/shared/5fe3kbsh.js +10 -0
  111. package/dist/shared/5v3xf80k.js +37 -0
  112. package/dist/shared/{51mvgj8w.js → 63qtkrca.js} +130 -3
  113. package/dist/shared/{gbtcc2d7.js → 67txcrcw.js} +62 -66
  114. package/dist/shared/79dt02vc.js +12 -0
  115. package/dist/shared/{v36c5g6p.js → 7k9grvf6.js} +407 -14
  116. package/dist/shared/7kms6fvj.js +20 -0
  117. package/dist/shared/7mnme5tn.js +8 -0
  118. package/dist/shared/7n7ddwt4.js +6 -0
  119. package/dist/shared/{87jvvhnt.js → 81ebdx9p.js} +48 -68
  120. package/dist/shared/{szm0cksa.js → 8skf0cam.js} +34 -6
  121. package/dist/shared/{gjthds9j.js → 9628a9xt.js} +1 -1
  122. package/dist/shared/9a4ae4p8.js +31 -0
  123. package/dist/shared/{8xsbagad.js → 9s0ypp87.js} +88 -7
  124. package/dist/shared/9y3mmmh1.js +436 -0
  125. package/dist/shared/ab9gmbwy.js +213 -0
  126. package/dist/shared/{sycnx8gt.js → ax7qv55k.js} +18 -8
  127. package/dist/shared/{f5cw5q5r.js → aytqh5y2.js} +6 -4
  128. package/dist/shared/{fancm5pt.js → b5pftnn2.js} +138 -15
  129. package/dist/shared/{efmy2gcg.js → b76b8d95.js} +2 -2
  130. package/dist/shared/bdk4sty6.js +58 -0
  131. package/dist/shared/{32zqc1dw.js → bg3rym3g.js} +63 -32
  132. package/dist/shared/{0t22wwh1.js → bm22fvzr.js} +16 -14
  133. package/dist/shared/bz84tkzm.js +342 -0
  134. package/dist/shared/{31vm914h.js → cm3w0ywp.js} +15 -16
  135. package/dist/shared/cn957f8d.js +179 -0
  136. package/dist/shared/{pf0d8f77.js → cnkky55j.js} +25 -14
  137. package/dist/shared/{5fqx9yh4.js → dk8v79p3.js} +3 -1
  138. package/dist/shared/{nkaxvt9q.js → dkxgzaqd.js} +224 -19
  139. package/dist/shared/dzj09cye.js +10 -0
  140. package/dist/shared/{4m9fn52z.js → ed0b8k4s.js} +1 -1
  141. package/dist/shared/{z2rnngj4.js → ek2wt2dz.js} +8 -5
  142. package/dist/shared/exn3sd90.js +359 -0
  143. package/dist/shared/g6evj1j3.js +66 -0
  144. package/dist/shared/ga9j92qj.js +25 -0
  145. package/dist/shared/{qv2ydck9.js → gs74dbj5.js} +651 -76
  146. package/dist/shared/gzaveazc.js +285 -0
  147. package/dist/shared/{8rsy3hxz.js → h15jx9bc.js} +1 -1
  148. package/dist/shared/{dyj86cmj.js → hyh73qk6.js} +3 -3
  149. package/dist/shared/je4axnm8.js +22 -0
  150. package/dist/shared/{ycatkxmq.js → jgqj11w4.js} +1 -1
  151. package/dist/shared/{6qd27mx0.js → jvd0mqag.js} +5 -5
  152. package/dist/shared/jznfax0y.js +155 -0
  153. package/dist/shared/{cgbamx3e.js → kb2sdhfb.js} +7 -4
  154. package/dist/shared/{ps7a6h14.js → kr0jzbw2.js} +12 -8
  155. package/dist/shared/{janx09m5.js → ktz42yez.js} +20 -8
  156. package/dist/shared/{gde73es6.js → m6p12kbr.js} +56 -55
  157. package/dist/shared/{r6nwkxnt.js → m7n9h2a5.js} +4 -4
  158. package/dist/shared/{672t5vym.js → mss6ctgv.js} +2 -2
  159. package/dist/shared/{nxdp2ze3.js → mtaszv5a.js} +144 -12
  160. package/dist/shared/n816peh1.js +45 -0
  161. package/dist/shared/nbw1z4yd.js +18 -0
  162. package/dist/shared/{cctw17hj.js → p6qc5gcp.js} +38 -34
  163. package/dist/shared/{6rk2gen5.js → pbp1ss85.js} +20 -17
  164. package/dist/shared/pt94kz7f.js +6 -0
  165. package/dist/shared/{wq9n6pwr.js → pz6rj8ay.js} +82 -9
  166. package/dist/shared/q5c6ngn3.js +13 -0
  167. package/dist/shared/{8bwbwy8h.js → qq3899ht.js} +128 -18
  168. package/dist/shared/{8ktwd3rh.js → r3j8s5y0.js} +1 -1
  169. package/dist/shared/rhs3xe4k.js +7 -0
  170. package/dist/shared/{ntneex2a.js → rpycarcr.js} +6 -6
  171. package/dist/shared/{sdc7r2ww.js → rs73fca9.js} +8 -8
  172. package/dist/shared/{tm5ab8we.js → sfz1ksn6.js} +7 -4
  173. package/dist/shared/{6mnp99hx.js → svncdeh5.js} +16 -12
  174. package/dist/shared/{hf22e0wt.js → tbrvgw6z.js} +62 -42
  175. package/dist/shared/te5as7z7.js +622 -0
  176. package/dist/shared/{ga3sfy93.js → tsvww22q.js} +535 -200
  177. package/dist/shared/{47x8x9ze.js → ttsqgp4p.js} +20 -13
  178. package/dist/shared/{x72jb7ad.js → v8g1vgv8.js} +1 -1
  179. package/dist/shared/vb6qfyve.js +152 -0
  180. package/dist/shared/{r2sp8hrc.js → vczs8gd4.js} +22 -13
  181. package/dist/shared/{1g0drakv.js → vqrjpcqn.js} +145 -3
  182. package/dist/shared/{2pqx26h8.js → w72kgg4q.js} +31 -22
  183. package/dist/shared/{96qcj21c.js → w79hsckn.js} +16 -51
  184. package/dist/shared/wa07eas9.js +730 -0
  185. package/dist/shared/{k8v5v5wj.js → x933k9a3.js} +75 -34
  186. package/dist/shared/{cr74e96e.js → xhfsfkgk.js} +62 -28
  187. package/dist/shared/xjk7hnn5.js +272 -0
  188. package/dist/shared/{5enne4ma.js → xnxsed62.js} +66 -113
  189. package/dist/shared/xqve9598.js +53 -0
  190. package/dist/shared/{9x25fxhc.js → y34a8714.js} +1 -1
  191. package/dist/shared/{k7dwkhvq.js → y6jdds7g.js} +4 -1
  192. package/dist/shared/y6njgyda.js +249 -0
  193. package/dist/shared/{c9z5g0fm.js → ywr8hmey.js} +5 -2
  194. package/dist/shared/{g7ez901n.js → ywspezzx.js} +1 -1
  195. package/dist/shared/z7s6fpxv.js +62 -0
  196. package/dist/shared/{n7mcc1gk.js → zchaghkf.js} +4 -3
  197. package/dist/shared/{9m80mkac.js → ze4hxsmy.js} +1 -1
  198. package/dist/shared/zm0ptry0.js +40 -0
  199. package/dist/shared/{nsva2a6b.js → znm0bpp5.js} +3 -0
  200. package/dist/shared/zp9fmend.js +145 -0
  201. package/dist/shared/{y005b761.js → zy8r7qvz.js} +6 -2
  202. package/dist/tooling/cli.js +41 -15
  203. package/dist/tooling/migrate/apply.d.ts +14 -0
  204. package/dist/tooling/migrate/check.d.ts +3 -4
  205. package/dist/tooling/migrate/classify.d.ts +4 -0
  206. package/dist/tooling/migrate/config.d.ts +3 -2
  207. package/dist/tooling/migrate/engine.d.ts +3 -2
  208. package/dist/tooling/migrate/files.d.ts +11 -1
  209. package/dist/tooling/migrate/index.js +14 -14
  210. package/dist/tooling/migrate/lint.d.ts +1 -1
  211. package/dist/tooling/migrate/lost.d.ts +28 -0
  212. package/dist/tooling/migrate/paths.d.ts +14 -0
  213. package/dist/tooling/migrate/plan.d.ts +6 -3
  214. package/dist/tooling/migrate/runner.d.ts +25 -0
  215. package/dist/tooling/migrate/sandbox.d.ts +57 -0
  216. package/dist/tooling/migrate/sql-lex.d.ts +20 -3
  217. package/dist/tooling/migrate/text.d.ts +42 -0
  218. package/dist/tooling/node-version.d.ts +21 -0
  219. package/dist/tooling/testing/facts.d.ts +33 -5
  220. package/dist/tooling/testing/index.d.ts +1 -1
  221. package/dist/tooling/testing/index.js +3 -3
  222. package/dist/tooling/testing/isolation.d.ts +11 -5
  223. package/package.json +8 -3
  224. package/dist/shared/7m88x3e9.js +0 -45
  225. package/dist/shared/7zwwyh0v.js +0 -448
  226. package/dist/shared/aj2qxyhj.js +0 -90
  227. package/dist/shared/caw8b9d8.js +0 -204
  228. package/dist/shared/jwtxdj06.js +0 -76
  229. package/dist/shared/kfjp0gck.js +0 -212
  230. package/dist/shared/q58y17hy.js +0 -21
  231. package/dist/shared/qm7cdtvr.js +0 -912
  232. package/dist/shared/r8x5qhd7.js +0 -86
  233. package/dist/shared/zqrnhwsq.js +0 -31
@@ -7,8 +7,10 @@
7
7
  import type { DriverTimeouts, Notice } from "../contracts/driver.js";
8
8
  import type { SafeResult } from "../contracts/error.js";
9
9
  import type { QuerySchema } from "../dialects/pg/model.js";
10
+ import type { Bucket } from "../dialects/pg/ops/bucket.js";
11
+ import type { Window } from "../dialects/pg/ops/window.js";
10
12
  import type { Inc } from "../dialects/pg/ops/inc.js";
11
- import type { ArrAppend, ArrRemove, JsonSet, Or, RelationFilter } from "../dialects/pg/operators.js";
13
+ import type { ArrAppend, ArrRemove, JsonSet, Or, RelationFilter, Relevance, SearchMatch } from "../dialects/pg/operators.js";
12
14
  import type { FieldWhere, IsJsonObject } from "../dialects/pg/where.js";
13
15
  import type { AppliedRule, ReadOp } from "./plan.js";
14
16
  export type { FieldWhere, WhereValue } from "../dialects/pg/where.js";
@@ -22,8 +24,20 @@ export type RelationsOf<S extends QuerySchema, K extends keyof S["~byName"]> = S
22
24
  } ? R : Record<string, never>;
23
25
  /** Array and JSON writes the column value type can accept. */
24
26
  type WriteOp<V> = [unknown] extends [V] ? JsonSet<unknown> | ArrAppend<unknown> | ArrRemove<unknown> : (V extends readonly (infer E)[] ? ArrAppend<E> | ArrRemove<E> : never) | (IsJsonObject<V> extends true ? JsonSet<unknown> : never);
25
- /** `has`, `none`, and `every` against the related row. */
27
+ /**
28
+ * `inc` on a number or bigint column.
29
+ *
30
+ * A `string` column is not included. `text` is a string, and so is `numeric`
31
+ * or `bigint` when the codec keeps the decimal text. The statement still
32
+ * accepts `inc` on a numeric database type.
33
+ */
34
+ type IncOf<V> = [unknown] extends [V] ? Inc<number> | Inc<bigint> : [NonNullable<V>] extends [number] ? Inc<number> : [NonNullable<V>] extends [bigint] ? Inc<bigint> : never;
35
+ /** `has`, `none`, and `every` against the related row. A morph include is not a filter. */
26
36
  export type RelFilter<S extends QuerySchema, Rel> = Rel extends {
37
+ readonly morph: {
38
+ readonly targets: readonly string[];
39
+ };
40
+ } ? never : Rel extends {
27
41
  readonly table: infer T extends string;
28
42
  } ? T extends keyof S["~byName"] ? RelationFilter<"has" | "none" | "every", FieldWhere<RowOf<S, T>>> : never : never;
29
43
  /** Known relation names. A string index (no declared relations) adds none. */
@@ -39,14 +53,34 @@ export type OrderBy<Row> = {
39
53
  readonly [K in keyof Row]?: "asc" | "desc" | {
40
54
  readonly dir: "asc" | "desc";
41
55
  readonly nulls?: "first" | "last";
42
- } | undefined;
56
+ } | Relevance | undefined;
57
+ };
58
+ /**
59
+ * Text to look for.
60
+ *
61
+ * A string is enough when the table has one column built for search. `in`
62
+ * names the column when it has more than one.
63
+ */
64
+ export type TextSearch<Row> = string | {
65
+ /** Text to look for. */
66
+ readonly for: string;
67
+ /** Column to search. Required when the table has more than one. */
68
+ readonly in?: keyof Row & string;
69
+ /** How to match. Omitted means `natural`. */
70
+ readonly match?: SearchMatch;
71
+ /** Text search language, such as `english`. Omitted uses the database default. */
72
+ readonly language?: string;
43
73
  };
44
74
  type Related<S extends QuerySchema, T extends keyof S["~byName"], Opt> = Opt extends {
45
75
  readonly select: infer Sel;
46
76
  } ? Selected<RowOf<S, T>, Sel> : RowOf<S, T>;
47
- /** One include. To-many needs `limit`. */
77
+ /** One include. To-many needs `limit`. A morph include is `true`. */
48
78
  export type IncludeOf<S extends QuerySchema, K extends keyof S["~byName"]> = {
49
79
  readonly [R in RelationKeys<RelationsOf<S, K>>]?: RelationsOf<S, K>[R] extends {
80
+ readonly morph: {
81
+ readonly targets: readonly string[];
82
+ };
83
+ } ? true : RelationsOf<S, K>[R] extends {
50
84
  readonly kind: "many";
51
85
  readonly table: infer T extends string;
52
86
  } ? T extends keyof S["~byName"] ? {
@@ -63,14 +97,40 @@ export type IncludeOf<S extends QuerySchema, K extends keyof S["~byName"]> = {
63
97
  readonly orderBy?: OrderBy<RowOf<S, T>>;
64
98
  } : never : never;
65
99
  };
100
+ /**
101
+ * Rows a morph include can return.
102
+ *
103
+ * Each target's row, plus the type field set to that table name, or null when
104
+ * the target row is missing.
105
+ */
106
+ /** Flattens an intersection so a morph arm is one object type. */
107
+ type Flat<T> = {
108
+ readonly [K in keyof T]: T[K];
109
+ };
110
+ /** One arm of a morph union. Distributes over the closed target list. */
111
+ type MorphArm<S extends QuerySchema, T extends string, Field extends string> = T extends keyof S["~byName"] ? Flat<RowOf<S, T> & {
112
+ readonly [P in Field]: T;
113
+ }> : never;
114
+ type MorphUnion<S extends QuerySchema, Targets extends readonly string[], Field extends string> = MorphArm<S, Targets[number], Field> | null;
66
115
  /** Columns kept by `select`. The full row when `select` is omitted. */
67
116
  export type Selected<Row, Sel> = [Sel] extends [readonly (infer P)[]] ? [P] extends [keyof Row] ? {
68
117
  readonly [K in P & keyof Row]: Row[K];
69
- } : Row : Row;
118
+ } : boolean extends HasWindow<P> ? Pick<Row, Extract<P, keyof Row>> & WindowFields<Row, P> : [P] extends [Window<string, string | number>] ? WindowFields<Row, P> : Row : Row;
119
+ /** `true` when a select entry is a window. A mix of fields and windows is `boolean`. */
120
+ type HasWindow<P> = P extends Window<string, string | number> ? true : false;
121
+ /** Result keys a window helper adds. A field name contributes nothing. */
122
+ type WindowFields<Row, P> = Intersect<P extends Window<infer A, infer V> ? {
123
+ readonly [K in A]: V extends keyof Row ? NonNullable<Row[V]> | null : number;
124
+ } : {}>;
70
125
  type IncludeRows<S extends QuerySchema, K extends keyof S["~byName"], Inc> = [Inc] extends [
71
126
  Record<string, unknown>
72
127
  ] ? {
73
128
  readonly [R in keyof Inc & keyof RelationsOf<S, K>]: RelationsOf<S, K>[R] extends {
129
+ readonly morph: {
130
+ readonly targets: infer Targets extends readonly string[];
131
+ readonly typeField: infer Field extends string;
132
+ };
133
+ } ? MorphUnion<S, Targets, Field> : RelationsOf<S, K>[R] extends {
74
134
  readonly kind: "many";
75
135
  readonly table: infer T extends keyof S["~byName"];
76
136
  } ? readonly Related<S, T, Inc[R]>[] : RelationsOf<S, K>[R] extends {
@@ -109,7 +169,8 @@ export type CallOptions = {
109
169
  /** Options shared by reads. */
110
170
  export type ReadOptions<S extends QuerySchema, K extends keyof S["~byName"]> = CallOptions & {
111
171
  readonly where?: WhereOf<S, K>;
112
- readonly select?: readonly (keyof RowOf<S, K> & string)[];
172
+ /** Field names, or a window helper (`rowNumber`, `rank`, `denseRank`, `runningTotal`). */
173
+ readonly select?: readonly ((keyof RowOf<S, K> & string) | Window<string, string | number>)[];
113
174
  readonly orderBy?: OrderBy<RowOf<S, K>>;
114
175
  readonly include?: IncludeOf<S, K>;
115
176
  };
@@ -118,6 +179,7 @@ export type ReadOptions<S extends QuerySchema, K extends keyof S["~byName"]> = C
118
179
  *
119
180
  * `wait` says what happens when a row is locked by another transaction: `nowait`
120
181
  * fails at once (kind `lock_timeout`) and `skip` leaves that row out.
182
+ * `lock: "skip"` is not a read lock. It claims rows on `update`.
121
183
  */
122
184
  export type LockOptions = {
123
185
  readonly lock?: "update" | "share";
@@ -126,6 +188,48 @@ export type LockOptions = {
126
188
  /** `find` options. `limit` is required unless the caller uses `.all(reason)`. */
127
189
  export type FindOptions<S extends QuerySchema, K extends keyof S["~byName"]> = ReadOptions<S, K> & {
128
190
  readonly limit?: number;
191
+ /** Text to look for. The closest matches come first unless `orderBy` is set. */
192
+ readonly search?: TextSearch<RowOf<S, K>>;
193
+ };
194
+ /**
195
+ * Options for `descendants` and `ancestors`.
196
+ *
197
+ * `depth` is how many steps from the starting row. Omit it to walk the whole
198
+ * tree. `self` includes that row. `relation` names which self-relation when
199
+ * the table has more than one.
200
+ */
201
+ export type TreeOptions<S extends QuerySchema, K extends keyof S["~byName"]> = CallOptions & {
202
+ readonly where?: WhereOf<S, K>;
203
+ readonly select?: readonly (keyof RowOf<S, K> & string)[];
204
+ readonly orderBy?: OrderBy<RowOf<S, K>>;
205
+ readonly depth?: number;
206
+ /** Include the starting row. Omitted leaves it out. */
207
+ readonly self?: boolean;
208
+ /** Which self-relation. Required when the table has more than one. */
209
+ readonly relation?: string;
210
+ };
211
+ /** Links `sync` added and removed. Values are the related row's primary key. */
212
+ export type SyncResult = {
213
+ readonly added: readonly unknown[];
214
+ readonly removed: readonly unknown[];
215
+ };
216
+ /** Options for `sync`. `expect` matches an update: the count is links added plus links removed. */
217
+ export type SyncOptions = CallOptions & {
218
+ readonly expect?: number;
219
+ };
220
+ /** The handle `sync` returns. */
221
+ export type SyncHandle = Promise<SyncResult> & {
222
+ /** The statement, before it runs. */
223
+ sql(): Promise<{
224
+ readonly statements: readonly {
225
+ readonly text: string;
226
+ readonly params?: readonly (string | null)[];
227
+ }[];
228
+ }>;
229
+ /** `{ ok, value }` or `{ ok, error }`. */
230
+ safe(): Promise<SafeResult<SyncResult>>;
231
+ /** Throws `not_found` when the number of added and removed links is not `count`. */
232
+ expect(count: number): SyncHandle;
129
233
  };
130
234
  /** A query handle. Await it, or inspect it before it runs. */
131
235
  export type Query<T> = Promise<T> & {
@@ -148,15 +252,27 @@ export type Read<T> = Query<T> & {
148
252
  all(reason: string): Read<T>;
149
253
  /** Turns a null `one()` into `not_found`. */
150
254
  required(): Read<NonNullable<T>>;
151
- /** Streams rows when the driver has `stream`. Otherwise OKM1111. */
152
- stream(): AsyncIterable<T extends readonly (infer R)[] ? R : T>;
255
+ /**
256
+ * Yields rows in keyset batches on every driver.
257
+ *
258
+ * `batch` is how many rows one query fetches. The default is 1000.
259
+ * `limit` on the find is the total. A table with no primary key is OKM1120.
260
+ */
261
+ stream(options?: {
262
+ readonly batch?: number;
263
+ }): AsyncIterable<T extends readonly (infer R)[] ? R : T>;
153
264
  };
154
265
  /** One page: the rows, and the cursor for the next page. `next` is `null` on the last page. */
155
266
  export type Page<Row> = {
156
267
  readonly items: readonly Row[];
157
268
  readonly next: string | null;
158
269
  };
159
- /** `page` options. `after` is the `next` of the page before. */
270
+ /**
271
+ * `page` options. `after` is the `next` of the page before.
272
+ *
273
+ * `page` refuses a window helper when the call runs (OKM1120). The keyset
274
+ * cursor has no window value to encode.
275
+ */
160
276
  export type PageOptions<S extends QuerySchema, K extends keyof S["~byName"]> = ReadOptions<S, K> & {
161
277
  /** Rows in the page. At least 1. */
162
278
  readonly limit: number;
@@ -172,25 +288,51 @@ export type PageOptions<S extends QuerySchema, K extends keyof S["~byName"]> = R
172
288
  type NumericKeys<Row> = {
173
289
  readonly [F in keyof Row]-?: [NonNullable<Row[F]>] extends [number | string] ? F : never;
174
290
  }[keyof Row] & string;
291
+ /** One `orderBy` value. `asc` is nulls last and `desc` is nulls first unless `nulls` is set. */
292
+ type SortDir = "asc" | "desc" | {
293
+ readonly dir: "asc" | "desc";
294
+ readonly nulls?: "first" | "last";
295
+ };
175
296
  /** `aggregate` options. A hidden field is refused at runtime. */
176
297
  export type AggregateOptions<S extends QuerySchema, K extends keyof S["~byName"]> = CallOptions & {
177
298
  readonly where?: WhereOf<S, K>;
178
299
  /** One result row per distinct combination. Needs `limit`, or `.all(reason)`. */
179
- readonly groupBy?: readonly (keyof RowOf<S, K> & string)[];
300
+ readonly groupBy?: readonly ((keyof RowOf<S, K> & string) | Bucket<string, string, string>)[];
180
301
  /** Adds `count`, the number of rows in the group. */
181
302
  readonly count?: true;
182
303
  readonly sum?: readonly NumericKeys<RowOf<S, K>>[];
183
304
  readonly avg?: readonly NumericKeys<RowOf<S, K>>[];
184
305
  readonly min?: readonly (keyof RowOf<S, K> & string)[];
185
306
  readonly max?: readonly (keyof RowOf<S, K> & string)[];
186
- /** Orders the groups. Only `groupBy` fields. Without it, groups come in `groupBy` order. */
187
- readonly orderBy?: OrderBy<RowOf<S, K>>;
307
+ /**
308
+ * Orders the groups. A `groupBy` field or a bucket `as`.
309
+ * Without it, groups come in `groupBy` order.
310
+ */
311
+ readonly orderBy?: OrderBy<RowOf<S, K>> | {
312
+ readonly [key: string]: SortDir | undefined;
313
+ };
188
314
  readonly limit?: number;
189
315
  };
316
+ /** `true` when a group entry is a bucket. A mix of fields and buckets is `boolean`. */
317
+ type HasBucket<G> = G extends Bucket<string, string, string> ? true : false;
318
+ /** One bucket key. A string group contributes nothing. */
319
+ type BucketPiece<Row, G> = G extends Bucket<infer C, infer U, infer A> ? {
320
+ readonly [K in A]: (U extends "second" | "minute" | "hour" ? Temporal.Instant : Temporal.PlainDate) | (C extends keyof Row ? (null extends Row[C] ? null : never) : null);
321
+ } : {};
322
+ /** Intersection of a union of group pieces. */
323
+ type Intersect<U> = (U extends unknown ? (arg: U) => void : never) extends (arg: infer I) => void ? I : unknown;
324
+ /**
325
+ * Group keys on an aggregate row.
326
+ *
327
+ * A plain field list stays `Pick`. A bucket list adds each `as` key. The value
328
+ * is `Temporal.PlainDate` for a calendar unit and `Temporal.Instant` for a
329
+ * clock unit, and includes `null` when the column does.
330
+ */
331
+ type GroupOf<Row, G> = boolean extends HasBucket<G> ? Pick<Row, Extract<G, keyof Row>> & Intersect<BucketPiece<Row, G>> : [G] extends [Bucket<string, string, string>] ? Intersect<BucketPiece<Row, G>> : Pick<Row, G & keyof Row>;
190
332
  /** A group: its fields, and the aggregates the call named. */
191
333
  export type AggregateRow<Row, O> = Show<(O extends {
192
334
  readonly groupBy: readonly (infer G)[];
193
- } ? Pick<Row, G & keyof Row> : unknown) & (O extends {
335
+ } ? GroupOf<Row, G> : unknown) & (O extends {
194
336
  readonly count: true;
195
337
  } ? {
196
338
  readonly count: number;
@@ -311,9 +453,15 @@ export type InsertOf<S extends QuerySchema, K extends keyof S["~byName"]> = S["~
311
453
  export type UpdateOf<S extends QuerySchema, K extends keyof S["~byName"]> = S["~byName"][K] extends {
312
454
  readonly "~update": infer U;
313
455
  } ? U : never;
314
- /** `set` values. `undefined` leaves the field unchanged. `inc` adds to it. `set` and `arr` write json and arrays. */
456
+ /**
457
+ * `set` values.
458
+ *
459
+ * `undefined` leaves the field unchanged. `null` sets null, and only on a
460
+ * nullable column. `inc` adds to a number or bigint column. A null number
461
+ * stays null. `json.set` and `arr` write json and arrays.
462
+ */
315
463
  export type UpdateSet<S extends QuerySchema, K extends keyof S["~byName"]> = {
316
- readonly [F in keyof UpdateOf<S, K>]?: UpdateOf<S, K>[F] | Inc<NonNullable<UpdateOf<S, K>[F]>> | WriteOp<NonNullable<UpdateOf<S, K>[F]>>;
464
+ readonly [F in keyof UpdateOf<S, K>]?: UpdateOf<S, K>[F] | IncOf<UpdateOf<S, K>[F]> | WriteOp<NonNullable<UpdateOf<S, K>[F]>>;
317
465
  };
318
466
  /** Conflict handling on `insert` (spec §11). */
319
467
  export type OnConflict<S extends QuerySchema, K extends keyof S["~byName"]> = "error" | "ignore" | {
@@ -337,7 +485,7 @@ export type InsertOptions<S extends QuerySchema, K extends keyof S["~byName"]> =
337
485
  };
338
486
  /** Options for `update` and `delete`. */
339
487
  export type WriteOptions<S extends QuerySchema, K extends keyof S["~byName"]> = {
340
- readonly returning?: readonly (keyof RowOf<S, K> & string)[];
488
+ readonly returning?: true | readonly (keyof RowOf<S, K> & string)[];
341
489
  /** Guarded fields this call may set. `delete` ignores it. */
342
490
  readonly allow?: readonly (keyof RowOf<S, K> & string)[];
343
491
  readonly expect?: number;
@@ -372,19 +520,32 @@ type AllowedSet<S extends QuerySchema, K extends keyof S["~byName"], Allow exten
372
520
  type AllowedUpdate<S extends QuerySchema, K extends keyof S["~byName"], Allow extends readonly (keyof RowOf<S, K> & string)[]> = {
373
521
  readonly where?: WhereOf<S, K>;
374
522
  readonly set: AllowedSet<S, K, Allow>;
523
+ readonly version?: number;
375
524
  } | readonly {
376
525
  readonly id?: unknown;
377
526
  readonly where?: WhereOf<S, K>;
378
527
  readonly set: AllowedSet<S, K, Allow>;
528
+ readonly version?: number;
379
529
  }[];
380
- /** One update, or a per-row list in one statement. */
530
+ /**
531
+ * One update, or a per-row list in one statement.
532
+ *
533
+ * `lock: "skip"` with `limit` claims that many matching rows and leaves rows
534
+ * another transaction already holds. It is not valid on a list.
535
+ */
381
536
  export type UpdateTarget<S extends QuerySchema, K extends keyof S["~byName"]> = {
382
537
  readonly where?: WhereOf<S, K>;
383
538
  readonly set: UpdateSet<S, K>;
539
+ readonly limit?: number;
540
+ readonly lock?: "skip";
541
+ /** Version read from the row. Required at runtime when the table is `versioned()`. */
542
+ readonly version?: number;
384
543
  } | readonly {
385
544
  readonly id?: unknown;
386
545
  readonly where?: WhereOf<S, K>;
387
546
  readonly set: UpdateSet<S, K>;
547
+ /** Version read from the row. Required at runtime when the table is `versioned()`. */
548
+ readonly version?: number;
388
549
  }[];
389
550
  /** `{ count, archiveId }` from one `archive()` call. */
390
551
  export type ArchiveCount = {
@@ -462,6 +623,7 @@ export type TableApi<S extends QuerySchema, K extends keyof S["~byName"] & strin
462
623
  };
463
624
  count(options?: CallOptions & {
464
625
  readonly where?: WhereOf<S, K>;
626
+ readonly search?: TextSearch<RowOf<S, K>>;
465
627
  }): Read<number>;
466
628
  exists(options?: CallOptions & {
467
629
  readonly where?: WhereOf<S, K>;
@@ -482,15 +644,49 @@ export type TableApi<S extends QuerySchema, K extends keyof S["~byName"] & strin
482
644
  * database default for that row; `null` stays NULL.
483
645
  */
484
646
  insert(data: readonly (RequiredInsert<InsertOf<S, K>> & OptionalInsert<InsertOf<S, K>>)[], options?: InsertOptions<S, K>): Write<readonly Show<RowOf<S, K>>[]>;
485
- /** Updates matching rows, or a per-row list in one statement. `where` is required. */
486
- update<const Allow extends readonly (keyof RowOf<S, K> & string)[]>(target: AllowedUpdate<S, K, Allow>, options: WriteOptions<S, K> & {
647
+ /**
648
+ * Updates matching rows, or a per-row list in one statement. `where` is required.
649
+ *
650
+ * `{ allow, returning: true }` returns the written rows. `{ allow }` without
651
+ * `returning: true` returns `{ count }`.
652
+ */
653
+ update<const Allow extends readonly (keyof RowOf<S, K> & string)[], const Opt extends WriteOptions<S, K> & {
487
654
  readonly allow: Allow;
488
- }): Write<WriteCount>;
655
+ }>(target: AllowedUpdate<S, K, Allow>, options: Opt): [Opt["returning"]] extends [true] ? Write<readonly Show<RowOf<S, K>>[]> : Write<WriteCount>;
656
+ update(target: UpdateTarget<S, K>, options: WriteOptions<S, K> & {
657
+ readonly returning: true;
658
+ }): Write<readonly Show<RowOf<S, K>>[]>;
489
659
  update(target: UpdateTarget<S, K>, options?: WriteOptions<S, K>): Write<WriteCount>;
490
- /** Deletes matching rows. `where` is required. */
660
+ /**
661
+ * Deletes matching rows. `where` is required.
662
+ *
663
+ * `{ returning: true }` is not accepted. Pass the field names, or omit
664
+ * `returning` for `{ count }`.
665
+ */
491
666
  delete(target: {
492
667
  readonly where?: WhereOf<S, K>;
493
- }, options?: WriteOptions<S, K>): Write<WriteCount>;
668
+ }, options?: Omit<WriteOptions<S, K>, "returning"> & {
669
+ readonly returning?: Exclude<WriteOptions<S, K>["returning"], true>;
670
+ }): Write<WriteCount>;
671
+ /**
672
+ * Rows below `id`, walking the table's self-relation.
673
+ *
674
+ * One statement. A row already seen is not entered again, so a cycle in the
675
+ * data returns. A missing id returns no rows. `where` and a preset filter
676
+ * the rows that come back. Tenancy and the active set apply at every step.
677
+ */
678
+ descendants<const O extends TreeOptions<S, K>>(id: unknown, options?: O): Query<readonly ResultRow<S, K, O>[]>;
679
+ /** Rows above `id`. The options match {@link TableApi.descendants}. */
680
+ ancestors<const O extends TreeOptions<S, K>>(id: unknown, options?: O): Query<readonly ResultRow<S, K, O>[]>;
681
+ /**
682
+ * Sets a to-many relation to exactly `ids`.
683
+ *
684
+ * One statement. A join table gains and loses link rows. A nullable foreign
685
+ * key is set or cleared, and the related row stays. A link that would have
686
+ * to delete a row is refused. Duplicate ids count once. An id that is not
687
+ * in the related table is `not_found`, and nothing is written.
688
+ */
689
+ sync(id: unknown, relation: string, ids: readonly unknown[], options?: SyncOptions): SyncHandle;
494
690
  } & (S["~byName"][K] extends {
495
691
  readonly "~archive": true;
496
692
  } ? ArchiveOps<S, K, L> : unknown) & PresetApi<S, K, L> & TableExtras<S, K>;
@@ -647,6 +843,16 @@ type ViewApi<Row> = {
647
843
  readonly where?: FieldWhere<Row>;
648
844
  }): Read<boolean>;
649
845
  };
846
+ /**
847
+ * `refresh()` on a materialized view.
848
+ *
849
+ * No arguments. It runs `REFRESH MATERIALIZED VIEW`, with `CONCURRENTLY` when
850
+ * the view declares `refresh: "concurrently"`. It is a write, so it uses the
851
+ * primary. It is not tenant-scoped: a scoped client still refreshes the whole view.
852
+ */
853
+ type MaterializedViewApi<Row> = ViewApi<Row> & {
854
+ refresh(): Promise<void>;
855
+ };
650
856
  /** `db.views`, typed from `schema({ views })`. Absent when the schema declares none. */
651
857
  type ViewsClient<S> = S extends {
652
858
  readonly "~views": infer V extends readonly unknown[];
@@ -654,7 +860,9 @@ type ViewsClient<S> = S extends {
654
860
  readonly views: {
655
861
  readonly [D in V[number] as D extends {
656
862
  readonly name: infer N extends string;
657
- } ? CamelName<N> : never]: ViewApi<Show<ViewRow<D>>>;
863
+ } ? CamelName<N> : never]: D extends {
864
+ readonly "~kind": "materialized";
865
+ } ? MaterializedViewApi<Show<ViewRow<D>>> : ViewApi<Show<ViewRow<D>>>;
658
866
  };
659
867
  } : unknown;
660
868
  /** A client whose tables are already inside one tenant or an unscoped reason. */
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  validationGate
3
- } from "../../shared/9m80mkac.js";
3
+ } from "../../shared/ze4hxsmy.js";
4
4
  import {
5
5
  addSchemaHook
6
- } from "../../shared/5enne4ma.js";
6
+ } from "../../shared/xnxsed62.js";
7
7
  import {
8
8
  queryHandle
9
- } from "../../shared/hf22e0wt.js";
9
+ } from "../../shared/tbrvgw6z.js";
10
10
  import {
11
11
  OkmError2
12
12
  } from "../../shared/52szzakm.js";
@@ -14,7 +14,7 @@ import {
14
14
  // src/runtime/validate/load.ts
15
15
  var engine;
16
16
  function loadEngine() {
17
- engine ??= import("../../shared/8rsy3hxz.js");
17
+ engine ??= import("../../shared/h15jx9bc.js");
18
18
  return engine;
19
19
  }
20
20
 
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Optimistic version checks.
3
+ *
4
+ * Loaded on the first update of a `versioned()` table. A plain update does
5
+ * not import it. The check and the bump are one statement: a stale row is
6
+ * not written, and the caller hears category `conflict`.
7
+ */
8
+ import type { Statement } from "../contracts/driver.js";
9
+ import type { QuerySchema } from "../dialects/pg/model.js";
10
+ import { type Outputs } from "./plan.js";
11
+ import { type Indexed } from "./plan.js";
12
+ import { type WriteMods } from "./write.js";
13
+ /** What {@link planVersioned} hands back to the write path. */
14
+ export type VersionPlan = {
15
+ readonly statements: readonly Statement[];
16
+ readonly outputs: Outputs;
17
+ readonly shape: "count" | "rows";
18
+ readonly expect: number | undefined;
19
+ /** Fields the caller tried to write, and the versions they sent. */
20
+ readonly versioned: {
21
+ readonly fields: readonly string[];
22
+ readonly sent: readonly number[];
23
+ };
24
+ };
25
+ /**
26
+ * Plans an update that checks `version` and bumps it.
27
+ *
28
+ * A list carries one version per row. `lock: "skip"` claims rows at that
29
+ * version and leaves locked rows. `.all()` is refused. An upsert is refused
30
+ * by the insert planner, not here.
31
+ *
32
+ * @param schema - Connected schema
33
+ * @param table - Target table
34
+ * @param input - `{ where, set, version }` or a per-row list
35
+ * @param options - Returning, expect, signal, timeout
36
+ * @param mods - `.expect`. `.all` is refused
37
+ * @returns One statement, and the versions the caller sent
38
+ */
39
+ export declare function planVersioned(schema: QuerySchema, table: Indexed, input: unknown, options: Record<string, unknown>, mods: WriteMods): VersionPlan;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Window helpers in `select` (spec §10, §13 tool 12).
3
+ *
4
+ * Loaded on the first `find` or `one` whose `select` contains a helper.
5
+ * A plain list of field names never loads this module. `page` does not take
6
+ * a window: its select is field names, and the keyset cursor has no window
7
+ * value to encode.
8
+ */
9
+ import type { QuerySchema } from "../dialects/pg/model.js";
10
+ import { type ReadCall } from "./plan.js";
11
+ /**
12
+ * Plans a read whose `select` contains a window helper.
13
+ *
14
+ * The returned call writes the statement. Includes, tenancy, and presets stay
15
+ * on the planner the plain read uses.
16
+ *
17
+ * @param schema - Connected schema
18
+ * @param call - The read, with a window in `select`
19
+ * @returns The same read, with its statement builder set
20
+ */
21
+ export declare function attach(schema: QuerySchema, call: ReadCall): ReadCall;
@@ -6,9 +6,9 @@
6
6
  */
7
7
  import type { ExecuteOptions, ExecuteResult, Statement } from "../contracts/driver.js";
8
8
  import type { IdGenerators } from "../contracts/generator.js";
9
- import type { PresetUse } from "../dialects/pg/model.js";
9
+ import type { ColumnModel, PresetUse } from "../dialects/pg/model.js";
10
10
  import type { QuerySchema } from "../dialects/pg/model.js";
11
- import { type ArchiveView, type CallScope } from "./plan.js";
11
+ import { type ArchiveView, type CallScope, type Indexed, type Sink } from "./plan.js";
12
12
  import { type RunHost } from "./tx.js";
13
13
  /** Statements in one insert stay under this many parameters. The protocol limit is 65535. */
14
14
  export declare const WRITE_PARAM_BUDGET = 2048;
@@ -39,8 +39,15 @@ export type PreparedWrite = {
39
39
  readonly statements: readonly Statement[];
40
40
  readonly options: ExecuteOptions | undefined;
41
41
  /** Set when `finish` can refuse a statement that already ran. `batch` refuses such a write (D183). */
42
- readonly checked?: "restore" | "expect";
42
+ readonly checked?: "restore" | "expect" | "parent";
43
43
  finish(results: readonly ExecuteResult[]): unknown;
44
+ /**
45
+ * More statements once the planned ones have run.
46
+ *
47
+ * First-or-create uses this when the insert returned fewer rows than it was
48
+ * given. Empty means the insert already returned every row.
49
+ */
50
+ follow?(results: readonly ExecuteResult[]): readonly Statement[];
44
51
  };
45
52
  /**
46
53
  * Runs a write and decodes it.
@@ -71,3 +78,48 @@ export declare function executeWrite(host: WriteHost, op: WriteOp, table: string
71
78
  export declare function explainWrite(schema: QuerySchema, op: WriteOp, table: string, input: unknown, options: object, mods: WriteMods, generators?: IdGenerators, scope?: CallScope): Promise<{
72
79
  readonly statements: readonly Statement[];
73
80
  }>;
81
+ export declare function updateSliceBody(schema: QuerySchema, table: Indexed, rows: readonly {
82
+ readonly where: unknown;
83
+ readonly set: Record<string, unknown>;
84
+ }[], sql: Sql, wrapWhere?: boolean, hooks?: {
85
+ afterWhere?(sql: Sql, index: number): void;
86
+ afterSet?(sql: Sql): void;
87
+ }): void;
88
+ export declare function rejectDuplicateTargets(table: Indexed, rows: readonly {
89
+ readonly where: unknown;
90
+ }[]): void;
91
+ export declare function emitSet(sql: Sql, table: Indexed, set: Record<string, unknown>, alias: string): void;
92
+ export declare class Sql {
93
+ private readonly parts;
94
+ private readonly params;
95
+ text(value: string): void;
96
+ /**
97
+ * Binds one parameter.
98
+ *
99
+ * An empty data type leaves the parameter uncast so `where` can infer it.
100
+ */
101
+ param(wire: string | null, dataType: string): void;
102
+ sink(): Sink;
103
+ statement(): Statement;
104
+ }
105
+ export declare function writeSet(table: Indexed, value: unknown, allow: ReadonlySet<string>, tenancy: QuerySchema["tenancy"]): Record<string, unknown>;
106
+ /**
107
+ * A list that sets one field with an operator in one row and a plain value,
108
+ * or a different operator, in another.
109
+ */
110
+ export declare function rejectMixedSets(rows: readonly {
111
+ readonly set: Record<string, unknown>;
112
+ }[]): void;
113
+ /**
114
+ * `lock: "skip"` with `limit` on one update. Absent when the caller named neither.
115
+ *
116
+ * @param input - The update target
117
+ * @returns The row cap, or `undefined` when this update does not claim
118
+ */
119
+ export declare function readClaim(input: Record<string, unknown>): number | undefined;
120
+ export declare function rejectUpdateKeys(input: Record<string, unknown>, row: boolean): void;
121
+ export declare function requireFilter(table: Indexed, where: unknown, mods: WriteMods, op: WriteOp): void;
122
+ export declare function returningOption(table: Indexed, value: unknown): readonly ColumnModel[] | undefined;
123
+ export declare function expectOf(options: Record<string, unknown>, mods: WriteMods): number | undefined;
124
+ export declare function allowSet(table: Indexed, value: unknown): ReadonlySet<string>;
125
+ export declare function noteGuarded(table: Indexed, allow: ReadonlySet<string>, op: "insert" | "update"): void;
@@ -6,7 +6,7 @@ import {
6
6
  runCall,
7
7
  EMPTY_NOTICES,
8
8
  resultFrom
9
- } from "./cgbamx3e.js";
9
+ } from "./kb2sdhfb.js";
10
10
 
11
11
  // src/adapters/pg/postgresjs.ts
12
12
  import net from "node:net";
@@ -62,13 +62,15 @@ class PoolSockets {
62
62
  }
63
63
  wake() {
64
64
  for (const socket of this.held)
65
- socket.ref();
65
+ if (socket.writable)
66
+ socket.ref();
66
67
  }
67
68
  park() {
68
69
  if (this.busy > 0 || this.listeners > 0)
69
70
  return;
70
71
  for (const socket of this.held)
71
- socket.unref();
72
+ if (socket.writable)
73
+ socket.unref();
72
74
  }
73
75
  }
74
76
  function driverOptions(config, state) {
@@ -115,26 +117,18 @@ function open2(config) {
115
117
  execute(text, params, options) {
116
118
  return sockets.occupy(() => runCall(closed, options, (watch) => root.query(text, params, watch)));
117
119
  },
118
- async batch(statements, options) {
119
- return sockets.occupy(async () => {
120
- const { checkout } = await import("./caw8b9d8.js");
121
- const connection = await checkout(held);
122
- try {
123
- return await connection.batch(statements, options);
124
- } finally {
125
- await connection.release();
126
- }
127
- });
120
+ batch(statements, options) {
121
+ return sockets.occupy(() => import("./je4axnm8.js").then((mod) => mod.runBatch(held, statements, options)));
128
122
  },
129
123
  reserve() {
130
124
  const gate = sockets.busyGate();
131
125
  gate.enter();
132
- return import("./caw8b9d8.js").then((mod) => mod.holdCheckout(gate, () => mod.checkout(held)), (error) => {
126
+ return import("./je4axnm8.js").then((mod) => mod.holdCheckout(gate, () => mod.checkout(held)), (error) => {
133
127
  gate.leave();
134
128
  throw error;
135
129
  });
136
130
  },
137
- describe: (text, params) => sockets.occupy(() => import("./caw8b9d8.js").then((mod) => mod.describe(sql, text, params))),
131
+ describe: (text, params) => sockets.occupy(() => import("./je4axnm8.js").then((mod) => mod.describe(sql, text, params))),
138
132
  stream(text, params) {
139
133
  const gate = sockets.busyGate();
140
134
  return async function* () {
@@ -149,7 +143,7 @@ function open2(config) {
149
143
  listen(channel, onNotify) {
150
144
  const gate = sockets.listenerGate();
151
145
  gate.enter();
152
- return import("./caw8b9d8.js").then((mod) => mod.holdListener(gate, async () => {
146
+ return import("./je4axnm8.js").then((mod) => mod.holdListener(gate, async () => {
153
147
  const listening = await sql.listen(channel, onNotify);
154
148
  return async () => {
155
149
  await listening.unlisten();
@@ -219,7 +213,7 @@ class PgSession {
219
213
  onAbort();
220
214
  else
221
215
  watch.signal.addEventListener("abort", onAbort, { once: true });
222
- return import("./caw8b9d8.js").then((mod) => mod.watchQuery(pending, watch, onAbort, {
216
+ return import("./je4axnm8.js").then((mod) => mod.watchQuery(pending, watch, onAbort, {
223
217
  start,
224
218
  text,
225
219
  notices: this.notices,
@@ -271,7 +265,7 @@ class PgSession {
271
265
  }
272
266
  }
273
267
  async function* loadStream(sql, text, params) {
274
- const { stream } = await import("./caw8b9d8.js");
268
+ const { stream } = await import("./je4axnm8.js");
275
269
  yield* stream(sql, text, params);
276
270
  }
277
271
  function send(sql, text, params, named) {