okmodel 0.6.0 → 0.8.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 (267) hide show
  1. package/README.md +100 -1131
  2. package/dist/adapters/capabilities.d.ts +35 -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/bun-sql.d.ts +53 -0
  6. package/dist/adapters/pg/bunsql-extra.d.ts +54 -3
  7. package/dist/adapters/pg/bunsql.d.ts +15 -2
  8. package/dist/adapters/pg/cursor.d.ts +17 -0
  9. package/dist/adapters/pg/neon-extra.d.ts +18 -0
  10. package/dist/adapters/pg/neon.d.ts +104 -0
  11. package/dist/adapters/pg/no-inflight-timeout.d.ts +11 -8
  12. package/dist/adapters/pg/nodepostgres-extra.d.ts +22 -1
  13. package/dist/adapters/pg/nodepostgres.d.ts +12 -0
  14. package/dist/adapters/pg/pglite-wire.d.ts +24 -0
  15. package/dist/adapters/pg/pglite.d.ts +10 -0
  16. package/dist/adapters/pg/postgres-extra.d.ts +27 -11
  17. package/dist/adapters/pg/reserved.d.ts +42 -0
  18. package/dist/adapters/pg/session.d.ts +0 -18
  19. package/dist/contracts/connection.d.ts +7 -6
  20. package/dist/contracts/error.d.ts +1 -1
  21. package/dist/dialects/pg/floor.d.ts +68 -0
  22. package/dist/dialects/pg/fn/index.d.ts +39 -1
  23. package/dist/dialects/pg/fn/index.js +118 -26
  24. package/dist/dialects/pg/index.d.ts +8 -1
  25. package/dist/dialects/pg/index.js +435 -170
  26. package/dist/dialects/pg/introspect.d.ts +11 -0
  27. package/dist/dialects/pg/keys.d.ts +11 -8
  28. package/dist/dialects/pg/model.d.ts +40 -0
  29. package/dist/dialects/pg/morph.d.ts +43 -0
  30. package/dist/dialects/pg/operator-fit.d.ts +2 -2
  31. package/dist/dialects/pg/operators.d.ts +14 -7
  32. package/dist/dialects/pg/ops/bucket.d.ts +65 -0
  33. package/dist/dialects/pg/ops/fragment.d.ts +119 -0
  34. package/dist/dialects/pg/ops/inc.d.ts +2 -2
  35. package/dist/dialects/pg/ops/lane.d.ts +49 -0
  36. package/dist/dialects/pg/ops/matches.d.ts +9 -12
  37. package/dist/dialects/pg/ops/relevance.d.ts +13 -0
  38. package/dist/dialects/pg/ops/search-query.d.ts +22 -0
  39. package/dist/dialects/pg/ops/window.d.ts +103 -0
  40. package/dist/dialects/pg/preset.d.ts +1 -1
  41. package/dist/dialects/pg/relations.d.ts +100 -3
  42. package/dist/dialects/pg/schema.d.ts +31 -3
  43. package/dist/dialects/pg/view/client.d.ts +14 -6
  44. package/dist/dialects/pg/view/index.d.ts +73 -1
  45. package/dist/dialects/pg/view/index.js +156 -5
  46. package/dist/dialects/pg/view/scratch.d.ts +8 -5
  47. package/dist/runtime/aggregate.d.ts +8 -2
  48. package/dist/runtime/bucket-group.d.ts +70 -0
  49. package/dist/runtime/conflict.d.ts +22 -4
  50. package/dist/runtime/include.d.ts +0 -8
  51. package/dist/runtime/inflight.d.ts +1 -1
  52. package/dist/runtime/otel.d.ts +105 -0
  53. package/dist/runtime/otel.js +97 -0
  54. package/dist/runtime/page.d.ts +4 -1
  55. package/dist/runtime/pg/bun.js +12 -6
  56. package/dist/runtime/pg/neon.d.ts +38 -0
  57. package/dist/runtime/pg/neon.js +64 -0
  58. package/dist/runtime/pg/pg.js +5 -5
  59. package/dist/runtime/pg/pglite.d.ts +1 -0
  60. package/dist/runtime/pg/pglite.js +9 -9
  61. package/dist/runtime/pg/postgresjs.js +5 -5
  62. package/dist/runtime/plan.d.ts +95 -5
  63. package/dist/runtime/read-stream.d.ts +13 -16
  64. package/dist/runtime/result-name.d.ts +17 -0
  65. package/dist/runtime/server-check.d.ts +3 -3
  66. package/dist/runtime/sort-bind.d.ts +21 -0
  67. package/dist/runtime/sort.d.ts +56 -0
  68. package/dist/runtime/sql-fragment.d.ts +43 -0
  69. package/dist/runtime/sync.d.ts +70 -0
  70. package/dist/runtime/tenancy/index.js +15 -13
  71. package/dist/runtime/text-search.d.ts +20 -0
  72. package/dist/runtime/topology.d.ts +1 -1
  73. package/dist/runtime/traits/index.d.ts +80 -0
  74. package/dist/runtime/traits/index.js +184 -21
  75. package/dist/runtime/tree.d.ts +38 -0
  76. package/dist/runtime/types.d.ts +232 -22
  77. package/dist/runtime/validate/index.js +4 -4
  78. package/dist/runtime/version.d.ts +39 -0
  79. package/dist/runtime/window.d.ts +21 -0
  80. package/dist/runtime/write.d.ts +54 -2
  81. package/dist/shared/{929h19xp.js → 0wrea3jq.js} +141 -13
  82. package/dist/shared/{qq3899ht.js → 12z7aznj.js} +243 -14
  83. package/dist/shared/{1z04fa85.js → 14x60fbf.js} +12 -57
  84. package/dist/shared/{ek2wt2dz.js → 16kvjebh.js} +4 -4
  85. package/dist/shared/{wynzeggs.js → 195pzzzz.js} +8 -8
  86. package/dist/shared/1d9q9cv2.js +312 -0
  87. package/dist/shared/2c13q96h.js +18 -0
  88. package/dist/shared/{b4v57v3x.js → 2d3xq4ps.js} +2 -2
  89. package/dist/shared/{1f0xa3cb.js → 3449rcae.js} +5 -5
  90. package/dist/shared/{wkme6tep.js → 35q0n9tz.js} +8 -16
  91. package/dist/shared/3bb7wsqt.js +99 -0
  92. package/dist/shared/3t6kw83m.js +249 -0
  93. package/dist/shared/{5j36z8dn.js → 4m6hskg8.js} +39 -70
  94. package/dist/shared/{n076ydsc.js → 4vbf83xx.js} +69 -28
  95. package/dist/shared/{vmfkhszw.js → 63f4ksbz.js} +33 -26
  96. package/dist/shared/{c58secgj.js → 63qtkrca.js} +38 -4
  97. package/dist/shared/6m78c8ss.js +6 -0
  98. package/dist/shared/{x3jc53kg.js → 760ppr76.js} +15 -7
  99. package/dist/shared/7ghwamrf.js +40 -0
  100. package/dist/shared/7kms6fvj.js +20 -0
  101. package/dist/shared/7n7ddwt4.js +6 -0
  102. package/dist/shared/9a4ae4p8.js +31 -0
  103. package/dist/shared/{hazqqecq.js → 9dr2qnx7.js} +63 -34
  104. package/dist/shared/{h15jx9bc.js → 9dvh1dr6.js} +1 -1
  105. package/dist/shared/a62rb2da.js +13 -0
  106. package/dist/shared/{cgbamx3e.js → ae4j5f42.js} +23 -4
  107. package/dist/shared/agsfb86s.js +233 -0
  108. package/dist/shared/{8x72s86k.js → b6d6p0zc.js} +13 -7
  109. package/dist/shared/{ag4c7516.js → b76b8d95.js} +2 -2
  110. package/dist/shared/{j60w0dvr.js → bah9nbg3.js} +58 -38
  111. package/dist/shared/bnby0esn.js +10 -0
  112. package/dist/shared/bsek72fg.js +225 -0
  113. package/dist/shared/{2cg3wnxc.js → bxas03mq.js} +608 -141
  114. package/dist/shared/{31vm914h.js → cm3w0ywp.js} +15 -16
  115. package/dist/shared/{gwn6v667.js → cnkky55j.js} +25 -14
  116. package/dist/shared/{dk8v79p3.js → d5nmj7vv.js} +1 -1
  117. package/dist/shared/{ttmg09vd.js → dpc2r7rb.js} +8 -8
  118. package/dist/shared/dzj09cye.js +10 -0
  119. package/dist/shared/{sbdme3vy.js → e8zyaqvj.js} +60 -10
  120. package/dist/shared/{2jd1sn0e.js → ecn8mfdq.js} +6 -6
  121. package/dist/shared/exn3sd90.js +359 -0
  122. package/dist/shared/{t3g0k88x.js → f4jy1j7x.js} +39 -22
  123. package/dist/shared/{y2t3jktd.js → fjpnhqan.js} +20 -13
  124. package/dist/shared/g5yc06ka.js +272 -0
  125. package/dist/shared/ga9j92qj.js +25 -0
  126. package/dist/shared/{3fqwmr09.js → hfqmpasr.js} +6 -6
  127. package/dist/shared/{wt5rzv1h.js → hm5f8jby.js} +7 -7
  128. package/dist/shared/{ys0xzyaj.js → hqpxf4a4.js} +224 -19
  129. package/dist/shared/jebgrkeq.js +179 -0
  130. package/dist/shared/{09p049xa.js → jp36k7dp.js} +44 -16
  131. package/dist/shared/jx2m62cs.js +96 -0
  132. package/dist/shared/{r11n8grd.js → k86n8vq3.js} +7 -4
  133. package/dist/shared/{2z7wv5tj.js → kgwp4jdd.js} +56 -35
  134. package/dist/shared/{knmes2kh.js → kj9d8maq.js} +1 -1
  135. package/dist/shared/{g90m9b0g.js → m4xff2a6.js} +6 -5
  136. package/dist/shared/{r6nwkxnt.js → m7n9h2a5.js} +4 -4
  137. package/dist/shared/mfedzr74.js +145 -0
  138. package/dist/shared/{f0f1n281.js → mkrn359n.js} +60 -11
  139. package/dist/shared/{p248q79y.js → mnvjvqyp.js} +10 -10
  140. package/dist/shared/{672t5vym.js → mss6ctgv.js} +2 -2
  141. package/dist/shared/{4az561fn.js → mtw6jz76.js} +8 -23
  142. package/dist/shared/n05z9nwz.js +313 -0
  143. package/dist/shared/{pjr6xrm5.js → n0jmpgj1.js} +20 -17
  144. package/dist/shared/{p6bjzq9q.js → n41w4fbz.js} +14 -6
  145. package/dist/shared/{b3awxn7h.js → n454kcnw.js} +1 -1
  146. package/dist/shared/n7kg8mmx.js +61 -0
  147. package/dist/shared/nbw1z4yd.js +18 -0
  148. package/dist/shared/needfe47.js +66 -0
  149. package/dist/shared/{1nw1f3vs.js → njga14v4.js} +9 -9
  150. package/dist/shared/{5yv4k6a6.js → nmnsgj7x.js} +145 -3
  151. package/dist/shared/{vjpnzwjz.js → p3xbdcvt.js} +14 -18
  152. package/dist/shared/p5nh3r8q.js +622 -0
  153. package/dist/shared/{nx9hh281.js → pan0370z.js} +13 -12
  154. package/dist/shared/q0cqt2sp.js +12 -0
  155. package/dist/shared/qd9hhd8f.js +37 -0
  156. package/dist/shared/{mb2ycs1p.js → qfw14tna.js} +15 -15
  157. package/dist/shared/{9s0ypp87.js → sjk86yrx.js} +1 -1
  158. package/dist/shared/th3be82n.js +208 -0
  159. package/dist/shared/{ed0b8k4s.js → typ3vy7t.js} +1 -1
  160. package/dist/shared/{5d8t84hg.js → v1wad97q.js} +14 -14
  161. package/dist/shared/{x72jb7ad.js → v8g1vgv8.js} +1 -1
  162. package/dist/shared/{9628a9xt.js → vk7rag46.js} +1 -1
  163. package/dist/shared/{ze4hxsmy.js → w9ejzaqf.js} +1 -1
  164. package/dist/shared/{q3j1tq7a.js → wcrheftc.js} +148 -23
  165. package/dist/shared/wvdjznah.js +213 -0
  166. package/dist/shared/wz2a78mp.js +8 -0
  167. package/dist/shared/xfhe73sb.js +436 -0
  168. package/dist/shared/{r1fdd0f6.js → z581d7ny.js} +5 -2
  169. package/dist/shared/{8etn7d8w.js → z7s6fpxv.js} +1 -1
  170. package/dist/shared/{32cnm7kn.js → zbqbmmrp.js} +76 -40
  171. package/dist/shared/{n7mcc1gk.js → zchaghkf.js} +4 -3
  172. package/dist/shared/{xq0mvhts.js → zgex00fd.js} +6 -6
  173. package/dist/shared/{nsva2a6b.js → znm0bpp5.js} +3 -0
  174. package/dist/shared/zq1he88x.js +155 -0
  175. package/dist/tooling/cli.js +26 -13
  176. package/dist/tooling/driver-run.js +4971 -0
  177. package/dist/tooling/driver-test.d.ts +36 -0
  178. package/dist/tooling/migrate/commands.d.ts +2 -2
  179. package/dist/tooling/migrate/engine.d.ts +3 -2
  180. package/dist/tooling/migrate/index.js +9 -9
  181. package/dist/tooling/migrate/project.d.ts +3 -0
  182. package/dist/tooling/shared/03k6res6.js +210 -0
  183. package/dist/tooling/shared/08kemxjd.js +10 -0
  184. package/dist/tooling/shared/2revefqt.js +209 -0
  185. package/dist/tooling/shared/2wtvc7rw.js +1425 -0
  186. package/dist/tooling/shared/345tbc2k.js +16 -0
  187. package/dist/tooling/shared/3m1hkg7z.js +344 -0
  188. package/dist/tooling/shared/3rrw5w8f.js +81 -0
  189. package/dist/tooling/shared/3tq8pnb8.js +131 -0
  190. package/dist/tooling/shared/417zdsk7.js +194 -0
  191. package/dist/tooling/shared/4d2w25vw.js +40 -0
  192. package/dist/tooling/shared/54tqkxja.js +51 -0
  193. package/dist/tooling/shared/5bvw2nev.js +12 -0
  194. package/dist/tooling/shared/6nyfyw70.js +231 -0
  195. package/dist/tooling/shared/72fyg4zv.js +160 -0
  196. package/dist/tooling/shared/733a1tq3.js +38 -0
  197. package/dist/tooling/shared/7ae7rjmn.js +20 -0
  198. package/dist/tooling/shared/7kms6fvj.js +20 -0
  199. package/dist/tooling/shared/8sqrsw3s.js +49 -0
  200. package/dist/tooling/shared/96ps4g1z.js +32 -0
  201. package/dist/tooling/shared/9kazs5p6.js +195 -0
  202. package/dist/tooling/shared/9xzm7hjg.js +38 -0
  203. package/dist/tooling/shared/a6pp9d12.js +49 -0
  204. package/dist/tooling/shared/a7q7t4n3.js +22 -0
  205. package/dist/tooling/shared/aftb2mwr.js +18 -0
  206. package/dist/tooling/shared/bz2dqhab.js +311 -0
  207. package/dist/tooling/shared/cmptmb4f.js +12 -0
  208. package/dist/tooling/shared/ddjtfgnx.js +177 -0
  209. package/dist/tooling/shared/djydjpqt.js +261 -0
  210. package/dist/tooling/shared/dw08f3m8.js +9 -0
  211. package/dist/tooling/shared/dy672fz6.js +16 -0
  212. package/dist/tooling/shared/dzx85q70.js +66 -0
  213. package/dist/tooling/shared/ec71zqgt.js +270 -0
  214. package/dist/{shared/d5azex6s.js → tooling/shared/ep8zh3bk.js} +1 -1
  215. package/dist/tooling/shared/f9mphxej.js +3789 -0
  216. package/dist/tooling/shared/fb9k2qwd.js +89 -0
  217. package/dist/tooling/shared/g9ad4n80.js +211 -0
  218. package/dist/tooling/shared/gfvtj6d0.js +94 -0
  219. package/dist/tooling/shared/gmcf9cxf.js +294 -0
  220. package/dist/tooling/shared/htnaj77v.js +17 -0
  221. package/dist/tooling/shared/j9t5s12a.js +7 -0
  222. package/dist/tooling/shared/jne7b93p.js +42 -0
  223. package/dist/tooling/shared/ma2340rx.js +118 -0
  224. package/dist/tooling/shared/mtrqn2hn.js +505 -0
  225. package/dist/tooling/shared/n4jqhpqz.js +27 -0
  226. package/dist/tooling/shared/nf7jmhfa.js +20 -0
  227. package/dist/tooling/shared/p7f08ktn.js +332 -0
  228. package/dist/tooling/shared/ppnnnvj8.js +13 -0
  229. package/dist/tooling/shared/pqy21k24.js +312 -0
  230. package/dist/tooling/shared/pw8fgahx.js +69 -0
  231. package/dist/tooling/shared/pwsytxm5.js +17 -0
  232. package/dist/tooling/shared/rf83gr2d.js +94 -0
  233. package/dist/tooling/shared/rq5kk8j6.js +401 -0
  234. package/dist/tooling/shared/rs1jb051.js +12 -0
  235. package/dist/tooling/shared/smn6kz1p.js +157 -0
  236. package/dist/tooling/shared/spk1jg3r.js +1696 -0
  237. package/dist/tooling/shared/tn8gay14.js +143 -0
  238. package/dist/tooling/shared/vraj6d74.js +42 -0
  239. package/dist/tooling/shared/vs0t6qt8.js +64 -0
  240. package/dist/tooling/shared/vx86qjv8.js +150 -0
  241. package/dist/tooling/shared/w7qe8sj1.js +140 -0
  242. package/dist/tooling/shared/wt7j7nf6.js +15 -0
  243. package/dist/tooling/shared/wwnekq5n.js +6 -0
  244. package/dist/tooling/shared/xhrnjch9.js +185 -0
  245. package/dist/tooling/shared/xjs6zqtc.js +190 -0
  246. package/dist/tooling/shared/y031jct9.js +16 -0
  247. package/dist/tooling/shared/y5656f0e.js +233 -0
  248. package/dist/tooling/shared/yfr8hzhm.js +604 -0
  249. package/dist/tooling/shared/yk9mp7vb.js +250 -0
  250. package/dist/tooling/shared/yw30vnq2.js +139 -0
  251. package/dist/tooling/shared/z8d7ptht.js +618 -0
  252. package/dist/tooling/shared/zhwnfyb2.js +9 -0
  253. package/dist/tooling/shared/zvnhh1n0.js +198 -0
  254. package/dist/tooling/testing/index.js +3 -3
  255. package/package.json +17 -3
  256. package/dist/shared/3qnhc7w5.js +0 -38
  257. package/dist/shared/7m88x3e9.js +0 -45
  258. package/dist/shared/8dqhth8c.js +0 -12
  259. package/dist/shared/j3rkk835.js +0 -99
  260. package/dist/shared/k68eedmy.js +0 -85
  261. package/dist/shared/venqrjna.js +0 -216
  262. package/dist/shared/wxr8cwns.js +0 -6
  263. package/dist/shared/y34a8714.js +0 -150
  264. package/dist/shared/zm0mafk4.js +0 -92
  265. package/dist/shared/zy8r7qvz.js +0 -116
  266. package/dist/shared/{ywr8hmey.js → 606g0nbf.js} +3 -3
  267. package/dist/shared/{rpycarcr.js → gcefca6p.js} +4 -4
@@ -0,0 +1,198 @@
1
+ import {
2
+ decodeRows,
3
+ readHandle,
4
+ readCall,
5
+ attachHttp
6
+ } from "./mtrqn2hn.js";
7
+ import {
8
+ OkmError,
9
+ throwNamed,
10
+ selectedColumns,
11
+ parseOrder,
12
+ rejectKeys,
13
+ readLimit,
14
+ indexes,
15
+ quote,
16
+ list,
17
+ isRecord,
18
+ registerFailFix,
19
+ fail2
20
+ } from "./f9mphxej.js";
21
+
22
+ // src/runtime/page.ts
23
+ registerFailFix("OKM1130", "Request the next page with the same orderBy and the exact next value the previous page returned. The cursor encodes that order.");
24
+ var OPTIONS = [
25
+ "where",
26
+ "select",
27
+ "orderBy",
28
+ "limit",
29
+ "include",
30
+ "after",
31
+ "route",
32
+ "signal",
33
+ "timeout"
34
+ ];
35
+ function build3(session, table, options, mods, view, pin) {
36
+ try {
37
+ return plan(session, table, options, mods, view, pin);
38
+ } catch (error) {
39
+ throw error instanceof OkmError ? attachHttp(session.http, error) : error;
40
+ }
41
+ }
42
+ function plan(session, table, options, mods, view, pin) {
43
+ const record = isRecord(options) ? options : {};
44
+ if (Object.hasOwn(record, "search")) {
45
+ fail2("OKM1120", "page() does not take search in this version. Use find({ search, limit }) for a ranked list.", "Ranked pages are later. find({ search, limit }) returns one ranked list.");
46
+ }
47
+ rejectKeys(record, OPTIONS, "page");
48
+ const indexed = indexes(session.schema).get(table);
49
+ if (indexed === undefined)
50
+ fail2("OKM1120", `Table ${table} is not in the schema.`);
51
+ if (record.limit === undefined)
52
+ fail2("OKM1101", "page() needs a limit.");
53
+ const size = readLimit(record.limit);
54
+ if (size < 1) {
55
+ throw new OkmError("invalid", "page() limit must be at least 1.", { kind: "invalid" });
56
+ }
57
+ const keys = orderKeys(indexed, record.orderBy);
58
+ const signature = `${table}:${keys.map((key) => `${key.column.field}.${key.dir}.${key.nulls}`).join(",")}`;
59
+ const after = record.after === undefined || record.after === null ? undefined : keyset(keys, signature, record.after);
60
+ const wanted = selectedColumns(indexed, record.select);
61
+ const extra = keys.filter((key) => !wanted.includes(key.column)).map((key) => key.column.field);
62
+ const select = extra.length === 0 ? record.select : [...wanted.map((column) => column.field), ...extra];
63
+ const orderBy = {};
64
+ for (const key of keys)
65
+ orderBy[key.column.field] = { dir: key.dir, nulls: key.nulls };
66
+ const call = {
67
+ ...readCall("find", table, {
68
+ where: record.where,
69
+ select,
70
+ orderBy,
71
+ limit: size + 1,
72
+ include: record.include,
73
+ signal: record.signal,
74
+ timeout: record.timeout,
75
+ route: record.route
76
+ }, undefined, session.scope, session.schema.model[table], session.schema, view),
77
+ ...after !== undefined ? { after } : {},
78
+ ...pin !== undefined ? { pin } : {}
79
+ };
80
+ return readHandle(session, table, call, mods, async (compiled, rows) => {
81
+ const items = await decodeRows(compiled, rows, table);
82
+ const more = items.length > size;
83
+ const kept = more ? items.slice(0, size) : items;
84
+ const last = rows[size - 1];
85
+ const next = more && last !== undefined ? makeCursor(compiled, last, keys, signature) : null;
86
+ if (extra.length > 0) {
87
+ for (const item of kept) {
88
+ for (const field of extra)
89
+ delete item[field];
90
+ }
91
+ }
92
+ return { items: kept, next };
93
+ });
94
+ }
95
+ function orderKeys(table, orderBy) {
96
+ if (orderBy !== undefined && !isRecord(orderBy)) {
97
+ fail2("OKM1120", "orderBy must be an object of fields.");
98
+ }
99
+ const keys = [];
100
+ for (const field of Object.keys(orderBy ?? {})) {
101
+ const column = table.columns.get(field);
102
+ if (column === undefined) {
103
+ throwNamed("OKM1120", field, table.names, `Field ${field} is not on ${table.model.name}. Accepted names: ${list(table.names)}.`);
104
+ }
105
+ keys.push({ column, ...parseOrder(field, orderBy?.[field]) });
106
+ }
107
+ if (table.model.primary.length === 0) {
108
+ fail2("OKM1120", `page() needs a primary key on ${table.model.name} to break ties.`);
109
+ }
110
+ for (const field of table.model.primary) {
111
+ const column = table.columns.get(field);
112
+ if (column === undefined || keys.some((key) => key.column === column))
113
+ continue;
114
+ keys.push({ column, dir: "asc", nulls: "last" });
115
+ }
116
+ return keys;
117
+ }
118
+ function keyset(keys, signature, token) {
119
+ const values = readCursor(token, signature, keys.length);
120
+ return (sink, alias) => {
121
+ sink.mark(`k:${signature}:${values.map((value) => value === null ? "n" : "v").join("")}`);
122
+ let wrote = false;
123
+ for (let index = 0;index < keys.length; index += 1) {
124
+ const key = keys[index];
125
+ const value = values[index];
126
+ if (key === undefined || value === undefined)
127
+ continue;
128
+ if (value === null && key.nulls === "last")
129
+ continue;
130
+ sink.text(wrote ? " or (" : "(");
131
+ wrote = true;
132
+ for (let before = 0;before < index; before += 1) {
133
+ const prior = keys[before];
134
+ const held = values[before];
135
+ if (prior === undefined || held === undefined)
136
+ continue;
137
+ const ref = `${alias}.${quote(prior.column.sql)}`;
138
+ if (held === null) {
139
+ sink.text(`${ref} is null and `);
140
+ } else {
141
+ sink.text(`${ref} = `);
142
+ sink.param(held);
143
+ sink.text(" and ");
144
+ }
145
+ }
146
+ const ref = `${alias}.${quote(key.column.sql)}`;
147
+ if (value === null) {
148
+ sink.text(`${ref} is not null`);
149
+ } else {
150
+ sink.text(key.nulls === "last" ? `(${ref} ${compare(key)} ` : `${ref} ${compare(key)} `);
151
+ sink.param(value);
152
+ sink.text(key.nulls === "last" ? ` or ${ref} is null)` : "");
153
+ }
154
+ sink.text(")");
155
+ }
156
+ if (!wrote)
157
+ sink.text("false");
158
+ };
159
+ }
160
+ function compare(key) {
161
+ return key.dir === "asc" ? ">" : "<";
162
+ }
163
+ function makeCursor(plan, row, keys, signature) {
164
+ const values = keys.map((key) => {
165
+ const at = plan.outputs.fields.find((field) => field.key === key.column.field)?.at;
166
+ return at === undefined ? null : row[at] ?? null;
167
+ });
168
+ const bytes = new TextEncoder().encode(JSON.stringify([signature, ...values]));
169
+ let binary = "";
170
+ for (const byte of bytes)
171
+ binary += String.fromCharCode(byte);
172
+ return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
173
+ }
174
+ function readCursor(token, signature, count) {
175
+ let parsed;
176
+ if (typeof token === "string") {
177
+ try {
178
+ const binary = atob(token.replaceAll("-", "+").replaceAll("_", "/"));
179
+ const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
180
+ parsed = JSON.parse(new TextDecoder().decode(bytes));
181
+ } catch {
182
+ parsed = undefined;
183
+ }
184
+ }
185
+ if (!Array.isArray(parsed) || typeof parsed[0] !== "string") {
186
+ fail2("OKM1130", "after is not a cursor that page() returned.");
187
+ }
188
+ if (parsed[0] !== signature) {
189
+ fail2("OKM1130", `The cursor was made for another order: ${parsed[0]}. This page orders by ${signature}.`);
190
+ }
191
+ const values = parsed.slice(1);
192
+ if (values.length !== count || !values.every((value) => value === null || typeof value === "string")) {
193
+ fail2("OKM1130", "after is not a cursor that page() returned.");
194
+ }
195
+ return values;
196
+ }
197
+
198
+ export { build3 };
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  testing2
3
- } from "../../shared/8x72s86k.js";
4
- import"../../shared/9s0ypp87.js";
5
- import"../../shared/qq3899ht.js";
3
+ } from "../../shared/b6d6p0zc.js";
4
+ import"../../shared/sjk86yrx.js";
5
+ import"../../shared/12z7aznj.js";
6
6
  export {
7
7
  testing2 as testing
8
8
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okmodel",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "okmodel is a catalog-first TypeScript ORM, PostgreSQL first.",
5
5
  "keywords": [
6
6
  "migrations",
@@ -63,6 +63,10 @@
63
63
  "types": "./dist/runtime/pg/bun.d.ts",
64
64
  "import": "./dist/runtime/pg/bun.js"
65
65
  },
66
+ "./pg/neon": {
67
+ "types": "./dist/runtime/pg/neon.d.ts",
68
+ "import": "./dist/runtime/pg/neon.js"
69
+ },
66
70
  "./ids": {
67
71
  "types": "./dist/runtime/ids/index.d.ts",
68
72
  "import": "./dist/runtime/ids/index.js"
@@ -87,6 +91,10 @@
87
91
  "types": "./dist/runtime/validate/index.d.ts",
88
92
  "import": "./dist/runtime/validate/index.js"
89
93
  },
94
+ "./otel": {
95
+ "types": "./dist/runtime/otel.d.ts",
96
+ "import": "./dist/runtime/otel.js"
97
+ },
90
98
  "./ext": {
91
99
  "types": "./dist/dialects/pg/ext/index.d.ts",
92
100
  "import": "./dist/dialects/pg/ext/index.js"
@@ -109,7 +117,7 @@
109
117
  }
110
118
  },
111
119
  "scripts": {
112
- "build": "rm -rf dist && bun build ./src/contracts/index.ts ./src/contracts/internal.ts ./src/dialects/pg/index.ts ./src/runtime/pg/postgresjs.ts ./src/runtime/pg/pglite.ts ./src/runtime/pg/pg.ts ./src/runtime/pg/bun.ts ./src/runtime/ids/index.ts ./src/runtime/safety/index.ts ./src/runtime/traits/index.ts ./src/runtime/tenancy/index.ts ./src/runtime/validate/index.ts ./src/dialects/pg/ext/index.ts ./src/dialects/pg/fn/index.ts ./src/dialects/pg/view/index.ts ./src/dialects/pg/ext/citext.ts ./src/dialects/pg/ext/pg-trgm.ts ./src/tooling/migrate/index.ts ./src/tooling/testing/index.ts ./src/tooling/cli.ts --outdir ./dist --root ./src --format esm --target node --splitting --chunk-naming=shared/[hash].js --external postgres --external @electric-sql/pglite --external pg --external bun && bunx tsc -p tsconfig.build.json && rm -f ./dist/dialects/pg/temporal.local.d.ts && bun ./scripts/write-bin-wrappers.ts",
120
+ "build": "rm -rf dist && bun build ./src/contracts/index.ts ./src/contracts/internal.ts ./src/dialects/pg/index.ts ./src/runtime/pg/postgresjs.ts ./src/runtime/pg/pglite.ts ./src/runtime/pg/pg.ts ./src/runtime/pg/bun.ts ./src/runtime/pg/neon.ts ./src/runtime/ids/index.ts ./src/runtime/safety/index.ts ./src/runtime/traits/index.ts ./src/runtime/tenancy/index.ts ./src/runtime/validate/index.ts ./src/runtime/otel.ts ./src/dialects/pg/ext/index.ts ./src/dialects/pg/fn/index.ts ./src/dialects/pg/view/index.ts ./src/dialects/pg/ext/citext.ts ./src/dialects/pg/ext/pg-trgm.ts ./src/tooling/migrate/index.ts ./src/tooling/testing/index.ts ./src/tooling/cli.ts --outdir ./dist --root ./src --format esm --target node --splitting --chunk-naming=shared/[hash].js --external postgres --external @electric-sql/pglite --external pg --external bun --external @neondatabase/serverless && bunx tsc -p tsconfig.build.json && rm -f ./dist/dialects/pg/temporal.local.d.ts && bun build ./packages/harness/src/driver-run.ts --outdir ./dist/tooling --format esm --target node --splitting --chunk-naming=shared/[hash].js --external postgres --external @electric-sql/pglite --external pg --external bun --external @neondatabase/serverless && bun ./scripts/write-bin-wrappers.ts",
113
121
  "driver-bench": "bun ./scripts/driver-bench.ts",
114
122
  "typecheck": "bunx tsc --noEmit -p tsconfig.json",
115
123
  "editor-check": "bun ./scripts/editor-check.ts",
@@ -126,6 +134,7 @@
126
134
  "compiler-api": "bun ./scripts/compiler-api.ts",
127
135
  "publint": "publint run . --strict --pack bun",
128
136
  "attw": "bun ./scripts/attw.ts",
137
+ "pack-tracked": "bun ./scripts/pack-tracked.ts",
129
138
  "prepack": "bun ./scripts/strip-workspaces.ts strip",
130
139
  "postpack": "bun ./scripts/strip-workspaces.ts restore",
131
140
  "size": "bun ./scripts/size.ts",
@@ -134,7 +143,7 @@
134
143
  "test:postgres": "bun ./scripts/postgres-suite.ts",
135
144
  "test:tarball": "bun ./scripts/tarball-smoke.ts",
136
145
  "verify": "bun ./scripts/verify.ts",
137
- "check": "bun run format:check && bun run lint && bun run typecheck && bun run editor-check && bun run type-cost && bun run layers-check && bun run core-purity && bun run okid-drift && bun run docs:check && bun run readme:check && bun run compiler-api && bun run bundle-purity && bun run build && bun test && bun run test:runtimes && bun run publint && bun run attw && bun run size",
146
+ "check": "bun run format:check && bun run lint && bun run typecheck && bun run editor-check && bun run type-cost && bun run layers-check && bun run core-purity && bun run okid-drift && bun run docs:check && bun run readme:check && bun run compiler-api && bun run bundle-purity && bun run build && bun test && bun run test:runtimes && bun run publint && bun run attw && bun run pack-tracked && bun run size",
138
147
  "bump": "bun ./scripts/bump-version.ts",
139
148
  "release-check": "bun ./scripts/release-check.ts",
140
149
  "db:up": "bun ./packages/harness/src/docker-cli.ts up",
@@ -142,6 +151,7 @@
142
151
  "bench": "bun ./packages/bench/src/run.ts",
143
152
  "catalog-bench": "bun ./scripts/catalog-bench.ts",
144
153
  "attest": "ATTEST_shouldFormat=0 ATTEST_updateSnapshots=0 bun ./packages/attest/src/measure.bench.ts",
154
+ "dev": "bun run site:dev",
145
155
  "site:dev": "bun --cwd site dev",
146
156
  "site:build": "bun --cwd site build",
147
157
  "site:check": "bun --cwd site check",
@@ -166,6 +176,7 @@
166
176
  },
167
177
  "peerDependencies": {
168
178
  "@electric-sql/pglite": "^0.5.8",
179
+ "@neondatabase/serverless": "^1.2.0",
169
180
  "pg": "^8.16.0",
170
181
  "postgres": "^3.4.9"
171
182
  },
@@ -173,6 +184,9 @@
173
184
  "@electric-sql/pglite": {
174
185
  "optional": true
175
186
  },
187
+ "@neondatabase/serverless": {
188
+ "optional": true
189
+ },
176
190
  "pg": {
177
191
  "optional": true
178
192
  },
@@ -1,38 +0,0 @@
1
- import {
2
- mapPostgresError2
3
- } from "./c58secgj.js";
4
- import {
5
- withHttp
6
- } from "./j60w0dvr.js";
7
- import {
8
- decodeResult
9
- } from "./2z7wv5tj.js";
10
- import {
11
- OkmError2
12
- } from "./52szzakm.js";
13
-
14
- // src/runtime/read-stream.ts
15
- async function* streamRows(session, call, prepare, log) {
16
- await session.connected;
17
- if (session.pool.capabilities.stream !== true || session.pool.stream === undefined) {
18
- throw log(new OkmError2("OKM1111", "stream needs a driver with stream: true. This driver does not have it.", withHttp(session.http, {
19
- fix: { summary: "Use a driver that sets stream, or read with find." }
20
- })));
21
- }
22
- const { plan, params } = await prepare();
23
- const decode = plan.outputs.includes.length === 0 ? decodeResult : (await import("./ys0xzyaj.js")).decodeIncluded;
24
- try {
25
- for await (const chunk of session.pool.stream(plan.text, params)) {
26
- const decoded = decode(plan, chunk, call.table);
27
- if (!Array.isArray(decoded))
28
- continue;
29
- for (const row of decoded)
30
- yield row;
31
- }
32
- } catch (error) {
33
- throw log(session.http === undefined ? mapPostgresError2(error) : mapPostgresError2(error, { http: session.http }));
34
- }
35
- }
36
- export {
37
- streamRows
38
- };
@@ -1,45 +0,0 @@
1
- // src/runtime/trait-read.ts
2
- function touchFields(model) {
3
- const traits = model.traits;
4
- if (traits === undefined)
5
- return;
6
- const names = [];
7
- for (const trait of traits) {
8
- const touch = trait.touch;
9
- if (touch === undefined)
10
- continue;
11
- for (const field of touch)
12
- names.push(field);
13
- }
14
- return names.length === 0 ? undefined : names;
15
- }
16
- function fieldSealed(model, field) {
17
- const traits = model.traits;
18
- if (traits === undefined)
19
- return false;
20
- for (const trait of traits) {
21
- const sealed = trait.sealed;
22
- if (sealed === undefined)
23
- continue;
24
- for (const name of sealed)
25
- if (name === field)
26
- return true;
27
- }
28
- return false;
29
- }
30
- function sealingTrait(model, field) {
31
- const traits = model.traits;
32
- if (traits === undefined)
33
- return;
34
- for (const trait of traits) {
35
- const sealed = trait.sealed;
36
- if (sealed === undefined)
37
- continue;
38
- for (const name of sealed)
39
- if (name === field)
40
- return trait.name;
41
- }
42
- return;
43
- }
44
-
45
- export { touchFields, fieldSealed, sealingTrait };
@@ -1,12 +0,0 @@
1
- import {
2
- OkmError2
3
- } from "./52szzakm.js";
4
-
5
- // src/adapters/pg/no-inflight-timeout.ts
6
- function noTimeout2(options) {
7
- if ((options?.timeout ?? 0) <= 0)
8
- return;
9
- throw new OkmError2("OKM1120", "timeout");
10
- }
11
-
12
- export { noTimeout2 };
@@ -1,99 +0,0 @@
1
- import {
2
- DriverError2
3
- } from "./31vm914h.js";
4
- import {
5
- noTimeout2
6
- } from "./8dqhth8c.js";
7
- import {
8
- send2,
9
- reserve,
10
- park
11
- } from "./32cnm7kn.js";
12
- import {
13
- isConnectionLost
14
- } from "./gwn6v667.js";
15
- import {
16
- WireSession
17
- } from "./4az561fn.js";
18
- import {
19
- rejectClosed,
20
- runCall
21
- } from "./cgbamx3e.js";
22
-
23
- // src/adapters/pg/bunsql-extra.ts
24
- async function checkout(held) {
25
- const { counters, isClosed } = held;
26
- if (isClosed())
27
- return rejectClosed();
28
- const reserved = held.parked.pop() ?? await reserve(held.sql, held.acquireMs, counters);
29
- counters.reserved += 1;
30
- const session = new WireSession((text, params) => send2(reserved, text, params), held.notices, isClosed, false, () => {
31
- counters.reservedBusy += 1;
32
- }, () => {
33
- counters.reservedBusy = Math.max(0, counters.reservedBusy - 1);
34
- });
35
- let lost = false;
36
- const guard = (run) => lost ? rejectClosed("CONNECTION_CLOSED") : run().catch((error) => {
37
- if (isConnectionLost(error))
38
- lost = true;
39
- if (error instanceof Error && bunClosed(error.message)) {
40
- lost = true;
41
- throw new DriverError2("CONNECTION_CLOSED", { cause: error });
42
- }
43
- throw error;
44
- });
45
- let released = false;
46
- return {
47
- execute: (text, params, options) => {
48
- noTimeout2(options);
49
- return guard(() => runCall(isClosed(), options, (watch) => session.query(text, params, watch)));
50
- },
51
- batch: (statements, options) => {
52
- noTimeout2(options);
53
- return guard(() => runCall(isClosed(), options, async (watch) => {
54
- const { runAtomicBatch } = await import("./ag4c7516.js");
55
- return runAtomicBatch(session, statements, watch);
56
- }));
57
- },
58
- async release() {
59
- if (released)
60
- return;
61
- released = true;
62
- try {
63
- if (!lost)
64
- await reset(session, reserved);
65
- } finally {
66
- counters.reserved = Math.max(0, counters.reserved - 1);
67
- if (lost)
68
- await held.sql.unsafe("select 1").catch(() => {
69
- return;
70
- });
71
- else
72
- await park(held.parked, reserved);
73
- }
74
- }
75
- };
76
- }
77
- function bunClosed(message) {
78
- return message === "Connection closed" || message === "connection must be a PostgresSQLConnection";
79
- }
80
- async function reset(session, sql) {
81
- const run = (text) => sql.unsafe(text);
82
- if (session.depth() > 0)
83
- await run("ROLLBACK").catch(() => {
84
- return;
85
- });
86
- try {
87
- await run("RESET ALL");
88
- await run("SELECT pg_advisory_unlock_all()");
89
- } catch {
90
- await run("ROLLBACK").catch(() => {
91
- return;
92
- });
93
- await run("RESET ALL");
94
- await run("SELECT pg_advisory_unlock_all()");
95
- }
96
- }
97
- export {
98
- checkout
99
- };
@@ -1,85 +0,0 @@
1
- import {
2
- catalogError2,
3
- throwNamed2
4
- } from "./52szzakm.js";
5
-
6
- // src/dialects/pg/through.ts
7
- var emit = (planner, schema, relation, child, sink, parent, alias, depth) => {
8
- const through = relation.through;
9
- const join = through === undefined ? undefined : planner.indexes(schema).get(through.table);
10
- if (through === undefined || join === undefined) {
11
- return catalogError2("OKM1020", `Relation ${relation.name} names a join table that is not in the schema.`);
12
- }
13
- const { quote } = planner;
14
- const joinAlias = `j${alias}`;
15
- sink.mark(`via:${through.table}`);
16
- sink.text(`${quote(join.model.sql)} ${joinAlias} join ${quote(child.model.sql)} ${alias} on `);
17
- for (let index = 0;index < through.local.length; index += 1) {
18
- const local = through.local[index];
19
- const remote = through.remote[index];
20
- if (local === undefined || remote === undefined)
21
- continue;
22
- if (index > 0)
23
- sink.text(" and ");
24
- sink.text(`${alias}.${quote(remote)} = ${joinAlias}.${quote(local)}`);
25
- }
26
- sink.text(" where ");
27
- planner.join(sink, parent, joinAlias, relation);
28
- planner.where(schema, join, undefined, sink, joinAlias, depth + 1, true);
29
- };
30
- function resolveThrough(scope, table, through, from, to) {
31
- for (const name of [table, through]) {
32
- if (!scope.tables.includes(name)) {
33
- throwNamed2("OKM1020", name, scope.tables, `Relation ${scope.owner}.${scope.name} names ${name}, which is not in the schema. Accepted names: ${scope.tables.join(", ")}.`);
34
- }
35
- }
36
- const toOwner = pick(scope, through, scope.owner, from, `${scope.owner}.${scope.name}`, "from");
37
- const toTable = pick(scope, through, table, to, `${scope.owner}.${scope.name}`, "to");
38
- if (toOwner === toTable) {
39
- catalogError2("OKM1021", `Relation ${scope.owner}.${scope.name} uses ${toOwner.fromField} on ${through} for both ends. Pass from and to.`);
40
- }
41
- return {
42
- name: scope.name,
43
- kind: "many",
44
- table,
45
- local: toOwner.remote,
46
- remote: toOwner.local,
47
- through: { table: through, local: toTable.local, remote: toTable.remote, emit }
48
- };
49
- }
50
- function pick(scope, through, target, field, label, end) {
51
- const matches = scope.edges.filter((edge) => edge.fromTable === through && edge.toTable === target && (field === undefined || edge.fromField === field));
52
- const [only] = matches;
53
- if (matches.length === 1 && only !== undefined)
54
- return only;
55
- const fields = matches.map((edge) => edge.fromField).sort();
56
- catalogError2("OKM1021", `Relation ${label} through ${through} is ambiguous at ${end}. Accepted columns: ${fields.length === 0 ? "(none)" : fields.join(", ")}.`);
57
- }
58
-
59
- // src/dialects/pg/relations.ts
60
- function one2(table, field) {
61
- return { kind: "one", table, field };
62
- }
63
- function many2(table, field) {
64
- return { kind: "many", table, field };
65
- }
66
- function isRelationCall(value) {
67
- if (typeof value !== "object" || value === null)
68
- return false;
69
- if (!("kind" in value) || !("table" in value))
70
- return false;
71
- const kind = value.kind;
72
- return (kind === "one" || kind === "many") && typeof value.table === "string";
73
- }
74
- function manyThrough2(table, options) {
75
- const { through, from, to } = options;
76
- return {
77
- kind: "many",
78
- table,
79
- field: undefined,
80
- through,
81
- resolve: (scope) => resolveThrough(scope, table, through, from, to)
82
- };
83
- }
84
-
85
- export { one2, many2, isRelationCall, manyThrough2 };