on-zero 0.0.1

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 (371) hide show
  1. package/LICENSE +21 -0
  2. package/cli.cjs +3 -0
  3. package/dist/cjs/cli.cjs +405 -0
  4. package/dist/cjs/cli.js +397 -0
  5. package/dist/cjs/cli.js.map +6 -0
  6. package/dist/cjs/cli.native.js +505 -0
  7. package/dist/cjs/cli.native.js.map +1 -0
  8. package/dist/cjs/constants.cjs +28 -0
  9. package/dist/cjs/constants.js +22 -0
  10. package/dist/cjs/constants.js.map +6 -0
  11. package/dist/cjs/constants.native.js +31 -0
  12. package/dist/cjs/constants.native.js.map +1 -0
  13. package/dist/cjs/createPermissions.cjs +82 -0
  14. package/dist/cjs/createPermissions.js +77 -0
  15. package/dist/cjs/createPermissions.js.map +6 -0
  16. package/dist/cjs/createPermissions.native.js +107 -0
  17. package/dist/cjs/createPermissions.native.js.map +1 -0
  18. package/dist/cjs/createUseQuery.cjs +59 -0
  19. package/dist/cjs/createUseQuery.js +34 -0
  20. package/dist/cjs/createUseQuery.js.map +6 -0
  21. package/dist/cjs/createUseQuery.native.js +70 -0
  22. package/dist/cjs/createUseQuery.native.js.map +1 -0
  23. package/dist/cjs/createZeroClient.cjs +162 -0
  24. package/dist/cjs/createZeroClient.js +126 -0
  25. package/dist/cjs/createZeroClient.js.map +6 -0
  26. package/dist/cjs/createZeroClient.native.js +214 -0
  27. package/dist/cjs/createZeroClient.native.js.map +1 -0
  28. package/dist/cjs/createZeroServer.cjs +148 -0
  29. package/dist/cjs/createZeroServer.js +126 -0
  30. package/dist/cjs/createZeroServer.js.map +6 -0
  31. package/dist/cjs/createZeroServer.native.js +170 -0
  32. package/dist/cjs/createZeroServer.native.js.map +1 -0
  33. package/dist/cjs/helpers/batchQuery.cjs +49 -0
  34. package/dist/cjs/helpers/batchQuery.js +38 -0
  35. package/dist/cjs/helpers/batchQuery.js.map +6 -0
  36. package/dist/cjs/helpers/batchQuery.native.js +49 -0
  37. package/dist/cjs/helpers/batchQuery.native.js.map +1 -0
  38. package/dist/cjs/helpers/createMutators.cjs +90 -0
  39. package/dist/cjs/helpers/createMutators.js +85 -0
  40. package/dist/cjs/helpers/createMutators.js.map +6 -0
  41. package/dist/cjs/helpers/createMutators.native.js +132 -0
  42. package/dist/cjs/helpers/createMutators.native.js.map +1 -0
  43. package/dist/cjs/helpers/didRunPermissionCheck.cjs +30 -0
  44. package/dist/cjs/helpers/didRunPermissionCheck.js +26 -0
  45. package/dist/cjs/helpers/didRunPermissionCheck.js.map +6 -0
  46. package/dist/cjs/helpers/didRunPermissionCheck.native.js +39 -0
  47. package/dist/cjs/helpers/didRunPermissionCheck.native.js.map +1 -0
  48. package/dist/cjs/helpers/ensureLoggedIn.cjs +33 -0
  49. package/dist/cjs/helpers/ensureLoggedIn.js +25 -0
  50. package/dist/cjs/helpers/ensureLoggedIn.js.map +6 -0
  51. package/dist/cjs/helpers/ensureLoggedIn.native.js +36 -0
  52. package/dist/cjs/helpers/ensureLoggedIn.native.js.map +1 -0
  53. package/dist/cjs/helpers/getQueryOrMutatorAuthData.cjs +30 -0
  54. package/dist/cjs/helpers/getQueryOrMutatorAuthData.js +24 -0
  55. package/dist/cjs/helpers/getQueryOrMutatorAuthData.js.map +6 -0
  56. package/dist/cjs/helpers/getQueryOrMutatorAuthData.native.js +33 -0
  57. package/dist/cjs/helpers/getQueryOrMutatorAuthData.native.js.map +1 -0
  58. package/dist/cjs/helpers/mutatorContext.cjs +40 -0
  59. package/dist/cjs/helpers/mutatorContext.js +36 -0
  60. package/dist/cjs/helpers/mutatorContext.js.map +6 -0
  61. package/dist/cjs/helpers/mutatorContext.native.js +43 -0
  62. package/dist/cjs/helpers/mutatorContext.native.js.map +1 -0
  63. package/dist/cjs/helpers/prettyFormatZeroQuery.cjs +107 -0
  64. package/dist/cjs/helpers/prettyFormatZeroQuery.js +92 -0
  65. package/dist/cjs/helpers/prettyFormatZeroQuery.js.map +6 -0
  66. package/dist/cjs/helpers/prettyFormatZeroQuery.native.js +119 -0
  67. package/dist/cjs/helpers/prettyFormatZeroQuery.native.js.map +1 -0
  68. package/dist/cjs/helpers/useZeroDebug.cjs +68 -0
  69. package/dist/cjs/helpers/useZeroDebug.js +49 -0
  70. package/dist/cjs/helpers/useZeroDebug.js.map +6 -0
  71. package/dist/cjs/helpers/useZeroDebug.native.js +81 -0
  72. package/dist/cjs/helpers/useZeroDebug.native.js.map +1 -0
  73. package/dist/cjs/index.cjs +42 -0
  74. package/dist/cjs/index.js +35 -0
  75. package/dist/cjs/index.js.map +6 -0
  76. package/dist/cjs/index.native.js +45 -0
  77. package/dist/cjs/index.native.js.map +1 -0
  78. package/dist/cjs/mutations.cjs +51 -0
  79. package/dist/cjs/mutations.js +44 -0
  80. package/dist/cjs/mutations.js.map +6 -0
  81. package/dist/cjs/mutations.native.js +56 -0
  82. package/dist/cjs/mutations.native.js.map +1 -0
  83. package/dist/cjs/queryRegistry.cjs +33 -0
  84. package/dist/cjs/queryRegistry.js +28 -0
  85. package/dist/cjs/queryRegistry.js.map +6 -0
  86. package/dist/cjs/queryRegistry.native.js +36 -0
  87. package/dist/cjs/queryRegistry.native.js.map +1 -0
  88. package/dist/cjs/resolveQuery.cjs +41 -0
  89. package/dist/cjs/resolveQuery.js +40 -0
  90. package/dist/cjs/resolveQuery.js.map +6 -0
  91. package/dist/cjs/resolveQuery.native.js +46 -0
  92. package/dist/cjs/resolveQuery.native.js.map +1 -0
  93. package/dist/cjs/run.cjs +48 -0
  94. package/dist/cjs/run.js +37 -0
  95. package/dist/cjs/run.js.map +6 -0
  96. package/dist/cjs/run.native.js +52 -0
  97. package/dist/cjs/run.native.js.map +1 -0
  98. package/dist/cjs/server.cjs +18 -0
  99. package/dist/cjs/server.js +15 -0
  100. package/dist/cjs/server.js.map +6 -0
  101. package/dist/cjs/server.native.js +21 -0
  102. package/dist/cjs/server.native.js.map +1 -0
  103. package/dist/cjs/serverWhere.cjs +29 -0
  104. package/dist/cjs/serverWhere.js +24 -0
  105. package/dist/cjs/serverWhere.js.map +6 -0
  106. package/dist/cjs/serverWhere.native.js +32 -0
  107. package/dist/cjs/serverWhere.native.js.map +1 -0
  108. package/dist/cjs/state.cjs +49 -0
  109. package/dist/cjs/state.js +37 -0
  110. package/dist/cjs/state.js.map +6 -0
  111. package/dist/cjs/state.native.js +54 -0
  112. package/dist/cjs/state.native.js.map +1 -0
  113. package/dist/cjs/types.cjs +16 -0
  114. package/dist/cjs/types.js +14 -0
  115. package/dist/cjs/types.js.map +6 -0
  116. package/dist/cjs/types.native.js +19 -0
  117. package/dist/cjs/types.native.js.map +1 -0
  118. package/dist/cjs/where.cjs +41 -0
  119. package/dist/cjs/where.js +35 -0
  120. package/dist/cjs/where.js.map +6 -0
  121. package/dist/cjs/where.native.js +46 -0
  122. package/dist/cjs/where.native.js.map +1 -0
  123. package/dist/cjs/zeroRunner.cjs +34 -0
  124. package/dist/cjs/zeroRunner.js +32 -0
  125. package/dist/cjs/zeroRunner.js.map +6 -0
  126. package/dist/cjs/zeroRunner.native.js +37 -0
  127. package/dist/cjs/zeroRunner.native.js.map +1 -0
  128. package/dist/cjs/zql.cjs +31 -0
  129. package/dist/cjs/zql.js +26 -0
  130. package/dist/cjs/zql.js.map +6 -0
  131. package/dist/cjs/zql.native.js +35 -0
  132. package/dist/cjs/zql.native.js.map +1 -0
  133. package/dist/esm/cli.js +383 -0
  134. package/dist/esm/cli.js.map +6 -0
  135. package/dist/esm/cli.mjs +384 -0
  136. package/dist/esm/cli.mjs.map +1 -0
  137. package/dist/esm/cli.native.js +481 -0
  138. package/dist/esm/cli.native.js.map +1 -0
  139. package/dist/esm/constants.js +6 -0
  140. package/dist/esm/constants.js.map +6 -0
  141. package/dist/esm/constants.mjs +4 -0
  142. package/dist/esm/constants.mjs.map +1 -0
  143. package/dist/esm/constants.native.js +4 -0
  144. package/dist/esm/constants.native.js.map +1 -0
  145. package/dist/esm/createPermissions.js +66 -0
  146. package/dist/esm/createPermissions.js.map +6 -0
  147. package/dist/esm/createPermissions.mjs +59 -0
  148. package/dist/esm/createPermissions.mjs.map +1 -0
  149. package/dist/esm/createPermissions.native.js +81 -0
  150. package/dist/esm/createPermissions.native.js.map +1 -0
  151. package/dist/esm/createUseQuery.js +21 -0
  152. package/dist/esm/createUseQuery.js.map +6 -0
  153. package/dist/esm/createUseQuery.mjs +36 -0
  154. package/dist/esm/createUseQuery.mjs.map +1 -0
  155. package/dist/esm/createUseQuery.native.js +44 -0
  156. package/dist/esm/createUseQuery.native.js.map +1 -0
  157. package/dist/esm/createZeroClient.js +135 -0
  158. package/dist/esm/createZeroClient.js.map +6 -0
  159. package/dist/esm/createZeroClient.mjs +139 -0
  160. package/dist/esm/createZeroClient.mjs.map +1 -0
  161. package/dist/esm/createZeroClient.native.js +188 -0
  162. package/dist/esm/createZeroClient.native.js.map +1 -0
  163. package/dist/esm/createZeroServer.js +121 -0
  164. package/dist/esm/createZeroServer.js.map +6 -0
  165. package/dist/esm/createZeroServer.mjs +125 -0
  166. package/dist/esm/createZeroServer.mjs.map +1 -0
  167. package/dist/esm/createZeroServer.native.js +144 -0
  168. package/dist/esm/createZeroServer.native.js.map +1 -0
  169. package/dist/esm/helpers/batchQuery.js +22 -0
  170. package/dist/esm/helpers/batchQuery.js.map +6 -0
  171. package/dist/esm/helpers/batchQuery.mjs +26 -0
  172. package/dist/esm/helpers/batchQuery.mjs.map +1 -0
  173. package/dist/esm/helpers/batchQuery.native.js +23 -0
  174. package/dist/esm/helpers/batchQuery.native.js.map +1 -0
  175. package/dist/esm/helpers/createMutators.js +71 -0
  176. package/dist/esm/helpers/createMutators.js.map +6 -0
  177. package/dist/esm/helpers/createMutators.mjs +67 -0
  178. package/dist/esm/helpers/createMutators.mjs.map +1 -0
  179. package/dist/esm/helpers/createMutators.native.js +106 -0
  180. package/dist/esm/helpers/createMutators.native.js.map +1 -0
  181. package/dist/esm/helpers/didRunPermissionCheck.js +10 -0
  182. package/dist/esm/helpers/didRunPermissionCheck.js.map +6 -0
  183. package/dist/esm/helpers/didRunPermissionCheck.mjs +6 -0
  184. package/dist/esm/helpers/didRunPermissionCheck.mjs.map +1 -0
  185. package/dist/esm/helpers/didRunPermissionCheck.native.js +12 -0
  186. package/dist/esm/helpers/didRunPermissionCheck.native.js.map +1 -0
  187. package/dist/esm/helpers/ensureLoggedIn.js +10 -0
  188. package/dist/esm/helpers/ensureLoggedIn.js.map +6 -0
  189. package/dist/esm/helpers/ensureLoggedIn.mjs +10 -0
  190. package/dist/esm/helpers/ensureLoggedIn.mjs.map +1 -0
  191. package/dist/esm/helpers/ensureLoggedIn.native.js +10 -0
  192. package/dist/esm/helpers/ensureLoggedIn.native.js.map +1 -0
  193. package/dist/esm/helpers/getQueryOrMutatorAuthData.js +9 -0
  194. package/dist/esm/helpers/getQueryOrMutatorAuthData.js.map +6 -0
  195. package/dist/esm/helpers/getQueryOrMutatorAuthData.mjs +7 -0
  196. package/dist/esm/helpers/getQueryOrMutatorAuthData.mjs.map +1 -0
  197. package/dist/esm/helpers/getQueryOrMutatorAuthData.native.js +7 -0
  198. package/dist/esm/helpers/getQueryOrMutatorAuthData.native.js.map +1 -0
  199. package/dist/esm/helpers/mutatorContext.js +20 -0
  200. package/dist/esm/helpers/mutatorContext.js.map +6 -0
  201. package/dist/esm/helpers/mutatorContext.mjs +15 -0
  202. package/dist/esm/helpers/mutatorContext.mjs.map +1 -0
  203. package/dist/esm/helpers/mutatorContext.native.js +15 -0
  204. package/dist/esm/helpers/mutatorContext.native.js.map +1 -0
  205. package/dist/esm/helpers/prettyFormatZeroQuery.js +76 -0
  206. package/dist/esm/helpers/prettyFormatZeroQuery.js.map +6 -0
  207. package/dist/esm/helpers/prettyFormatZeroQuery.mjs +84 -0
  208. package/dist/esm/helpers/prettyFormatZeroQuery.mjs.map +1 -0
  209. package/dist/esm/helpers/prettyFormatZeroQuery.native.js +93 -0
  210. package/dist/esm/helpers/prettyFormatZeroQuery.native.js.map +1 -0
  211. package/dist/esm/helpers/useZeroDebug.js +35 -0
  212. package/dist/esm/helpers/useZeroDebug.js.map +6 -0
  213. package/dist/esm/helpers/useZeroDebug.mjs +45 -0
  214. package/dist/esm/helpers/useZeroDebug.mjs.map +1 -0
  215. package/dist/esm/helpers/useZeroDebug.native.js +55 -0
  216. package/dist/esm/helpers/useZeroDebug.native.js.map +1 -0
  217. package/dist/esm/index.js +20 -0
  218. package/dist/esm/index.js.map +6 -0
  219. package/dist/esm/index.mjs +17 -0
  220. package/dist/esm/index.mjs.map +1 -0
  221. package/dist/esm/index.native.js +17 -0
  222. package/dist/esm/index.native.js.map +1 -0
  223. package/dist/esm/mutations.js +28 -0
  224. package/dist/esm/mutations.js.map +6 -0
  225. package/dist/esm/mutations.mjs +28 -0
  226. package/dist/esm/mutations.mjs.map +1 -0
  227. package/dist/esm/mutations.native.js +30 -0
  228. package/dist/esm/mutations.native.js.map +1 -0
  229. package/dist/esm/queryRegistry.js +12 -0
  230. package/dist/esm/queryRegistry.js.map +6 -0
  231. package/dist/esm/queryRegistry.mjs +9 -0
  232. package/dist/esm/queryRegistry.mjs.map +1 -0
  233. package/dist/esm/queryRegistry.native.js +9 -0
  234. package/dist/esm/queryRegistry.native.js.map +1 -0
  235. package/dist/esm/resolveQuery.js +24 -0
  236. package/dist/esm/resolveQuery.js.map +6 -0
  237. package/dist/esm/resolveQuery.mjs +18 -0
  238. package/dist/esm/resolveQuery.mjs.map +1 -0
  239. package/dist/esm/resolveQuery.native.js +20 -0
  240. package/dist/esm/resolveQuery.native.js.map +1 -0
  241. package/dist/esm/run.js +22 -0
  242. package/dist/esm/run.js.map +6 -0
  243. package/dist/esm/run.mjs +24 -0
  244. package/dist/esm/run.mjs.map +1 -0
  245. package/dist/esm/run.native.js +25 -0
  246. package/dist/esm/run.native.js.map +1 -0
  247. package/dist/esm/server.js +2 -0
  248. package/dist/esm/server.js.map +6 -0
  249. package/dist/esm/server.mjs +2 -0
  250. package/dist/esm/server.mjs.map +1 -0
  251. package/dist/esm/server.native.js +2 -0
  252. package/dist/esm/server.native.js.map +1 -0
  253. package/dist/esm/serverWhere.js +8 -0
  254. package/dist/esm/serverWhere.js.map +6 -0
  255. package/dist/esm/serverWhere.mjs +6 -0
  256. package/dist/esm/serverWhere.mjs.map +1 -0
  257. package/dist/esm/serverWhere.native.js +6 -0
  258. package/dist/esm/serverWhere.native.js.map +1 -0
  259. package/dist/esm/state.js +21 -0
  260. package/dist/esm/state.js.map +6 -0
  261. package/dist/esm/state.mjs +22 -0
  262. package/dist/esm/state.mjs.map +1 -0
  263. package/dist/esm/state.native.js +24 -0
  264. package/dist/esm/state.native.js.map +1 -0
  265. package/dist/esm/types.js +1 -0
  266. package/dist/esm/types.js.map +6 -0
  267. package/dist/esm/types.mjs +2 -0
  268. package/dist/esm/types.mjs.map +1 -0
  269. package/dist/esm/types.native.js +2 -0
  270. package/dist/esm/types.native.js.map +1 -0
  271. package/dist/esm/where.js +20 -0
  272. package/dist/esm/where.js.map +6 -0
  273. package/dist/esm/where.mjs +17 -0
  274. package/dist/esm/where.mjs.map +1 -0
  275. package/dist/esm/where.native.js +19 -0
  276. package/dist/esm/where.native.js.map +1 -0
  277. package/dist/esm/zeroRunner.js +16 -0
  278. package/dist/esm/zeroRunner.js.map +6 -0
  279. package/dist/esm/zeroRunner.mjs +10 -0
  280. package/dist/esm/zeroRunner.mjs.map +1 -0
  281. package/dist/esm/zeroRunner.native.js +10 -0
  282. package/dist/esm/zeroRunner.native.js.map +1 -0
  283. package/dist/esm/zql.js +10 -0
  284. package/dist/esm/zql.js.map +6 -0
  285. package/dist/esm/zql.mjs +8 -0
  286. package/dist/esm/zql.mjs.map +1 -0
  287. package/dist/esm/zql.native.js +9 -0
  288. package/dist/esm/zql.native.js.map +1 -0
  289. package/package.json +98 -0
  290. package/readme.md +594 -0
  291. package/src/cli.ts +626 -0
  292. package/src/constants.native.ts +3 -0
  293. package/src/constants.ts +3 -0
  294. package/src/createPermissions.ts +131 -0
  295. package/src/createUseQuery.tsx +82 -0
  296. package/src/createZeroClient.tsx +301 -0
  297. package/src/createZeroServer.ts +226 -0
  298. package/src/helpers/batchQuery.ts +46 -0
  299. package/src/helpers/createMutators.ts +138 -0
  300. package/src/helpers/didRunPermissionCheck.ts +16 -0
  301. package/src/helpers/ensureLoggedIn.ts +11 -0
  302. package/src/helpers/getQueryOrMutatorAuthData.ts +12 -0
  303. package/src/helpers/mutatorContext.ts +25 -0
  304. package/src/helpers/prettyFormatZeroQuery.ts +167 -0
  305. package/src/helpers/useZeroDebug.ts +102 -0
  306. package/src/index.ts +18 -0
  307. package/src/mutations.ts +133 -0
  308. package/src/queryRegistry.ts +12 -0
  309. package/src/resolveQuery.ts +44 -0
  310. package/src/run.ts +62 -0
  311. package/src/server.ts +1 -0
  312. package/src/serverWhere.ts +21 -0
  313. package/src/state.ts +32 -0
  314. package/src/types.ts +136 -0
  315. package/src/where.ts +58 -0
  316. package/src/zeroRunner.ts +28 -0
  317. package/src/zql.ts +10 -0
  318. package/types/cli.d.ts +3 -0
  319. package/types/cli.d.ts.map +1 -0
  320. package/types/constants.d.ts +3 -0
  321. package/types/constants.d.ts.map +1 -0
  322. package/types/constants.native.d.ts +3 -0
  323. package/types/constants.native.d.ts.map +1 -0
  324. package/types/createPermissions.d.ts +10 -0
  325. package/types/createPermissions.d.ts.map +1 -0
  326. package/types/createUseQuery.d.ts +20 -0
  327. package/types/createUseQuery.d.ts.map +1 -0
  328. package/types/createZeroClient.d.ts +35 -0
  329. package/types/createZeroClient.d.ts.map +1 -0
  330. package/types/createZeroServer.d.ts +146 -0
  331. package/types/createZeroServer.d.ts.map +1 -0
  332. package/types/helpers/batchQuery.d.ts +7 -0
  333. package/types/helpers/batchQuery.d.ts.map +1 -0
  334. package/types/helpers/createMutators.d.ts +10 -0
  335. package/types/helpers/createMutators.d.ts.map +1 -0
  336. package/types/helpers/didRunPermissionCheck.d.ts +4 -0
  337. package/types/helpers/didRunPermissionCheck.d.ts.map +1 -0
  338. package/types/helpers/ensureLoggedIn.d.ts +3 -0
  339. package/types/helpers/ensureLoggedIn.d.ts.map +1 -0
  340. package/types/helpers/getQueryOrMutatorAuthData.d.ts +3 -0
  341. package/types/helpers/getQueryOrMutatorAuthData.d.ts.map +1 -0
  342. package/types/helpers/mutatorContext.d.ts +5 -0
  343. package/types/helpers/mutatorContext.d.ts.map +1 -0
  344. package/types/helpers/prettyFormatZeroQuery.d.ts +3 -0
  345. package/types/helpers/prettyFormatZeroQuery.d.ts.map +1 -0
  346. package/types/helpers/useZeroDebug.d.ts +3 -0
  347. package/types/helpers/useZeroDebug.d.ts.map +1 -0
  348. package/types/index.d.ts +17 -0
  349. package/types/index.d.ts.map +1 -0
  350. package/types/mutations.d.ts +20 -0
  351. package/types/mutations.d.ts.map +1 -0
  352. package/types/queryRegistry.d.ts +3 -0
  353. package/types/queryRegistry.d.ts.map +1 -0
  354. package/types/resolveQuery.d.ts +11 -0
  355. package/types/resolveQuery.d.ts.map +1 -0
  356. package/types/run.d.ts +7 -0
  357. package/types/run.d.ts.map +1 -0
  358. package/types/server.d.ts +2 -0
  359. package/types/server.d.ts.map +1 -0
  360. package/types/serverWhere.d.ts +5 -0
  361. package/types/serverWhere.d.ts.map +1 -0
  362. package/types/state.d.ts +8 -0
  363. package/types/state.d.ts.map +1 -0
  364. package/types/types.d.ts +78 -0
  365. package/types/types.d.ts.map +1 -0
  366. package/types/where.d.ts +6 -0
  367. package/types/where.d.ts.map +1 -0
  368. package/types/zeroRunner.d.ts +6 -0
  369. package/types/zeroRunner.d.ts.map +1 -0
  370. package/types/zql.d.ts +3 -0
  371. package/types/zql.d.ts.map +1 -0
@@ -0,0 +1,226 @@
1
+ import { mustGetQuery } from '@rocicorp/zero'
2
+ import { PushProcessor } from '@rocicorp/zero/pg'
3
+ import { handleQueryRequest as zeroHandleQueryRequest } from '@rocicorp/zero/server'
4
+ import { zeroNodePg } from '@rocicorp/zero/server/adapters/pg'
5
+ import { assertString, randomId } from '@take-out/helpers'
6
+ import { Pool } from 'pg'
7
+
8
+ import { createPermissions } from './createPermissions'
9
+ import { createMutators } from './helpers/createMutators'
10
+ import { isInZeroMutation, mutatorContext } from './helpers/mutatorContext'
11
+ import { setCustomQueries } from './run'
12
+ import { setAuthData, setSchema } from './state'
13
+ import { setRunner } from './zeroRunner'
14
+
15
+ import type {
16
+ AsyncAction,
17
+ AuthData,
18
+ GenericModels,
19
+ GetZeroMutators,
20
+ Transaction,
21
+ } from './types'
22
+ import type {
23
+ AnyQueryRegistry,
24
+ HumanReadable,
25
+ Query,
26
+ Schema as ZeroSchema,
27
+ } from '@rocicorp/zero'
28
+ import type { TransactionProviderInput } from '@rocicorp/zero/pg'
29
+
30
+ export function createZeroServer<
31
+ Schema extends ZeroSchema,
32
+ Models extends GenericModels,
33
+ ServerActions extends Record<string, unknown>,
34
+ >({
35
+ createServerActions,
36
+ database,
37
+ schema,
38
+ models,
39
+ queries,
40
+ }: {
41
+ /**
42
+ * The DB connection string, same as ZERO_UPSTREAM_DB
43
+ */
44
+ database: string
45
+ schema: Schema
46
+ models: Models
47
+ createServerActions: () => ServerActions
48
+ queries?: AnyQueryRegistry
49
+ }) {
50
+ setSchema(schema)
51
+
52
+ const dbString = assertString(database, `createZeroServer "database"`)
53
+
54
+ const zeroDb = zeroNodePg(
55
+ schema,
56
+ new Pool({
57
+ connectionString: dbString,
58
+ // handle self-signed certificates in production
59
+ ssl: dbString.includes('sslmode=require')
60
+ ? { rejectUnauthorized: false }
61
+ : undefined,
62
+ })
63
+ )
64
+
65
+ const permissions = createPermissions<Schema>({
66
+ environment: 'server',
67
+ schema,
68
+ })
69
+
70
+ const processor = new PushProcessor(zeroDb)
71
+
72
+ const handleMutationRequest = async ({
73
+ authData,
74
+ request,
75
+ skipAsyncTasks,
76
+ }: {
77
+ authData: AuthData | null
78
+ request: Request
79
+ skipAsyncTasks?: boolean
80
+ }) => {
81
+ // since mutations do DB work in transaction, avoid any async tasks during
82
+ const asyncTasks: AsyncAction[] = []
83
+
84
+ const mutators = createMutators({
85
+ asyncTasks,
86
+ can: permissions.can,
87
+ createServerActions,
88
+ environment: 'server',
89
+ models,
90
+ authData,
91
+ })
92
+
93
+ // @ts-expect-error type is ok but config in monorepo
94
+ const response = await processor.process(mutators, request)
95
+
96
+ // now finish
97
+ if (!skipAsyncTasks && asyncTasks.length) {
98
+ const id = randomId()
99
+ console.info(`[push] complete, running async tasks ${asyncTasks.length} id ${id}`)
100
+ Promise.all(asyncTasks.map((task) => task()))
101
+ .then(() => {
102
+ console.info(`[push] async tasks complete ${id}`)
103
+ })
104
+ .catch((err) => {
105
+ console.error(`[push] error: async tasks failed 😞`, err)
106
+ })
107
+ }
108
+
109
+ return {
110
+ response,
111
+ asyncTasks,
112
+ }
113
+ }
114
+
115
+ const handleQueryRequest = async ({
116
+ authData,
117
+ request,
118
+ }: {
119
+ authData: AuthData | null
120
+ request: Request
121
+ }) => {
122
+ if (!queries) {
123
+ throw new Error(
124
+ 'No queries registered with createZeroServer. ' +
125
+ 'Pass the syncedQueries registry to createZeroServer via the queries option.'
126
+ )
127
+ }
128
+
129
+ // set authData globally for permission checks in query functions
130
+ setAuthData(authData || ({} as AuthData))
131
+
132
+ const response = await zeroHandleQueryRequest(
133
+ (name, args) => {
134
+ const query = (mustGetQuery as any)(queries, name)
135
+ return query.fn({ args, ctx: authData })
136
+ },
137
+ schema,
138
+ request
139
+ )
140
+
141
+ return {
142
+ response,
143
+ }
144
+ }
145
+
146
+ const mutate = async (
147
+ run: (tx: Transaction, mutators: GetZeroMutators<Models>) => Promise<void>,
148
+ authData?: Pick<AuthData, 'email' | 'id'> & Partial<AuthData>
149
+ ) => {
150
+ const asyncTasks: Array<() => Promise<void>> = []
151
+
152
+ const mutators = createMutators({
153
+ models,
154
+ environment: 'server',
155
+ asyncTasks,
156
+ authData: {
157
+ id: '',
158
+ email: 'admin@start.chat',
159
+ role: 'admin',
160
+ ...authData,
161
+ },
162
+ createServerActions,
163
+ can: permissions.can,
164
+ })
165
+
166
+ await transaction(async (tx) => {
167
+ await run(tx, mutators)
168
+ })
169
+
170
+ await Promise.all(asyncTasks.map((t) => t()))
171
+ }
172
+
173
+ async function transaction<
174
+ CB extends (tx: Transaction) => Promise<any>,
175
+ Returns extends CB extends (tx: Transaction) => Promise<infer X> ? X : never,
176
+ >(query: CB): Promise<Returns> {
177
+ try {
178
+ if (isInZeroMutation()) {
179
+ const { tx } = mutatorContext()
180
+ return await query(tx)
181
+ }
182
+ // @ts-expect-error type
183
+ const output = await zeroDb.transaction(query, dummyTransactionInput)
184
+ return output
185
+ } catch (err) {
186
+ console.error(`Error running transaction(): ${err}`)
187
+ throw err
188
+ }
189
+ }
190
+
191
+ function query<R>(
192
+ cb: (q: Transaction['query']) => Query<any, Schema, R>
193
+ ): Promise<HumanReadable<R>> {
194
+ return transaction(async (tx) => {
195
+ return cb(tx.query)
196
+ }) as any
197
+ }
198
+
199
+ // register for global run() helper
200
+ if (queries) {
201
+ setCustomQueries(queries)
202
+ }
203
+
204
+ // server uses transaction-based execution
205
+ setRunner((queryObj) => {
206
+ return transaction(async (tx) => {
207
+ return tx.run(queryObj)
208
+ })
209
+ })
210
+
211
+ // This is needed temporarily and will be cleaned up in the future.
212
+ const dummyTransactionInput: TransactionProviderInput = {
213
+ clientGroupID: 'unused',
214
+ clientID: 'unused',
215
+ mutationID: 42,
216
+ upstreamSchema: 'unused',
217
+ }
218
+
219
+ return {
220
+ handleMutationRequest,
221
+ handleQueryRequest,
222
+ transaction,
223
+ mutate,
224
+ query,
225
+ }
226
+ }
@@ -0,0 +1,46 @@
1
+ import { sleep } from '@take-out/helpers'
2
+
3
+ import type { Query, Row } from '@rocicorp/zero'
4
+
5
+ export async function batchQuery<Q extends Query<any, any, any>, Item extends Row<Q>>(
6
+ q: Q,
7
+ mapper: (items: Item[]) => Promise<void>,
8
+ {
9
+ chunk,
10
+ pause = 0,
11
+ stopAfter = 100_000,
12
+ }: {
13
+ chunk: number
14
+ pause?: number
15
+ stopAfter?: number
16
+ } = { chunk: 20 }
17
+ ) {
18
+ let hasMore = true
19
+ let last: Item | null = null
20
+ let iterations = 0
21
+
22
+ while (hasMore) {
23
+ let query = q.limit(chunk)
24
+
25
+ if (last) {
26
+ query = query.start(last)
27
+ }
28
+
29
+ const results = await query.run({ type: 'complete' })
30
+
31
+ await mapper(results as Item[])
32
+
33
+ if (results.length < chunk) {
34
+ hasMore = false
35
+ }
36
+
37
+ if (iterations > stopAfter) {
38
+ console.error(`[batchQuery] ‼️ stopping batch, ran ${stopAfter} chunks`)
39
+ break
40
+ }
41
+
42
+ if (pause) {
43
+ await sleep(pause)
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,138 @@
1
+ import { mapObject, time } from '@take-out/helpers'
2
+
3
+ import { runWithContext } from './mutatorContext'
4
+
5
+ import { isBrowser, isServer } from '../constants'
6
+ import type {
7
+ AuthData,
8
+ Can,
9
+ GenericModels,
10
+ GetZeroMutators,
11
+ MutatorContext,
12
+ Transaction,
13
+ } from '../types'
14
+
15
+ export function createMutators<Models extends GenericModels>({
16
+ environment,
17
+ authData,
18
+ createServerActions,
19
+ asyncTasks = [],
20
+ can,
21
+ models,
22
+ }: {
23
+ environment: 'server' | 'client'
24
+ authData: AuthData | null
25
+ can: Can
26
+ models: Models
27
+ asyncTasks?: Array<() => Promise<void>>
28
+ createServerActions?: () => Record<string, any>
29
+ }): GetZeroMutators<Models> {
30
+ const serverActions = createServerActions?.()
31
+
32
+ const modelMutators = mapObject(models, (val) => val.mutate) as {
33
+ [K in keyof typeof models]: (typeof models)[K]['mutate']
34
+ }
35
+
36
+ function withContext<Args extends any[]>(fn: (...args: Args) => Promise<void>) {
37
+ return async (tx: Transaction, ...args: Args): Promise<void> => {
38
+ const mutationContext: MutatorContext = {
39
+ tx,
40
+ authData,
41
+ environment,
42
+ can,
43
+ server:
44
+ environment === 'server'
45
+ ? ({
46
+ actions: serverActions || {},
47
+ asyncTasks: asyncTasks || {},
48
+ } as MutatorContext['server'])
49
+ : undefined,
50
+ }
51
+
52
+ return await runWithContext(mutationContext, () => {
53
+ // @ts-expect-error type shenanigan
54
+ // map to our mutations() helper
55
+ return fn(mutationContext, ...args)
56
+ })
57
+ }
58
+ }
59
+
60
+ function withDevelopmentLogging<Args extends any[]>(
61
+ name: string,
62
+ fn: (...args: Args) => Promise<void>
63
+ ) {
64
+ if (process.env.NODE_ENV !== 'development' && !process.env.IS_TESTING) {
65
+ return fn
66
+ }
67
+
68
+ return async (...args: Args): Promise<void> => {
69
+ const startTime = performance.now()
70
+
71
+ try {
72
+ if (isServer) {
73
+ console.info(`[mutator] ${name} start`)
74
+ }
75
+ const result = await fn(...args)
76
+ const duration = (performance.now() - startTime).toFixed(2)
77
+ if (isBrowser) {
78
+ console.groupCollapsed(`[mutator] ${name} completed in ${duration}ms`)
79
+ console.info('→', args[1])
80
+ console.info('←', result)
81
+ console.trace()
82
+ console.groupEnd()
83
+ } else {
84
+ // TODO in prod just track
85
+ console.info(`[mutator] ${name} completed in ${duration}ms`)
86
+ }
87
+ return result
88
+ } catch (error) {
89
+ const duration = (performance.now() - startTime).toFixed(2)
90
+ console.groupCollapsed(`[mutator] ${name} failed after ${duration}ms`)
91
+ console.error('error:', error)
92
+ console.info('arguments:', JSON.stringify(args[1], null, 2))
93
+ console.info('stack trace:', new Error().stack)
94
+ console.groupEnd()
95
+ throw error
96
+ }
97
+ }
98
+ }
99
+
100
+ function withTimeoutGuard<Args extends any[]>(
101
+ name: string,
102
+ fn: (...args: Args) => Promise<void>,
103
+ // don't want this too high - zero runs mutations in order and waits for the last to finish it seems
104
+ // so if one mutation gets stuck it will just sit there
105
+ timeoutMs: number = time.ms.minutes(1)
106
+ ) {
107
+ return async (...args: Args): Promise<void> => {
108
+ const timeoutPromise = new Promise<never>((_, reject) => {
109
+ setTimeout(() => {
110
+ reject(new Error(`[mutator] ${name} timeout after ${timeoutMs}ms`))
111
+ }, timeoutMs)
112
+ })
113
+
114
+ return Promise.race([fn(...args), timeoutPromise])
115
+ }
116
+ }
117
+
118
+ function decorateMutators<T extends Record<string, Record<string, any>>>(modules: T) {
119
+ const result: any = {}
120
+
121
+ for (const [moduleName, moduleExports] of Object.entries(modules)) {
122
+ result[moduleName] = {}
123
+ for (const [name, exportValue] of Object.entries(moduleExports)) {
124
+ if (typeof exportValue === 'function') {
125
+ const fullName = `${moduleName}.${name}`
126
+ result[moduleName][name] = withDevelopmentLogging(
127
+ fullName,
128
+ withTimeoutGuard(fullName, withContext(exportValue))
129
+ )
130
+ }
131
+ }
132
+ }
133
+
134
+ return result
135
+ }
136
+
137
+ return decorateMutators(modelMutators)
138
+ }
@@ -0,0 +1,16 @@
1
+ import { globalValue } from '@take-out/helpers'
2
+
3
+ import type { MutatorContext } from '../types'
4
+
5
+ const PermissionCheckRan = globalValue(
6
+ `on-zero:permissions-check`,
7
+ () => new WeakMap<MutatorContext, boolean>()
8
+ )
9
+
10
+ export const getDidRunPermissionCheck = (ctx: MutatorContext) => {
11
+ return PermissionCheckRan.get(ctx)
12
+ }
13
+
14
+ export const setDidRunPermissionCheck = (ctx: MutatorContext) => {
15
+ return PermissionCheckRan.set(ctx, true)
16
+ }
@@ -0,0 +1,11 @@
1
+ import { ensure } from '@take-out/helpers'
2
+
3
+ import { mutatorContext } from './mutatorContext'
4
+
5
+ import type { AuthData } from '../types'
6
+
7
+ export const ensureLoggedIn = (): AuthData => {
8
+ const { authData } = mutatorContext()
9
+ ensure(authData, 'logged in')
10
+ return authData
11
+ }
@@ -0,0 +1,12 @@
1
+ import { getAuthData } from '../state'
2
+ import { isInZeroMutation, mutatorContext } from './mutatorContext'
3
+
4
+ import type { AuthData } from '../types'
5
+
6
+ export function getQueryOrMutatorAuthData(): AuthData | null {
7
+ if (isInZeroMutation()) {
8
+ return mutatorContext().authData as AuthData
9
+ }
10
+
11
+ return getAuthData()
12
+ }
@@ -0,0 +1,25 @@
1
+ import { createAsyncContext } from '@take-out/helpers'
2
+
3
+ import type { MutatorContext } from '../types'
4
+
5
+ const asyncContext = createAsyncContext<MutatorContext>()
6
+
7
+ export function mutatorContext(): MutatorContext {
8
+ const currentContext = asyncContext.get()
9
+ if (!currentContext) {
10
+ throw new Error('mutatorContext must be called within a mutator')
11
+ }
12
+
13
+ return currentContext
14
+ }
15
+
16
+ export function isInZeroMutation() {
17
+ return !!asyncContext.get()
18
+ }
19
+
20
+ export function runWithContext<T>(
21
+ context: MutatorContext,
22
+ fn: () => T | Promise<T>
23
+ ): Promise<T> {
24
+ return asyncContext.run(context, fn)
25
+ }
@@ -0,0 +1,167 @@
1
+ import { ellipsis } from '@take-out/helpers'
2
+
3
+ import type { Query } from '@rocicorp/zero'
4
+
5
+ export const prettyFormatZeroQuery = (
6
+ query: Query<any, any, any>,
7
+ mode: 'full' | 'minimal' = 'full'
8
+ ): string => {
9
+ const astObject = query['_completeAst']?.()
10
+
11
+ if (!astObject) return ''
12
+
13
+ if (mode === 'minimal') {
14
+ return prettyFormatMinimal(astObject)
15
+ }
16
+ return prettyFormatFull(astObject)
17
+ }
18
+
19
+ const prettyFormatFull = (astObject: any, indent = 0): string => {
20
+ if (!astObject || !astObject.table) return ''
21
+
22
+ const spaces = ' '.repeat(indent)
23
+ let query = astObject.table
24
+ let hasChainedMethods = false
25
+
26
+ // Add where conditions
27
+ if (astObject.where) {
28
+ const whereClause = formatWhere(astObject.where)
29
+ if (hasChainedMethods) {
30
+ query += `\n${spaces} ${whereClause}`
31
+ } else {
32
+ query += whereClause
33
+ hasChainedMethods = true
34
+ }
35
+ }
36
+
37
+ // Add limit
38
+ if (astObject.limit) {
39
+ const limitClause = `.limit(${astObject.limit})`
40
+ if (hasChainedMethods) {
41
+ query += `\n${spaces} ${limitClause}`
42
+ } else {
43
+ query += limitClause
44
+ hasChainedMethods = true
45
+ }
46
+ }
47
+
48
+ // Add orderBy
49
+ if (astObject.orderBy && astObject.orderBy.length > 0) {
50
+ const orderClauses = astObject.orderBy
51
+ .map(([field, direction]: [string, string]) => `${field}, ${direction}`)
52
+ .join(', ')
53
+ const orderByClause = `.orderBy(${orderClauses})`
54
+ if (hasChainedMethods) {
55
+ query += `\n${spaces} ${orderByClause}`
56
+ } else {
57
+ query += orderByClause
58
+ hasChainedMethods = true
59
+ }
60
+ }
61
+
62
+ // Add related queries
63
+ if (astObject.related && astObject.related.length > 0) {
64
+ astObject.related.forEach((rel: any) => {
65
+ if (rel.subquery) {
66
+ const alias = rel.subquery.alias || rel.subquery.table
67
+ const subQuery = prettyFormatFull(rel.subquery, indent + 1)
68
+ query += `\n${spaces} .related(${alias}, q => q.${subQuery}`
69
+ }
70
+ })
71
+
72
+ // Add closing parentheses
73
+ const closingParens = ')'.repeat(astObject.related.length)
74
+ query += `\n${spaces}${closingParens}`
75
+ }
76
+
77
+ return query
78
+ }
79
+
80
+ const prettyFormatMinimal = (astObject: any): string => {
81
+ if (!astObject || !astObject.table) return ''
82
+
83
+ let query = astObject.table
84
+
85
+ // Add where conditions only
86
+ if (astObject.where) {
87
+ query += formatWhere(astObject.where).replace('.where(', '(')
88
+ }
89
+
90
+ // Add sub-queries info if present
91
+ if (astObject.related && astObject.related.length > 0) {
92
+ const subQueries = collectSubQueryTables(astObject.related)
93
+ const count = subQueries.length
94
+ const tableNames = subQueries.join(', ')
95
+ query += ` (+${count}: ${ellipsis(tableNames, 30)})`
96
+ }
97
+
98
+ return query
99
+ }
100
+
101
+ const collectSubQueryTables = (related: any[]): string[] => {
102
+ const tables: string[] = []
103
+
104
+ related.forEach((rel: any) => {
105
+ if (rel.subquery) {
106
+ const tableName = rel.subquery.alias || rel.subquery.table
107
+ tables.push(tableName)
108
+
109
+ // Recursively collect nested sub-queries
110
+ if (rel.subquery.related && rel.subquery.related.length > 0) {
111
+ tables.push(...collectSubQueryTables(rel.subquery.related))
112
+ }
113
+ }
114
+ })
115
+
116
+ return tables
117
+ }
118
+
119
+ const formatWhere = (where: any): string => {
120
+ if (!where) return ''
121
+
122
+ if (where.type === 'simple') {
123
+ const column = where.left?.name || where.left
124
+ const value = where.right?.value !== undefined ? where.right.value : where.right
125
+ const op = where.op || '='
126
+
127
+ // Special case: if column is "id" and op is "=" and value is a single item, show just the value
128
+ if (
129
+ column === 'id' &&
130
+ op === '=' &&
131
+ (typeof value === 'string' || typeof value === 'number')
132
+ ) {
133
+ return `(${value})`
134
+ }
135
+
136
+ if (op === '=') {
137
+ return `.where(${column}, ${value})`
138
+ }
139
+ return `.where(${column}, ${op}, ${value})`
140
+ }
141
+
142
+ if (where.type === 'and' && where.conditions) {
143
+ let result = ''
144
+ where.conditions.forEach((condition: any, index: number) => {
145
+ if (index === 0) {
146
+ result += formatWhere(condition)
147
+ } else {
148
+ result += `.and(${formatWhere(condition).slice(1)})` // Remove the leading dot
149
+ }
150
+ })
151
+ return result
152
+ }
153
+
154
+ if (where.type === 'or' && where.conditions) {
155
+ let result = ''
156
+ where.conditions.forEach((condition: any, index: number) => {
157
+ if (index === 0) {
158
+ result += formatWhere(condition)
159
+ } else {
160
+ result += `.or(${formatWhere(condition).slice(1)})` // Remove the leading dot
161
+ }
162
+ })
163
+ return result
164
+ }
165
+
166
+ return ''
167
+ }