@rocicorp/zero 1.2.0-canary.1 → 1.2.0-canary.12

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 (309) hide show
  1. package/out/analyze-query/src/bin-analyze.js +25 -25
  2. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  3. package/out/ast-to-zql/src/ast-to-zql.d.ts.map +1 -1
  4. package/out/ast-to-zql/src/ast-to-zql.js +2 -1
  5. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  6. package/out/ast-to-zql/src/format.d.ts.map +1 -1
  7. package/out/ast-to-zql/src/format.js +6 -6
  8. package/out/ast-to-zql/src/format.js.map +1 -1
  9. package/out/replicache/src/btree/node.d.ts.map +1 -1
  10. package/out/replicache/src/btree/node.js +2 -2
  11. package/out/replicache/src/btree/node.js.map +1 -1
  12. package/out/replicache/src/connection-loop.js +3 -3
  13. package/out/replicache/src/connection-loop.js.map +1 -1
  14. package/out/replicache/src/deleted-clients.d.ts +0 -4
  15. package/out/replicache/src/deleted-clients.d.ts.map +1 -1
  16. package/out/replicache/src/deleted-clients.js +1 -1
  17. package/out/replicache/src/deleted-clients.js.map +1 -1
  18. package/out/replicache/src/hash.d.ts.map +1 -1
  19. package/out/replicache/src/hash.js.map +1 -1
  20. package/out/replicache/src/process-scheduler.d.ts.map +1 -1
  21. package/out/replicache/src/process-scheduler.js.map +1 -1
  22. package/out/replicache/src/request-idle.js +1 -1
  23. package/out/replicache/src/request-idle.js.map +1 -1
  24. package/out/replicache/src/sync/patch.d.ts +1 -1
  25. package/out/replicache/src/sync/patch.d.ts.map +1 -1
  26. package/out/replicache/src/sync/patch.js +1 -1
  27. package/out/replicache/src/sync/patch.js.map +1 -1
  28. package/out/shared/src/arrays.d.ts.map +1 -1
  29. package/out/shared/src/arrays.js +1 -2
  30. package/out/shared/src/arrays.js.map +1 -1
  31. package/out/shared/src/bigint-json.d.ts.map +1 -1
  32. package/out/shared/src/bigint-json.js +1 -1
  33. package/out/shared/src/bigint-json.js.map +1 -1
  34. package/out/shared/src/btree-set.d.ts.map +1 -1
  35. package/out/shared/src/btree-set.js +74 -42
  36. package/out/shared/src/btree-set.js.map +1 -1
  37. package/out/shared/src/iterables.d.ts +7 -0
  38. package/out/shared/src/iterables.d.ts.map +1 -1
  39. package/out/shared/src/iterables.js +10 -1
  40. package/out/shared/src/iterables.js.map +1 -1
  41. package/out/shared/src/logging.d.ts.map +1 -1
  42. package/out/shared/src/logging.js +10 -9
  43. package/out/shared/src/logging.js.map +1 -1
  44. package/out/shared/src/options.js +1 -1
  45. package/out/shared/src/options.js.map +1 -1
  46. package/out/shared/src/tdigest-schema.d.ts.map +1 -1
  47. package/out/shared/src/tdigest-schema.js.map +1 -1
  48. package/out/shared/src/tdigest.d.ts.map +1 -1
  49. package/out/shared/src/tdigest.js +7 -7
  50. package/out/shared/src/tdigest.js.map +1 -1
  51. package/out/shared/src/valita.d.ts.map +1 -1
  52. package/out/shared/src/valita.js +1 -1
  53. package/out/shared/src/valita.js.map +1 -1
  54. package/out/z2s/src/sql.d.ts +2 -2
  55. package/out/z2s/src/sql.d.ts.map +1 -1
  56. package/out/z2s/src/sql.js +4 -4
  57. package/out/z2s/src/sql.js.map +1 -1
  58. package/out/zero/package.js +9 -10
  59. package/out/zero/package.js.map +1 -1
  60. package/out/zero/src/pg.js +1 -1
  61. package/out/zero/src/server.js +1 -1
  62. package/out/zero-cache/src/auth/load-permissions.d.ts +2 -2
  63. package/out/zero-cache/src/auth/load-permissions.d.ts.map +1 -1
  64. package/out/zero-cache/src/auth/load-permissions.js +1 -1
  65. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  66. package/out/zero-cache/src/config/zero-config.d.ts +17 -1
  67. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  68. package/out/zero-cache/src/config/zero-config.js +37 -3
  69. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  70. package/out/zero-cache/src/custom/fetch.d.ts +1 -1
  71. package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
  72. package/out/zero-cache/src/custom/fetch.js +2 -0
  73. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  74. package/out/zero-cache/src/custom-queries/transform-query.d.ts.map +1 -1
  75. package/out/zero-cache/src/custom-queries/transform-query.js +5 -2
  76. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  77. package/out/zero-cache/src/db/migration-lite.d.ts.map +1 -1
  78. package/out/zero-cache/src/db/migration-lite.js +1 -1
  79. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  80. package/out/zero-cache/src/db/migration.d.ts.map +1 -1
  81. package/out/zero-cache/src/db/migration.js +1 -1
  82. package/out/zero-cache/src/db/migration.js.map +1 -1
  83. package/out/zero-cache/src/db/pg-copy-binary.d.ts +101 -0
  84. package/out/zero-cache/src/db/pg-copy-binary.d.ts.map +1 -0
  85. package/out/zero-cache/src/db/pg-copy-binary.js +381 -0
  86. package/out/zero-cache/src/db/pg-copy-binary.js.map +1 -0
  87. package/out/zero-cache/src/db/run-transaction.d.ts.map +1 -1
  88. package/out/zero-cache/src/db/run-transaction.js +2 -2
  89. package/out/zero-cache/src/db/run-transaction.js.map +1 -1
  90. package/out/zero-cache/src/db/transaction-pool.d.ts.map +1 -1
  91. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  92. package/out/zero-cache/src/db/warmup.d.ts.map +1 -1
  93. package/out/zero-cache/src/db/warmup.js +3 -1
  94. package/out/zero-cache/src/db/warmup.js.map +1 -1
  95. package/out/zero-cache/src/observability/metrics.d.ts +1 -1
  96. package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
  97. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  98. package/out/zero-cache/src/server/anonymous-otel-start.d.ts.map +1 -1
  99. package/out/zero-cache/src/server/anonymous-otel-start.js +8 -2
  100. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  101. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  102. package/out/zero-cache/src/server/change-streamer.js +3 -1
  103. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  104. package/out/zero-cache/src/server/logging.d.ts.map +1 -1
  105. package/out/zero-cache/src/server/logging.js +9 -1
  106. package/out/zero-cache/src/server/logging.js.map +1 -1
  107. package/out/zero-cache/src/server/main.js +1 -1
  108. package/out/zero-cache/src/server/main.js.map +1 -1
  109. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  110. package/out/zero-cache/src/server/replicator.js +28 -1
  111. package/out/zero-cache/src/server/replicator.js.map +1 -1
  112. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  113. package/out/zero-cache/src/server/syncer.js +8 -10
  114. package/out/zero-cache/src/server/syncer.js.map +1 -1
  115. package/out/zero-cache/src/server/worker-urls.d.ts.map +1 -1
  116. package/out/zero-cache/src/server/worker-urls.js +2 -1
  117. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  118. package/out/zero-cache/src/services/change-source/change-source.d.ts +5 -1
  119. package/out/zero-cache/src/services/change-source/change-source.d.ts.map +1 -1
  120. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
  121. package/out/zero-cache/src/services/change-source/common/replica-schema.js +13 -1
  122. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  123. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +1 -1
  124. package/out/zero-cache/src/services/change-source/custom/change-source.js +7 -4
  125. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  126. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  127. package/out/zero-cache/src/services/change-source/pg/change-source.js +74 -23
  128. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  129. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +1 -0
  130. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  131. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +85 -5
  132. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  133. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +1 -1
  134. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +1 -1
  135. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  136. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts +1 -1
  137. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
  138. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +31 -1
  139. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  140. package/out/zero-cache/src/services/change-streamer/broadcast.js +1 -1
  141. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  142. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +1 -1
  143. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +3 -3
  144. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  145. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +4 -0
  146. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
  147. package/out/zero-cache/src/services/change-streamer/change-streamer.js +9 -1
  148. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  149. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  150. package/out/zero-cache/src/services/change-streamer/storer.js +1 -1
  151. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  152. package/out/zero-cache/src/services/life-cycle.d.ts +1 -0
  153. package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
  154. package/out/zero-cache/src/services/life-cycle.js +2 -2
  155. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  156. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  157. package/out/zero-cache/src/services/litestream/commands.js +5 -5
  158. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  159. package/out/zero-cache/src/services/mutagen/pusher.d.ts +2 -2
  160. package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
  161. package/out/zero-cache/src/services/mutagen/pusher.js +7 -4
  162. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  163. package/out/zero-cache/src/services/replicator/change-processor.js +1 -1
  164. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  165. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  166. package/out/zero-cache/src/services/replicator/incremental-sync.js +6 -3
  167. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  168. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  169. package/out/zero-cache/src/services/replicator/schema/column-metadata.d.ts +1 -1
  170. package/out/zero-cache/src/services/replicator/schema/column-metadata.d.ts.map +1 -1
  171. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  172. package/out/zero-cache/src/services/replicator/schema/replication-state.d.ts.map +1 -1
  173. package/out/zero-cache/src/services/replicator/schema/replication-state.js +6 -3
  174. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  175. package/out/zero-cache/src/services/view-syncer/client-schema.d.ts.map +1 -1
  176. package/out/zero-cache/src/services/view-syncer/client-schema.js +4 -3
  177. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  178. package/out/zero-cache/src/services/view-syncer/cvr-store.js +2 -2
  179. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  180. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  181. package/out/zero-cache/src/services/view-syncer/cvr.js +12 -9
  182. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  183. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +1 -1
  184. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  185. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +3 -1
  186. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  187. package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +1 -1
  188. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +13 -7
  189. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  190. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +1 -1
  191. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  192. package/out/zero-cache/src/services/view-syncer/snapshotter.js +1 -1
  193. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  194. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  195. package/out/zero-cache/src/services/view-syncer/view-syncer.js +34 -15
  196. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  197. package/out/zero-cache/src/types/lite.d.ts.map +1 -1
  198. package/out/zero-cache/src/types/lite.js +3 -2
  199. package/out/zero-cache/src/types/lite.js.map +1 -1
  200. package/out/zero-cache/src/types/pg-types.js +4 -1
  201. package/out/zero-cache/src/types/pg-types.js.map +1 -1
  202. package/out/zero-cache/src/types/pg.d.ts +1 -0
  203. package/out/zero-cache/src/types/pg.d.ts.map +1 -1
  204. package/out/zero-cache/src/types/pg.js +26 -10
  205. package/out/zero-cache/src/types/pg.js.map +1 -1
  206. package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
  207. package/out/zero-cache/src/types/subscription.js +2 -2
  208. package/out/zero-cache/src/types/subscription.js.map +1 -1
  209. package/out/zero-cache/src/workers/connection.js.map +1 -1
  210. package/out/zero-cache/src/workers/replicator.d.ts +5 -2
  211. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  212. package/out/zero-cache/src/workers/replicator.js +10 -6
  213. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  214. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts +1 -1
  215. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  216. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +18 -2
  217. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  218. package/out/zero-cache/src/workers/syncer.d.ts +1 -1
  219. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  220. package/out/zero-cache/src/workers/syncer.js +5 -5
  221. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  222. package/out/zero-client/src/client/http-string.d.ts.map +1 -1
  223. package/out/zero-client/src/client/http-string.js.map +1 -1
  224. package/out/zero-client/src/client/metrics.d.ts.map +1 -1
  225. package/out/zero-client/src/client/metrics.js +2 -1
  226. package/out/zero-client/src/client/metrics.js.map +1 -1
  227. package/out/zero-client/src/client/server-option.js +1 -1
  228. package/out/zero-client/src/client/server-option.js.map +1 -1
  229. package/out/zero-client/src/client/version.js +1 -1
  230. package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
  231. package/out/zero-client/src/client/zero-poke-handler.js +7 -3
  232. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  233. package/out/zero-pg/src/mod.js +1 -1
  234. package/out/zero-protocol/src/application-error.d.ts +1 -1
  235. package/out/zero-protocol/src/application-error.d.ts.map +1 -1
  236. package/out/zero-protocol/src/application-error.js.map +1 -1
  237. package/out/zero-protocol/src/ast.d.ts.map +1 -1
  238. package/out/zero-protocol/src/ast.js.map +1 -1
  239. package/out/zero-protocol/src/primary-key.d.ts.map +1 -1
  240. package/out/zero-protocol/src/primary-key.js.map +1 -1
  241. package/out/zero-protocol/src/push.d.ts.map +1 -1
  242. package/out/zero-protocol/src/push.js.map +1 -1
  243. package/out/zero-schema/src/name-mapper.js +1 -1
  244. package/out/zero-schema/src/name-mapper.js.map +1 -1
  245. package/out/zero-server/src/mod.js +1 -1
  246. package/out/zero-server/src/process-mutations.d.ts.map +1 -1
  247. package/out/zero-server/src/process-mutations.js +2 -1
  248. package/out/zero-server/src/process-mutations.js.map +1 -1
  249. package/out/zero-server/src/push-processor.d.ts +1 -0
  250. package/out/zero-server/src/push-processor.d.ts.map +1 -1
  251. package/out/zero-server/src/push-processor.js +3 -2
  252. package/out/zero-server/src/push-processor.js.map +1 -1
  253. package/out/zero-types/src/name-mapper.d.ts +1 -0
  254. package/out/zero-types/src/name-mapper.d.ts.map +1 -1
  255. package/out/zero-types/src/name-mapper.js +3 -0
  256. package/out/zero-types/src/name-mapper.js.map +1 -1
  257. package/out/zql/src/builder/builder.d.ts.map +1 -1
  258. package/out/zql/src/builder/builder.js +5 -15
  259. package/out/zql/src/builder/builder.js.map +1 -1
  260. package/out/zql/src/builder/like.js +2 -1
  261. package/out/zql/src/builder/like.js.map +1 -1
  262. package/out/zql/src/ivm/data.d.ts.map +1 -1
  263. package/out/zql/src/ivm/data.js +6 -15
  264. package/out/zql/src/ivm/data.js.map +1 -1
  265. package/out/zql/src/ivm/memory-source.d.ts +1 -1
  266. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  267. package/out/zql/src/ivm/memory-source.js +4 -6
  268. package/out/zql/src/ivm/memory-source.js.map +1 -1
  269. package/out/zql/src/ivm/take.d.ts.map +1 -1
  270. package/out/zql/src/ivm/take.js +2 -2
  271. package/out/zql/src/ivm/take.js.map +1 -1
  272. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  273. package/out/zql/src/ivm/view-apply-change.js +34 -26
  274. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  275. package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
  276. package/out/zql/src/planner/planner-debug.js.map +1 -1
  277. package/out/zql/src/query/complete-ordering.js +1 -1
  278. package/out/zql/src/query/complete-ordering.js.map +1 -1
  279. package/out/zql/src/query/expression.d.ts +1 -1
  280. package/out/zql/src/query/expression.d.ts.map +1 -1
  281. package/out/zql/src/query/expression.js.map +1 -1
  282. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  283. package/out/zql/src/query/query-impl.js +2 -2
  284. package/out/zql/src/query/query-impl.js.map +1 -1
  285. package/out/zql/src/query/query-registry.d.ts.map +1 -1
  286. package/out/zql/src/query/query-registry.js +2 -1
  287. package/out/zql/src/query/query-registry.js.map +1 -1
  288. package/out/zql/src/query/query.d.ts +1 -2
  289. package/out/zql/src/query/query.d.ts.map +1 -1
  290. package/out/zql/src/query/ttl.js +1 -1
  291. package/out/zql/src/query/ttl.js.map +1 -1
  292. package/out/zqlite/src/internal/sql.d.ts +2 -2
  293. package/out/zqlite/src/internal/sql.d.ts.map +1 -1
  294. package/out/zqlite/src/internal/sql.js +1 -2
  295. package/out/zqlite/src/internal/sql.js.map +1 -1
  296. package/out/zqlite/src/sqlite-cost-model.d.ts +1 -1
  297. package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -1
  298. package/out/zqlite/src/sqlite-cost-model.js +1 -1
  299. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  300. package/out/zqlite/src/sqlite-stat-fanout.js +1 -1
  301. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  302. package/out/zqlite/src/table-source.d.ts.map +1 -1
  303. package/out/zqlite/src/table-source.js +8 -12
  304. package/out/zqlite/src/table-source.js.map +1 -1
  305. package/package.json +9 -10
  306. package/out/zql/src/ivm/cap.d.ts +0 -32
  307. package/out/zql/src/ivm/cap.d.ts.map +0 -1
  308. package/out/zql/src/ivm/cap.js +0 -226
  309. package/out/zql/src/ivm/cap.js.map +0 -1
@@ -7,5 +7,12 @@ type IteratorWithHelpers<T> = Iterator<T> & {
7
7
  [Symbol.iterator](): IteratorWithHelpers<T>;
8
8
  };
9
9
  export declare function wrapIterable<T>(iter: Iterable<T>): IteratorWithHelpers<T>;
10
+ /**
11
+ * This will make a new array where the elements are the same as the iterable
12
+ * but sorted according to the compare function. If the compare function is not
13
+ * provided, it will sort the elements in JS standard way which is string
14
+ * compare.
15
+ */
16
+ export declare function toSorted<T>(iter: Iterable<T>, compare?: (a: T, b: T) => number): T[];
10
17
  export {};
11
18
  //# sourceMappingURL=iterables.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"iterables.d.ts","sourceRoot":"","sources":["../../../../shared/src/iterables.ts"],"names":[],"mappings":"AAAA,wBAAiB,aAAa,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,2BAIxD;AAwBD,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAK3D;AAED,wBAAiB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAOzD;AAKD,KAAK,mBAAmB,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG;IAC1C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAC9D,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,mBAAmB,CAAC,CAAC,CAAC,CAAC;CAC7C,CAAC;AAyCF,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAEzE"}
1
+ {"version":3,"file":"iterables.d.ts","sourceRoot":"","sources":["../../../../shared/src/iterables.ts"],"names":[],"mappings":"AAAA,wBAAiB,aAAa,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,2BAIxD;AAwBD,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAK3D;AAED,wBAAiB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAOzD;AAKD,KAAK,mBAAmB,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG;IAC1C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAC9D,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,mBAAmB,CAAC,CAAC,CAAC,CAAC;CAC7C,CAAC;AAyCF,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAEzE;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACxB,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,EACjB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,GAC/B,CAAC,EAAE,CAGL"}
@@ -38,7 +38,16 @@ var IterWrapper = class IterWrapper {
38
38
  function wrapIterable(iter) {
39
39
  return iteratorFrom(iter);
40
40
  }
41
+ /**
42
+ * This will make a new array where the elements are the same as the iterable
43
+ * but sorted according to the compare function. If the compare function is not
44
+ * provided, it will sort the elements in JS standard way which is string
45
+ * compare.
46
+ */
47
+ function toSorted(iter, compare) {
48
+ return [...iter].sort(compare);
49
+ }
41
50
  //#endregion
42
- export { joinIterables, once, wrapIterable };
51
+ export { joinIterables, once, toSorted, wrapIterable };
43
52
 
44
53
  //# sourceMappingURL=iterables.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"iterables.js","names":["#iterator"],"sources":["../../../../shared/src/iterables.ts"],"sourcesContent":["export function* joinIterables<T>(...iters: Iterable<T>[]) {\n for (const iter of iters) {\n yield* iter;\n }\n}\n\nfunction* filterIter<T>(\n iter: Iterable<T>,\n p: (t: T, index: number) => boolean,\n): Iterable<T> {\n let index = 0;\n for (const t of iter) {\n if (p(t, index++)) {\n yield t;\n }\n }\n}\n\nfunction* mapIter<T, U>(\n iter: Iterable<T>,\n f: (t: T, index: number) => U,\n): Iterable<U> {\n let index = 0;\n for (const t of iter) {\n yield f(t, index++);\n }\n}\n\nexport function first<T>(stream: Iterable<T>): T | undefined {\n const it = stream[Symbol.iterator]();\n const {value} = it.next();\n it.return?.();\n return value;\n}\n\nexport function* once<T>(stream: Iterable<T>): Iterable<T> {\n const it = stream[Symbol.iterator]();\n const {value} = it.next();\n if (value !== undefined) {\n yield value;\n }\n it.return?.();\n}\n\n// ES2024 Iterator helpers are available in Node 22+ and part of ES2024.\n// https://github.com/tc39/proposal-iterator-helpers\n\ntype IteratorWithHelpers<T> = Iterator<T> & {\n map<U>(f: (t: T, index: number) => U): IteratorWithHelpers<U>;\n filter(p: (t: T, index: number) => boolean): IteratorWithHelpers<T>;\n [Symbol.iterator](): IteratorWithHelpers<T>;\n};\n\ntype IteratorConstructor = {\n from<T>(this: void, iter: Iterable<T>): IteratorWithHelpers<T>;\n};\n\n// Check if native Iterator.from is available and bind it once at startup\n// We use globalThis to access the runtime value safely\nconst iteratorCtor = (globalThis as {Iterator?: IteratorConstructor}).Iterator;\nconst nativeIteratorFrom = iteratorCtor?.from as\n | (<T>(iter: Iterable<T>) => IteratorWithHelpers<T>)\n | undefined;\n\nconst iteratorFrom: <T>(e: Iterable<T>) => IteratorWithHelpers<T> =\n nativeIteratorFrom ?? (e => new IterWrapper(e));\n\n// Fallback implementation for environments without ES2024 Iterator helpers\nclass IterWrapper<T> implements IteratorWithHelpers<T>, IterableIterator<T> {\n readonly #iterator: Iterator<T>;\n\n constructor(iterable: Iterable<T>) {\n this.#iterator = iterable[Symbol.iterator]();\n }\n\n next(): IteratorResult<T> {\n return this.#iterator.next();\n }\n\n [Symbol.iterator](): IteratorWithHelpers<T> {\n return this;\n }\n\n map<U>(f: (t: T, index: number) => U): IterWrapper<U> {\n return new IterWrapper(mapIter(this, f));\n }\n\n filter(p: (t: T, index: number) => boolean): IterWrapper<T> {\n return new IterWrapper(filterIter(this, p));\n }\n}\n\nexport function wrapIterable<T>(iter: Iterable<T>): IteratorWithHelpers<T> {\n return iteratorFrom(iter);\n}\n"],"mappings":";AAAA,UAAiB,cAAiB,GAAG,OAAsB;AACzD,MAAK,MAAM,QAAQ,MACjB,QAAO;;AAIX,UAAU,WACR,MACA,GACa;CACb,IAAI,QAAQ;AACZ,MAAK,MAAM,KAAK,KACd,KAAI,EAAE,GAAG,QAAQ,CACf,OAAM;;AAKZ,UAAU,QACR,MACA,GACa;CACb,IAAI,QAAQ;AACZ,MAAK,MAAM,KAAK,KACd,OAAM,EAAE,GAAG,QAAQ;;AAWvB,UAAiB,KAAQ,QAAkC;CACzD,MAAM,KAAK,OAAO,OAAO,WAAW;CACpC,MAAM,EAAC,UAAS,GAAG,MAAM;AACzB,KAAI,UAAU,KAAA,EACZ,OAAM;AAER,IAAG,UAAU;;AAuBf,IAAM,eALgB,WAAgD,UAC7B,UAKhB,MAAK,IAAI,YAAY,EAAE;AAGhD,IAAM,cAAN,MAAM,YAAsE;CAC1E;CAEA,YAAY,UAAuB;AACjC,QAAA,WAAiB,SAAS,OAAO,WAAW;;CAG9C,OAA0B;AACxB,SAAO,MAAA,SAAe,MAAM;;CAG9B,CAAC,OAAO,YAAoC;AAC1C,SAAO;;CAGT,IAAO,GAA+C;AACpD,SAAO,IAAI,YAAY,QAAQ,MAAM,EAAE,CAAC;;CAG1C,OAAO,GAAqD;AAC1D,SAAO,IAAI,YAAY,WAAW,MAAM,EAAE,CAAC;;;AAI/C,SAAgB,aAAgB,MAA2C;AACzE,QAAO,aAAa,KAAK"}
1
+ {"version":3,"file":"iterables.js","names":["#iterator"],"sources":["../../../../shared/src/iterables.ts"],"sourcesContent":["export function* joinIterables<T>(...iters: Iterable<T>[]) {\n for (const iter of iters) {\n yield* iter;\n }\n}\n\nfunction* filterIter<T>(\n iter: Iterable<T>,\n p: (t: T, index: number) => boolean,\n): Iterable<T> {\n let index = 0;\n for (const t of iter) {\n if (p(t, index++)) {\n yield t;\n }\n }\n}\n\nfunction* mapIter<T, U>(\n iter: Iterable<T>,\n f: (t: T, index: number) => U,\n): Iterable<U> {\n let index = 0;\n for (const t of iter) {\n yield f(t, index++);\n }\n}\n\nexport function first<T>(stream: Iterable<T>): T | undefined {\n const it = stream[Symbol.iterator]();\n const {value} = it.next();\n it.return?.();\n return value;\n}\n\nexport function* once<T>(stream: Iterable<T>): Iterable<T> {\n const it = stream[Symbol.iterator]();\n const {value} = it.next();\n if (value !== undefined) {\n yield value;\n }\n it.return?.();\n}\n\n// ES2024 Iterator helpers are available in Node 22+ and part of ES2024.\n// https://github.com/tc39/proposal-iterator-helpers\n\ntype IteratorWithHelpers<T> = Iterator<T> & {\n map<U>(f: (t: T, index: number) => U): IteratorWithHelpers<U>;\n filter(p: (t: T, index: number) => boolean): IteratorWithHelpers<T>;\n [Symbol.iterator](): IteratorWithHelpers<T>;\n};\n\ntype IteratorConstructor = {\n from<T>(this: void, iter: Iterable<T>): IteratorWithHelpers<T>;\n};\n\n// Check if native Iterator.from is available and bind it once at startup\n// We use globalThis to access the runtime value safely\nconst iteratorCtor = (globalThis as {Iterator?: IteratorConstructor}).Iterator;\nconst nativeIteratorFrom = iteratorCtor?.from as\n | (<T>(iter: Iterable<T>) => IteratorWithHelpers<T>)\n | undefined;\n\nconst iteratorFrom: <T>(e: Iterable<T>) => IteratorWithHelpers<T> =\n nativeIteratorFrom ?? (e => new IterWrapper(e));\n\n// Fallback implementation for environments without ES2024 Iterator helpers\nclass IterWrapper<T> implements IteratorWithHelpers<T>, IterableIterator<T> {\n readonly #iterator: Iterator<T>;\n\n constructor(iterable: Iterable<T>) {\n this.#iterator = iterable[Symbol.iterator]();\n }\n\n next(): IteratorResult<T> {\n return this.#iterator.next();\n }\n\n [Symbol.iterator](): IteratorWithHelpers<T> {\n return this;\n }\n\n map<U>(f: (t: T, index: number) => U): IterWrapper<U> {\n return new IterWrapper(mapIter(this, f));\n }\n\n filter(p: (t: T, index: number) => boolean): IterWrapper<T> {\n return new IterWrapper(filterIter(this, p));\n }\n}\n\nexport function wrapIterable<T>(iter: Iterable<T>): IteratorWithHelpers<T> {\n return iteratorFrom(iter);\n}\n\n/**\n * This will make a new array where the elements are the same as the iterable\n * but sorted according to the compare function. If the compare function is not\n * provided, it will sort the elements in JS standard way which is string\n * compare.\n */\nexport function toSorted<T>(\n iter: Iterable<T>,\n compare?: (a: T, b: T) => number,\n): T[] {\n // oxlint-disable-next-line e18e/prefer-array-to-sorted\n return [...iter].sort(compare);\n}\n"],"mappings":";AAAA,UAAiB,cAAiB,GAAG,OAAsB;AACzD,MAAK,MAAM,QAAQ,MACjB,QAAO;;AAIX,UAAU,WACR,MACA,GACa;CACb,IAAI,QAAQ;AACZ,MAAK,MAAM,KAAK,KACd,KAAI,EAAE,GAAG,QAAQ,CACf,OAAM;;AAKZ,UAAU,QACR,MACA,GACa;CACb,IAAI,QAAQ;AACZ,MAAK,MAAM,KAAK,KACd,OAAM,EAAE,GAAG,QAAQ;;AAWvB,UAAiB,KAAQ,QAAkC;CACzD,MAAM,KAAK,OAAO,OAAO,WAAW;CACpC,MAAM,EAAC,UAAS,GAAG,MAAM;AACzB,KAAI,UAAU,KAAA,EACZ,OAAM;AAER,IAAG,UAAU;;AAuBf,IAAM,eALgB,WAAgD,UAC7B,UAKhB,MAAK,IAAI,YAAY,EAAE;AAGhD,IAAM,cAAN,MAAM,YAAsE;CAC1E;CAEA,YAAY,UAAuB;AACjC,QAAA,WAAiB,SAAS,OAAO,WAAW;;CAG9C,OAA0B;AACxB,SAAO,MAAA,SAAe,MAAM;;CAG9B,CAAC,OAAO,YAAoC;AAC1C,SAAO;;CAGT,IAAO,GAA+C;AACpD,SAAO,IAAI,YAAY,QAAQ,MAAM,EAAE,CAAC;;CAG1C,OAAO,GAAqD;AAC1D,SAAO,IAAI,YAAY,WAAW,MAAM,EAAE,CAAC;;;AAI/C,SAAgB,aAAgB,MAA2C;AACzE,QAAO,aAAa,KAAK;;;;;;;;AAS3B,SAAgB,SACd,MACA,SACK;AAEL,QAAO,CAAC,GAAG,KAAK,CAAC,KAAK,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../../../shared/src/logging.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,UAAU,EACV,KAAK,QAAQ,EACb,KAAK,OAAO,EACb,MAAM,kBAAkB,CAAC;AAK1B,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB,CAAC;AAQF;;;GAGG;AACH,eAAO,MAAM,YAAY;mBACR,OAAO,EAAE;qBAGP,OAAO,EAAE;oBAGV,OAAO,EAAE;oBAGT,OAAO,EAAE;qBAGR,OAAO,EAAE;CAG3B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,OAQzB,CAAC;AA4BF,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAErD;AAED,wBAAgB,gBAAgB,CAC9B,EAAC,GAAG,EAAC,EAAE;IAAC,GAAG,EAAE,SAAS,CAAA;CAAC,EACvB,OAAO,KAAK,EACZ,IAAI,sDAAkB,GACrB,UAAU,CAOZ;AA0BD,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQ5D"}
1
+ {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../../../shared/src/logging.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,UAAU,EACV,KAAK,QAAQ,EACb,KAAK,OAAO,EACb,MAAM,kBAAkB,CAAC;AAK1B,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB,CAAC;AAUF;;;GAGG;AACH,eAAO,MAAM,YAAY;mBACR,OAAO,EAAE;qBAGP,OAAO,EAAE;oBAGV,OAAO,EAAE;oBAGT,OAAO,EAAE;qBAGR,OAAO,EAAE;CAG3B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,OAQzB,CAAC;AA4BF,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAErD;AAED,wBAAgB,gBAAgB,CAC9B,EAAC,GAAG,EAAC,EAAE;IAAC,GAAG,EAAE,SAAS,CAAA;CAAC,EACvB,OAAO,KAAK,EACZ,IAAI,sDAAkB,GACrB,UAAU,CAOZ;AA0BD,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQ5D"}
@@ -1,13 +1,14 @@
1
1
  import { stringify } from "./bigint-json.js";
2
2
  import { LogContext } from "@rocicorp/logger";
3
3
  import { pid } from "node:process";
4
- import chalk from "chalk";
4
+ import { styleText } from "node:util";
5
5
  //#region ../shared/src/logging.ts
6
- var colors = {
7
- debug: chalk.grey,
8
- warn: chalk.yellow,
9
- error: chalk.red
10
- };
6
+ function style(color, args) {
7
+ return styleText(color, args.join(" "));
8
+ }
9
+ var COLOR_DEBUG = "gray";
10
+ var COLOR_WARN = "yellow";
11
+ var COLOR_ERROR = "red";
11
12
  /**
12
13
  * Returns an object for writing colorized output to a provided console.
13
14
  * Note this should only be used when console is a TTY (i.e., Node).
@@ -17,16 +18,16 @@ var colorConsole = {
17
18
  console.log(...args);
18
19
  },
19
20
  debug: (...args) => {
20
- console.debug(colors.debug(...args));
21
+ console.debug(style(COLOR_DEBUG, args));
21
22
  },
22
23
  info: (...args) => {
23
24
  console.info(...args);
24
25
  },
25
26
  warn: (...args) => {
26
- console.warn(colors.warn(...args));
27
+ console.warn(style(COLOR_WARN, args));
27
28
  },
28
29
  error: (...args) => {
29
- console.error(colors.error(...args));
30
+ console.error(style(COLOR_ERROR, args));
30
31
  }
31
32
  };
32
33
  var consoleSink = { log(level, context, ...args) {
@@ -1 +1 @@
1
- {"version":3,"file":"logging.js","names":[],"sources":["../../../../shared/src/logging.ts"],"sourcesContent":["/* oxlint-disable no-console */\nimport {\n type Context,\n LogContext,\n type LogLevel,\n type LogSink,\n} from '@rocicorp/logger';\nimport chalk from 'chalk';\nimport {pid} from 'node:process';\nimport {stringify} from './bigint-json.ts';\n\nexport type LogConfig = {\n level: LogLevel;\n format: 'text' | 'json';\n};\n\nconst colors = {\n debug: chalk.grey,\n warn: chalk.yellow,\n error: chalk.red,\n};\n\n/**\n * Returns an object for writing colorized output to a provided console.\n * Note this should only be used when console is a TTY (i.e., Node).\n */\nexport const colorConsole = {\n log: (...args: unknown[]) => {\n console.log(...args);\n },\n debug: (...args: unknown[]) => {\n console.debug(colors.debug(...args));\n },\n info: (...args: unknown[]) => {\n console.info(...args);\n },\n warn: (...args: unknown[]) => {\n console.warn(colors.warn(...args));\n },\n error: (...args: unknown[]) => {\n console.error(colors.error(...args));\n },\n};\n\nexport const consoleSink: LogSink = {\n log(level, context, ...args) {\n colorConsole[level](\n toLocalIsoString(),\n stringifyContext(context),\n ...args.map(stringifyValue),\n );\n },\n};\n\nfunction toLocalIsoString(date = new Date()) {\n const tzo = -date.getTimezoneOffset();\n const sign = tzo >= 0 ? '+' : '-';\n const pad = (n: number, len = 2) => String(Math.abs(n)).padStart(len, '0');\n\n return (\n date.getFullYear() +\n '-' +\n pad(date.getMonth() + 1) +\n '-' +\n pad(date.getDate()) +\n 'T' +\n pad(date.getHours()) +\n ':' +\n pad(date.getMinutes()) +\n ':' +\n pad(date.getSeconds()) +\n '.' +\n pad(date.getMilliseconds(), 3) +\n sign +\n pad(tzo / 60) +\n ':' +\n pad(tzo % 60)\n );\n}\n\nexport function getLogSink(config: LogConfig): LogSink {\n return config.format === 'json' ? consoleJsonLogSink : consoleSink;\n}\n\nexport function createLogContext(\n {log}: {log: LogConfig},\n context = {},\n sink = getLogSink(log),\n): LogContext {\n const ctx = {pid, ...context};\n const lc = new LogContext(log.level, ctx, sink);\n // Emit a blank line to absorb random ANSI control code garbage that\n // for some reason gets prepended to the first log line in CloudWatch.\n lc.info?.('');\n return lc;\n}\n\nconst consoleJsonLogSink: LogSink = {\n log(level: LogLevel, context: Context | undefined, ...args: unknown[]): void {\n // If the last arg is an object or an Error, combine those fields into the message.\n const lastObj = errorOrObject(args.at(-1));\n if (lastObj) {\n args.pop();\n }\n const message = args.length\n ? {\n message: args.map(stringifyValue).join(' '),\n }\n : undefined;\n\n console[level](\n stringify({\n level: level.toUpperCase(),\n ...context,\n ...lastObj,\n ...message,\n }),\n );\n },\n};\n\nexport function errorOrObject(v: unknown): object | undefined {\n if (v instanceof Error) {\n return toErrorLogObject(v);\n }\n if (v && typeof v === 'object') {\n return v;\n }\n return undefined;\n}\n\nfunction toErrorLogObject(v: Error) {\n return {\n ...v, // some properties of Error subclasses may be enumerable\n name: v.name,\n errorMsg: v.message,\n stack: v.stack,\n ...('cause' in v ? {cause: errorOrObject(v.cause)} : null),\n };\n}\n\nfunction stringifyContext(context: Context | undefined): unknown[] {\n const args = [];\n for (const [k, v] of Object.entries(context ?? {})) {\n const arg = v === undefined ? k : `${k}=${v}`;\n args.push(arg);\n }\n return args;\n}\n\nfunction stringifyValue(v: unknown) {\n if (typeof v === 'string') {\n return v;\n }\n if (v instanceof Error) {\n return stringify(toErrorLogObject(v));\n }\n return stringify(v);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"logging.js","names":[],"sources":["../../../../shared/src/logging.ts"],"sourcesContent":["/* oxlint-disable no-console */\nimport {\n type Context,\n LogContext,\n type LogLevel,\n type LogSink,\n} from '@rocicorp/logger';\nimport {pid} from 'node:process';\nimport {styleText} from 'node:util';\nimport {stringify} from './bigint-json.ts';\n\nexport type LogConfig = {\n level: LogLevel;\n format: 'text' | 'json';\n};\n\nfunction style(color: 'gray' | 'yellow' | 'red', args: unknown[]) {\n return styleText(color, args.join(' '));\n}\n\nconst COLOR_DEBUG = 'gray';\nconst COLOR_WARN = 'yellow';\nconst COLOR_ERROR = 'red';\n\n/**\n * Returns an object for writing colorized output to a provided console.\n * Note this should only be used when console is a TTY (i.e., Node).\n */\nexport const colorConsole = {\n log: (...args: unknown[]) => {\n console.log(...args);\n },\n debug: (...args: unknown[]) => {\n console.debug(style(COLOR_DEBUG, args));\n },\n info: (...args: unknown[]) => {\n console.info(...args);\n },\n warn: (...args: unknown[]) => {\n console.warn(style(COLOR_WARN, args));\n },\n error: (...args: unknown[]) => {\n console.error(style(COLOR_ERROR, args));\n },\n};\n\nexport const consoleSink: LogSink = {\n log(level, context, ...args) {\n colorConsole[level](\n toLocalIsoString(),\n stringifyContext(context),\n ...args.map(stringifyValue),\n );\n },\n};\n\nfunction toLocalIsoString(date = new Date()) {\n const tzo = -date.getTimezoneOffset();\n const sign = tzo >= 0 ? '+' : '-';\n const pad = (n: number, len = 2) => String(Math.abs(n)).padStart(len, '0');\n\n return (\n date.getFullYear() +\n '-' +\n pad(date.getMonth() + 1) +\n '-' +\n pad(date.getDate()) +\n 'T' +\n pad(date.getHours()) +\n ':' +\n pad(date.getMinutes()) +\n ':' +\n pad(date.getSeconds()) +\n '.' +\n pad(date.getMilliseconds(), 3) +\n sign +\n pad(tzo / 60) +\n ':' +\n pad(tzo % 60)\n );\n}\n\nexport function getLogSink(config: LogConfig): LogSink {\n return config.format === 'json' ? consoleJsonLogSink : consoleSink;\n}\n\nexport function createLogContext(\n {log}: {log: LogConfig},\n context = {},\n sink = getLogSink(log),\n): LogContext {\n const ctx = {pid, ...context};\n const lc = new LogContext(log.level, ctx, sink);\n // Emit a blank line to absorb random ANSI control code garbage that\n // for some reason gets prepended to the first log line in CloudWatch.\n lc.info?.('');\n return lc;\n}\n\nconst consoleJsonLogSink: LogSink = {\n log(level: LogLevel, context: Context | undefined, ...args: unknown[]): void {\n // If the last arg is an object or an Error, combine those fields into the message.\n const lastObj = errorOrObject(args.at(-1));\n if (lastObj) {\n args.pop();\n }\n const message = args.length\n ? {\n message: args.map(stringifyValue).join(' '),\n }\n : undefined;\n\n console[level](\n stringify({\n level: level.toUpperCase(),\n ...context,\n ...lastObj,\n ...message,\n }),\n );\n },\n};\n\nexport function errorOrObject(v: unknown): object | undefined {\n if (v instanceof Error) {\n return toErrorLogObject(v);\n }\n if (v && typeof v === 'object') {\n return v;\n }\n return undefined;\n}\n\nfunction toErrorLogObject(v: Error) {\n return {\n ...v, // some properties of Error subclasses may be enumerable\n name: v.name,\n errorMsg: v.message,\n stack: v.stack,\n ...('cause' in v ? {cause: errorOrObject(v.cause)} : null),\n };\n}\n\nfunction stringifyContext(context: Context | undefined): unknown[] {\n const args = [];\n for (const [k, v] of Object.entries(context ?? {})) {\n const arg = v === undefined ? k : `${k}=${v}`;\n args.push(arg);\n }\n return args;\n}\n\nfunction stringifyValue(v: unknown) {\n if (typeof v === 'string') {\n return v;\n }\n if (v instanceof Error) {\n return stringify(toErrorLogObject(v));\n }\n return stringify(v);\n}\n"],"mappings":"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"}
@@ -89,7 +89,7 @@ function parseOptionsAdvanced(appOptions, opts = {}) {
89
89
  });
90
90
  const spec = [(required ? "{italic required}" : defaultValue !== void 0 ? `default: ${JSON.stringify(defaultValue)}` : "optional") + "\n"];
91
91
  if (desc) spec.push(...desc);
92
- const typeLabel = [literals.size ? String([...literals].map((l) => `{underline ${l}}`)) : multiple ? `{underline ${terminalType}[]}` : `{underline ${terminalType}}`, ` ${env} env`];
92
+ const typeLabel = [literals.size ? String(Array.from(literals, (l) => `{underline ${l}}`)) : multiple ? `{underline ${terminalType}[]}` : `{underline ${terminalType}}`, ` ${env} env`];
93
93
  const opt = {
94
94
  name: flag,
95
95
  alias,
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","names":[],"sources":["../../../../shared/src/options.ts"],"sourcesContent":["import type {OptionalLogger} from '@rocicorp/logger';\nimport {template} from 'chalk-template';\nimport type {OptionDefinition} from 'command-line-args';\nimport commandLineArgs from 'command-line-args';\nimport commandLineUsage, {type Section} from 'command-line-usage';\nimport {createDefu} from 'defu';\nimport {toKebabCase, toSnakeCase} from 'kasi';\nimport {stripVTControlCharacters as stripAnsi} from 'node:util';\nimport {assert} from './asserts.ts';\nimport {must} from './must.ts';\nimport type {\n Config,\n Group,\n Option,\n Options,\n WrappedOptionType,\n} from './options-types.ts';\nimport * as v from './valita.ts';\n\nexport type {Config, Group, Option, Options, WrappedOptionType};\n\ntype Primitive = number | string | boolean;\ntype Value = Primitive | Array<Primitive>;\n\ntype RequiredOptionType =\n | v.Type<string>\n | v.Type<number>\n | v.Type<boolean>\n | v.Type<string[]>\n | v.Type<number[]>\n | v.Type<boolean[]>;\n\ntype OptionalOptionType =\n | v.Optional<string>\n | v.Optional<number>\n | v.Optional<boolean>\n | v.Optional<string[]>\n | v.Optional<number[]>\n | v.Optional<boolean[]>;\n\ntype OptionType = RequiredOptionType | OptionalOptionType;\n\n/**\n * Creates a defu instance that overrides arrays instead of merging them.\n */\nconst defu = createDefu((obj, key, value) => {\n if (!Array.isArray(value)) return;\n\n obj[key] = value;\n return true;\n});\n\n/**\n * Converts an Options instance into its corresponding {@link Config} schema.\n */\nfunction configSchema<T extends Options>(\n options: T,\n envNamePrefix: string,\n): v.Type<Config<T>> {\n function makeObjectType(options: Options | Group, group?: string) {\n return v.object(\n Object.fromEntries(\n Object.entries(options).map(\n ([name, value]): [string, OptionType | v.Type] => {\n const addErrorMessage = (t: OptionType) => {\n const {required} = getRequiredOrDefault(t);\n if (required) {\n // Adds an error message for required options that includes the\n // actual name of the option.\n const optionName = toSnakeCase(\n `${envNamePrefix}${group ? group + '_' : ''}${name}`,\n ).toUpperCase();\n return (t as v.Type<string>)\n .optional()\n .assert(\n val => val !== undefined,\n `Missing required option ${optionName}`,\n );\n }\n return t;\n };\n // OptionType\n if (v.instanceOfAbstractType(value)) {\n return [name, addErrorMessage(value)];\n }\n // WrappedOptionType\n const {type} = value;\n if (v.instanceOfAbstractType(type)) {\n return [name, addErrorMessage(type)];\n }\n // OptionGroup\n return [name, makeObjectType(value as Group, name)];\n },\n ),\n ),\n );\n }\n return makeObjectType(options) as v.Type<Config<T>>;\n}\n\n/**\n * Converts an Options instance into an \"env schema\", which is an object with\n * ENV names as its keys, mapped to optional or required string values\n * (corresponding to the optionality of the corresponding options).\n *\n * This is used as a format for encoding options for a multi-tenant version\n * of an app, with an envSchema for each tenant.\n */\nexport function envSchema<T extends Options>(options: T, envNamePrefix = '') {\n const fields: [string, v.Type<string> | v.Optional<string>][] = [];\n\n function addField(name: string, type: OptionType, group?: string) {\n const flag = group ? `${group}_${name}` : name;\n const env = toSnakeCase(`${envNamePrefix}${flag}`).toUpperCase();\n\n const {required} = getRequiredOrDefault(type);\n fields.push([env, required ? v.string() : v.string().optional()]);\n }\n\n function addFields(o: Options | Group, group?: string) {\n Object.entries(o).forEach(([name, value]) => {\n // OptionType\n if (v.instanceOfAbstractType(value)) {\n addField(name, value, group);\n return;\n }\n // WrappedOptionType\n const {type} = value;\n if (v.instanceOfAbstractType(type)) {\n addField(name, type, group);\n return;\n }\n // OptionGroup\n addFields(value as Group, name);\n });\n }\n\n addFields(options);\n\n return v.object(Object.fromEntries(fields));\n}\n\n// type TerminalType is not exported from badrap/valita\ntype TerminalType = Parameters<\n Parameters<v.Type<unknown>['toTerminals']>[0]\n>[0];\n\nfunction getRequiredOrDefault(type: OptionType) {\n const defaultResult = v.testOptional<Value>(undefined, type);\n return {\n required: !defaultResult.ok,\n defaultValue: defaultResult.ok ? defaultResult.value : undefined,\n };\n}\n\nexport type ParseOptions = {\n /** Defaults to process.argv.slice(2) */\n argv?: string[];\n\n envNamePrefix?: string;\n\n description?: {header: string; content: string}[];\n\n /** Defaults to `false` */\n allowUnknown?: boolean;\n\n /** Defaults to `false` */\n allowPartial?: boolean;\n\n /** Defaults to `process.env`. */\n env?: NodeJS.ProcessEnv;\n\n /** Defaults to `true`. */\n emitDeprecationWarnings?: boolean;\n\n /** Defaults to `true`. When false, excludes default values from both config and env return values. */\n includeDefaults?: boolean;\n\n /** Defaults to `console` */\n logger?: OptionalLogger;\n\n /** Defaults to `process.exit` */\n exit?: (code?: number | string | null) => never;\n};\n\nexport function parseOptions<T extends Options>(\n appOptions: T,\n opts: ParseOptions = {},\n): Config<T> {\n return parseOptionsAdvanced(appOptions, opts).config;\n}\n\nexport function parseOptionsAdvanced<T extends Options>(\n appOptions: T,\n opts: ParseOptions = {},\n): {config: Config<T>; env: Record<string, string>; unknown?: string[]} {\n const {\n argv = process.argv.slice(2),\n envNamePrefix = '',\n description = [],\n allowUnknown = false,\n allowPartial = false,\n env: processEnv = process.env,\n emitDeprecationWarnings = true,\n includeDefaults = true,\n logger = console,\n exit = process.exit,\n } = opts;\n // The main logic for converting a valita Type spec to an Option (i.e. flag) spec.\n function addOption(field: string, option: WrappedOptionType, group?: string) {\n const {type, desc = [], deprecated, alias, hidden} = option;\n\n // The group name is prepended to the flag name.\n const flag = group ? toKebabCase(`${group}-${field}`) : toKebabCase(field);\n\n const {required, defaultValue} = getRequiredOrDefault(type);\n let multiple = type.name === 'array';\n const literals = new Set<string>();\n const terminalTypes = new Set<string>();\n\n type.toTerminals(getTerminalTypes);\n\n function getTerminalTypes(t: TerminalType) {\n switch (t.name) {\n case 'undefined':\n case 'optional':\n break;\n case 'array': {\n multiple = true;\n t.prefix.forEach(t => t.toTerminals(getTerminalTypes));\n t.rest?.toTerminals(getTerminalTypes);\n t.suffix.forEach(t => t.toTerminals(getTerminalTypes));\n break;\n }\n case 'literal':\n literals.add(String(t.value));\n terminalTypes.add(typeof t.value);\n break;\n default:\n terminalTypes.add(t.name);\n break;\n }\n }\n const env = toSnakeCase(`${envNamePrefix}${flag}`).toUpperCase();\n if (terminalTypes.size > 1) {\n throw new TypeError(`${env} has mixed types ${[...terminalTypes]}`);\n }\n assert(terminalTypes.size === 1, 'Expected exactly one terminal type');\n const terminalType = [...terminalTypes][0];\n\n if (processEnv[env]) {\n if (multiple) {\n // Technically not water-tight; assumes values for the string[] flag don't contain commas.\n envArgv.push(`--${flag}`, ...processEnv[env].split(','));\n } else {\n envArgv.push(`--${flag}`, processEnv[env]);\n }\n }\n names.set(flag, {field, env});\n\n const spec = [\n (required\n ? '{italic required}'\n : defaultValue !== undefined\n ? `default: ${JSON.stringify(defaultValue)}`\n : 'optional') + '\\n',\n ];\n if (desc) {\n spec.push(...desc);\n }\n\n const typeLabel = [\n literals.size\n ? String([...literals].map(l => `{underline ${l}}`))\n : multiple\n ? `{underline ${terminalType}[]}`\n : `{underline ${terminalType}}`,\n ` ${env} env`,\n ];\n\n const opt = {\n name: flag,\n alias,\n type: valueParser(\n env,\n terminalType,\n logger,\n emitDeprecationWarnings ? deprecated : undefined,\n ),\n multiple,\n group,\n description: spec.join('\\n') + '\\n',\n typeLabel: typeLabel.join('\\n') + '\\n',\n hidden: hidden === undefined ? deprecated !== undefined : hidden,\n };\n optsWithoutDefaults.push(opt);\n optsWithDefaults.push({...opt, defaultValue});\n }\n\n const names = new Map<string, {field: string; env: string}>();\n const optsWithDefaults: DescribedOptionDefinition[] = [];\n const optsWithoutDefaults: DescribedOptionDefinition[] = [];\n const envArgv: string[] = [];\n\n try {\n for (const [name, val] of Object.entries(appOptions)) {\n const {type} = val as {type: unknown};\n if (v.instanceOfAbstractType(val)) {\n addOption(name, {type: val});\n } else if (v.instanceOfAbstractType(type)) {\n addOption(name, val as WrappedOptionType);\n } else {\n const group = name;\n for (const [name, option] of Object.entries(val as Group)) {\n const wrapped = v.instanceOfAbstractType(option)\n ? {type: option}\n : option;\n addOption(name, wrapped, group);\n }\n }\n }\n\n const [defaults, env1, unknown] = parseArgs(optsWithDefaults, argv, names);\n const [fromEnv, env2] = parseArgs(optsWithoutDefaults, envArgv, names);\n const [withoutDefaults, env3] = parseArgs(optsWithoutDefaults, argv, names);\n\n switch (unknown?.[0]) {\n case undefined:\n break;\n case '--help':\n case '-h':\n showUsage(optsWithDefaults, description, logger);\n exit(0);\n break;\n default:\n if (!allowUnknown) {\n logger.error?.('Invalid arguments:', unknown);\n showUsage(optsWithDefaults, description, logger);\n exit(0);\n }\n break;\n }\n\n const parsedArgs = includeDefaults\n ? defu(withoutDefaults, fromEnv, defaults)\n : defu(withoutDefaults, fromEnv);\n const env = includeDefaults\n ? {...env1, ...env2, ...env3}\n : {...env2, ...env3};\n\n let schema = configSchema(appOptions, envNamePrefix);\n if (allowPartial || !includeDefaults) {\n // TODO: Type configSchema() to return a v.ObjectType<...>\n schema = v.deepPartial(schema as v.ObjectType) as v.Type<Config<T>>;\n }\n return {\n config: v.parse(parsedArgs, schema),\n env,\n ...(unknown ? {unknown} : {}),\n };\n } catch (e) {\n logger.error?.(String(e));\n showUsage(optsWithDefaults, description, logger);\n throw e;\n }\n}\n\nfunction valueParser(\n optionName: string,\n typeName: string,\n logger: OptionalLogger,\n deprecated: string[] | undefined,\n) {\n return (input: string) => {\n if (deprecated) {\n logger.warn?.(\n template(\n `\\n${optionName} is deprecated:\\n` + deprecated.join('\\n') + '\\n',\n ),\n );\n }\n switch (typeName) {\n case 'string':\n return input;\n case 'boolean':\n return parseBoolean(optionName, input);\n case 'number': {\n const val = Number(input);\n if (Number.isNaN(val)) {\n throw new TypeError(`Invalid input for ${optionName}: \"${input}\"`);\n }\n return val;\n }\n default:\n // Should be impossible given the constraints of `Option`\n throw new TypeError(\n `${optionName} option has unsupported type ${typeName}`,\n );\n }\n };\n}\n\nfunction parseArgs(\n optionDefs: DescribedOptionDefinition[],\n argv: string[],\n names: Map<string, {field: string; env: string}>,\n) {\n function normalizeFlagValue(value: unknown) {\n // A --flag without value is parsed by commandLineArgs() to `null`,\n // but this is a common convention to set a boolean flag to true.\n return value === null ? true : value;\n }\n\n const {\n _all,\n _none: ungrouped,\n _unknown: unknown,\n ...config\n } = commandLineArgs(optionDefs, {\n argv,\n partial: true,\n });\n\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n const result: Record<string, any> = {};\n const envObj: Record<string, string> = {};\n\n function addFlag(flagName: string, value: unknown, group?: string) {\n const {field, env} = must(names.get(flagName));\n const normalized = normalizeFlagValue(value);\n if (group) {\n result[group][field] = normalized;\n } else {\n result[field] = normalized;\n }\n envObj[env] = String(normalized);\n }\n\n for (const [flagName, value] of Object.entries(ungrouped ?? {})) {\n addFlag(flagName, value);\n }\n\n // Then handle (potentially) grouped flags\n for (const [name, value] of Object.entries(config)) {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n addFlag(name, value); // Flag, not a group\n } else {\n const group = name;\n result[group] = {};\n for (const [flagName, flagValue] of Object.entries(value)) {\n addFlag(flagName, flagValue, group);\n }\n }\n }\n\n return [result, envObj, unknown] as const;\n}\n\nexport function flagToEnv(prefix: string, flag: string): string {\n return toSnakeCase(prefix + flag).toUpperCase();\n}\n\nexport function parseBoolean(optionName: string, input: string) {\n const bool = input.toLowerCase();\n if (['true', '1'].includes(bool)) {\n return true;\n } else if (['false', '0'].includes(bool)) {\n return false;\n }\n throw new TypeError(`Invalid input for ${optionName}: \"${input}\"`);\n}\n\nfunction showUsage(\n optionList: DescribedOptionDefinition[],\n description: {header: string; content: string}[] = [],\n logger: OptionalLogger = console,\n) {\n const hide: string[] = [];\n let leftWidth = 35;\n let rightWidth = 70;\n optionList.forEach(({name, typeLabel, description, hidden}) => {\n if (hidden) {\n hide.push(name);\n }\n const text = template(`${name} ${typeLabel ?? ''}`);\n const lines = stripAnsi(text).split('\\n');\n for (const l of lines) {\n leftWidth = Math.max(leftWidth, l.length + 2);\n }\n const desc = stripAnsi(template(description ?? '')).split('\\n');\n for (const l of desc) {\n rightWidth = Math.max(rightWidth, l.length + 2);\n }\n });\n\n const sections: Section[] = [\n {\n optionList,\n reverseNameOrder: true, // Display --flag-name before -alias\n hide,\n tableOptions: {\n columns: [\n {name: 'option', width: leftWidth},\n {name: 'description', width: rightWidth},\n ],\n noTrim: true,\n },\n },\n ];\n\n if (description) {\n sections.unshift(...description);\n }\n\n logger.info?.(commandLineUsage(sections));\n}\n\ntype DescribedOptionDefinition = OptionDefinition & {\n // Additional fields recognized by command-line-usage\n description?: string;\n typeLabel?: string | undefined;\n hidden?: boolean | undefined;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"options.js","names":[],"sources":["../../../../shared/src/options.ts"],"sourcesContent":["import type {OptionalLogger} from '@rocicorp/logger';\nimport {template} from 'chalk-template';\nimport type {OptionDefinition} from 'command-line-args';\nimport commandLineArgs from 'command-line-args';\nimport commandLineUsage, {type Section} from 'command-line-usage';\nimport {createDefu} from 'defu';\nimport {toKebabCase, toSnakeCase} from 'kasi';\nimport {stripVTControlCharacters as stripAnsi} from 'node:util';\nimport {assert} from './asserts.ts';\nimport {must} from './must.ts';\nimport type {\n Config,\n Group,\n Option,\n Options,\n WrappedOptionType,\n} from './options-types.ts';\nimport * as v from './valita.ts';\n\nexport type {Config, Group, Option, Options, WrappedOptionType};\n\ntype Primitive = number | string | boolean;\ntype Value = Primitive | Array<Primitive>;\n\ntype RequiredOptionType =\n | v.Type<string>\n | v.Type<number>\n | v.Type<boolean>\n | v.Type<string[]>\n | v.Type<number[]>\n | v.Type<boolean[]>;\n\ntype OptionalOptionType =\n | v.Optional<string>\n | v.Optional<number>\n | v.Optional<boolean>\n | v.Optional<string[]>\n | v.Optional<number[]>\n | v.Optional<boolean[]>;\n\ntype OptionType = RequiredOptionType | OptionalOptionType;\n\n/**\n * Creates a defu instance that overrides arrays instead of merging them.\n */\nconst defu = createDefu((obj, key, value) => {\n if (!Array.isArray(value)) return;\n\n obj[key] = value;\n return true;\n});\n\n/**\n * Converts an Options instance into its corresponding {@link Config} schema.\n */\nfunction configSchema<T extends Options>(\n options: T,\n envNamePrefix: string,\n): v.Type<Config<T>> {\n function makeObjectType(options: Options | Group, group?: string) {\n return v.object(\n Object.fromEntries(\n Object.entries(options).map(\n ([name, value]): [string, OptionType | v.Type] => {\n const addErrorMessage = (t: OptionType) => {\n const {required} = getRequiredOrDefault(t);\n if (required) {\n // Adds an error message for required options that includes the\n // actual name of the option.\n const optionName = toSnakeCase(\n `${envNamePrefix}${group ? group + '_' : ''}${name}`,\n ).toUpperCase();\n return (t as v.Type<string>)\n .optional()\n .assert(\n val => val !== undefined,\n `Missing required option ${optionName}`,\n );\n }\n return t;\n };\n // OptionType\n if (v.instanceOfAbstractType(value)) {\n return [name, addErrorMessage(value)];\n }\n // WrappedOptionType\n const {type} = value;\n if (v.instanceOfAbstractType(type)) {\n return [name, addErrorMessage(type)];\n }\n // OptionGroup\n return [name, makeObjectType(value as Group, name)];\n },\n ),\n ),\n );\n }\n return makeObjectType(options) as v.Type<Config<T>>;\n}\n\n/**\n * Converts an Options instance into an \"env schema\", which is an object with\n * ENV names as its keys, mapped to optional or required string values\n * (corresponding to the optionality of the corresponding options).\n *\n * This is used as a format for encoding options for a multi-tenant version\n * of an app, with an envSchema for each tenant.\n */\nexport function envSchema<T extends Options>(options: T, envNamePrefix = '') {\n const fields: [string, v.Type<string> | v.Optional<string>][] = [];\n\n function addField(name: string, type: OptionType, group?: string) {\n const flag = group ? `${group}_${name}` : name;\n const env = toSnakeCase(`${envNamePrefix}${flag}`).toUpperCase();\n\n const {required} = getRequiredOrDefault(type);\n fields.push([env, required ? v.string() : v.string().optional()]);\n }\n\n function addFields(o: Options | Group, group?: string) {\n Object.entries(o).forEach(([name, value]) => {\n // OptionType\n if (v.instanceOfAbstractType(value)) {\n addField(name, value, group);\n return;\n }\n // WrappedOptionType\n const {type} = value;\n if (v.instanceOfAbstractType(type)) {\n addField(name, type, group);\n return;\n }\n // OptionGroup\n addFields(value as Group, name);\n });\n }\n\n addFields(options);\n\n return v.object(Object.fromEntries(fields));\n}\n\n// type TerminalType is not exported from badrap/valita\ntype TerminalType = Parameters<\n Parameters<v.Type<unknown>['toTerminals']>[0]\n>[0];\n\nfunction getRequiredOrDefault(type: OptionType) {\n const defaultResult = v.testOptional<Value>(undefined, type);\n return {\n required: !defaultResult.ok,\n defaultValue: defaultResult.ok ? defaultResult.value : undefined,\n };\n}\n\nexport type ParseOptions = {\n /** Defaults to process.argv.slice(2) */\n argv?: string[];\n\n envNamePrefix?: string;\n\n description?: {header: string; content: string}[];\n\n /** Defaults to `false` */\n allowUnknown?: boolean;\n\n /** Defaults to `false` */\n allowPartial?: boolean;\n\n /** Defaults to `process.env`. */\n env?: NodeJS.ProcessEnv;\n\n /** Defaults to `true`. */\n emitDeprecationWarnings?: boolean;\n\n /** Defaults to `true`. When false, excludes default values from both config and env return values. */\n includeDefaults?: boolean;\n\n /** Defaults to `console` */\n logger?: OptionalLogger;\n\n /** Defaults to `process.exit` */\n exit?: (code?: number | string | null) => never;\n};\n\nexport function parseOptions<T extends Options>(\n appOptions: T,\n opts: ParseOptions = {},\n): Config<T> {\n return parseOptionsAdvanced(appOptions, opts).config;\n}\n\nexport function parseOptionsAdvanced<T extends Options>(\n appOptions: T,\n opts: ParseOptions = {},\n): {config: Config<T>; env: Record<string, string>; unknown?: string[]} {\n const {\n argv = process.argv.slice(2),\n envNamePrefix = '',\n description = [],\n allowUnknown = false,\n allowPartial = false,\n env: processEnv = process.env,\n emitDeprecationWarnings = true,\n includeDefaults = true,\n logger = console,\n exit = process.exit,\n } = opts;\n // The main logic for converting a valita Type spec to an Option (i.e. flag) spec.\n function addOption(field: string, option: WrappedOptionType, group?: string) {\n const {type, desc = [], deprecated, alias, hidden} = option;\n\n // The group name is prepended to the flag name.\n const flag = group ? toKebabCase(`${group}-${field}`) : toKebabCase(field);\n\n const {required, defaultValue} = getRequiredOrDefault(type);\n let multiple = type.name === 'array';\n const literals = new Set<string>();\n const terminalTypes = new Set<string>();\n\n type.toTerminals(getTerminalTypes);\n\n function getTerminalTypes(t: TerminalType) {\n switch (t.name) {\n case 'undefined':\n case 'optional':\n break;\n case 'array': {\n multiple = true;\n t.prefix.forEach(t => t.toTerminals(getTerminalTypes));\n t.rest?.toTerminals(getTerminalTypes);\n t.suffix.forEach(t => t.toTerminals(getTerminalTypes));\n break;\n }\n case 'literal':\n literals.add(String(t.value));\n terminalTypes.add(typeof t.value);\n break;\n default:\n terminalTypes.add(t.name);\n break;\n }\n }\n const env = toSnakeCase(`${envNamePrefix}${flag}`).toUpperCase();\n if (terminalTypes.size > 1) {\n throw new TypeError(`${env} has mixed types ${[...terminalTypes]}`);\n }\n assert(terminalTypes.size === 1, 'Expected exactly one terminal type');\n const terminalType = [...terminalTypes][0];\n\n if (processEnv[env]) {\n if (multiple) {\n // Technically not water-tight; assumes values for the string[] flag don't contain commas.\n envArgv.push(`--${flag}`, ...processEnv[env].split(','));\n } else {\n envArgv.push(`--${flag}`, processEnv[env]);\n }\n }\n names.set(flag, {field, env});\n\n const spec = [\n (required\n ? '{italic required}'\n : defaultValue !== undefined\n ? `default: ${JSON.stringify(defaultValue)}`\n : 'optional') + '\\n',\n ];\n if (desc) {\n spec.push(...desc);\n }\n\n const typeLabel = [\n literals.size\n ? String(Array.from(literals, l => `{underline ${l}}`))\n : multiple\n ? `{underline ${terminalType}[]}`\n : `{underline ${terminalType}}`,\n ` ${env} env`,\n ];\n\n const opt = {\n name: flag,\n alias,\n type: valueParser(\n env,\n terminalType,\n logger,\n emitDeprecationWarnings ? deprecated : undefined,\n ),\n multiple,\n group,\n description: spec.join('\\n') + '\\n',\n typeLabel: typeLabel.join('\\n') + '\\n',\n hidden: hidden === undefined ? deprecated !== undefined : hidden,\n };\n optsWithoutDefaults.push(opt);\n optsWithDefaults.push({...opt, defaultValue});\n }\n\n const names = new Map<string, {field: string; env: string}>();\n const optsWithDefaults: DescribedOptionDefinition[] = [];\n const optsWithoutDefaults: DescribedOptionDefinition[] = [];\n const envArgv: string[] = [];\n\n try {\n for (const [name, val] of Object.entries(appOptions)) {\n const {type} = val as {type: unknown};\n if (v.instanceOfAbstractType(val)) {\n addOption(name, {type: val});\n } else if (v.instanceOfAbstractType(type)) {\n addOption(name, val as WrappedOptionType);\n } else {\n const group = name;\n for (const [name, option] of Object.entries(val as Group)) {\n const wrapped = v.instanceOfAbstractType(option)\n ? {type: option}\n : option;\n addOption(name, wrapped, group);\n }\n }\n }\n\n const [defaults, env1, unknown] = parseArgs(optsWithDefaults, argv, names);\n const [fromEnv, env2] = parseArgs(optsWithoutDefaults, envArgv, names);\n const [withoutDefaults, env3] = parseArgs(optsWithoutDefaults, argv, names);\n\n switch (unknown?.[0]) {\n case undefined:\n break;\n case '--help':\n case '-h':\n showUsage(optsWithDefaults, description, logger);\n exit(0);\n break;\n default:\n if (!allowUnknown) {\n logger.error?.('Invalid arguments:', unknown);\n showUsage(optsWithDefaults, description, logger);\n exit(0);\n }\n break;\n }\n\n const parsedArgs = includeDefaults\n ? defu(withoutDefaults, fromEnv, defaults)\n : defu(withoutDefaults, fromEnv);\n const env = includeDefaults\n ? {...env1, ...env2, ...env3}\n : {...env2, ...env3};\n\n let schema = configSchema(appOptions, envNamePrefix);\n if (allowPartial || !includeDefaults) {\n // TODO: Type configSchema() to return a v.ObjectType<...>\n schema = v.deepPartial(schema as v.ObjectType) as v.Type<Config<T>>;\n }\n return {\n config: v.parse(parsedArgs, schema),\n env,\n ...(unknown ? {unknown} : {}),\n };\n } catch (e) {\n logger.error?.(String(e));\n showUsage(optsWithDefaults, description, logger);\n throw e;\n }\n}\n\nfunction valueParser(\n optionName: string,\n typeName: string,\n logger: OptionalLogger,\n deprecated: string[] | undefined,\n) {\n return (input: string) => {\n if (deprecated) {\n logger.warn?.(\n template(\n `\\n${optionName} is deprecated:\\n` + deprecated.join('\\n') + '\\n',\n ),\n );\n }\n switch (typeName) {\n case 'string':\n return input;\n case 'boolean':\n return parseBoolean(optionName, input);\n case 'number': {\n const val = Number(input);\n if (Number.isNaN(val)) {\n throw new TypeError(`Invalid input for ${optionName}: \"${input}\"`);\n }\n return val;\n }\n default:\n // Should be impossible given the constraints of `Option`\n throw new TypeError(\n `${optionName} option has unsupported type ${typeName}`,\n );\n }\n };\n}\n\nfunction parseArgs(\n optionDefs: DescribedOptionDefinition[],\n argv: string[],\n names: Map<string, {field: string; env: string}>,\n) {\n function normalizeFlagValue(value: unknown) {\n // A --flag without value is parsed by commandLineArgs() to `null`,\n // but this is a common convention to set a boolean flag to true.\n return value === null ? true : value;\n }\n\n const {\n _all,\n _none: ungrouped,\n _unknown: unknown,\n ...config\n } = commandLineArgs(optionDefs, {\n argv,\n partial: true,\n });\n\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n const result: Record<string, any> = {};\n const envObj: Record<string, string> = {};\n\n function addFlag(flagName: string, value: unknown, group?: string) {\n const {field, env} = must(names.get(flagName));\n const normalized = normalizeFlagValue(value);\n if (group) {\n result[group][field] = normalized;\n } else {\n result[field] = normalized;\n }\n envObj[env] = String(normalized);\n }\n\n for (const [flagName, value] of Object.entries(ungrouped ?? {})) {\n addFlag(flagName, value);\n }\n\n // Then handle (potentially) grouped flags\n for (const [name, value] of Object.entries(config)) {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n addFlag(name, value); // Flag, not a group\n } else {\n const group = name;\n result[group] = {};\n for (const [flagName, flagValue] of Object.entries(value)) {\n addFlag(flagName, flagValue, group);\n }\n }\n }\n\n return [result, envObj, unknown] as const;\n}\n\nexport function flagToEnv(prefix: string, flag: string): string {\n return toSnakeCase(prefix + flag).toUpperCase();\n}\n\nexport function parseBoolean(optionName: string, input: string) {\n const bool = input.toLowerCase();\n if (['true', '1'].includes(bool)) {\n return true;\n } else if (['false', '0'].includes(bool)) {\n return false;\n }\n throw new TypeError(`Invalid input for ${optionName}: \"${input}\"`);\n}\n\nfunction showUsage(\n optionList: DescribedOptionDefinition[],\n description: {header: string; content: string}[] = [],\n logger: OptionalLogger = console,\n) {\n const hide: string[] = [];\n let leftWidth = 35;\n let rightWidth = 70;\n optionList.forEach(({name, typeLabel, description, hidden}) => {\n if (hidden) {\n hide.push(name);\n }\n const text = template(`${name} ${typeLabel ?? ''}`);\n const lines = stripAnsi(text).split('\\n');\n for (const l of lines) {\n leftWidth = Math.max(leftWidth, l.length + 2);\n }\n const desc = stripAnsi(template(description ?? '')).split('\\n');\n for (const l of desc) {\n rightWidth = Math.max(rightWidth, l.length + 2);\n }\n });\n\n const sections: Section[] = [\n {\n optionList,\n reverseNameOrder: true, // Display --flag-name before -alias\n hide,\n tableOptions: {\n columns: [\n {name: 'option', width: leftWidth},\n {name: 'description', width: rightWidth},\n ],\n noTrim: true,\n },\n },\n ];\n\n if (description) {\n sections.unshift(...description);\n }\n\n logger.info?.(commandLineUsage(sections));\n}\n\ntype DescribedOptionDefinition = OptionDefinition & {\n // Additional fields recognized by command-line-usage\n description?: string;\n typeLabel?: string | undefined;\n hidden?: boolean | undefined;\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tdigest-schema.d.ts","sourceRoot":"","sources":["../../../../shared/src/tdigest-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AAEjC;;;GAGG;AACH,eAAO,MAAM,aAAa,2DAAoD,CAAC;AAE/E,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC"}
1
+ {"version":3,"file":"tdigest-schema.d.ts","sourceRoot":"","sources":["../../../../shared/src/tdigest-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AAEjC;;;GAGG;AAEH,eAAO,MAAM,aAAa,2DAAoD,CAAC;AAE/E,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tdigest-schema.js","names":[],"sources":["../../../../shared/src/tdigest-schema.ts"],"sourcesContent":["import * as v from './valita.ts';\n\n/**\n * Valita schema for TDigest JSON representation.\n * Matches the structure returned by TDigest.toJSON().\n */\nexport const tdigestSchema = v.tuple([v.number()]).concat(v.array(v.number()));\n\nexport type TDigestJSON = v.Infer<typeof tdigestSchema>;\n"],"mappings":";;;;;;AAMA,IAAa,gBAAgB,eAAE,MAAM,CAAC,eAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,eAAE,MAAM,eAAE,QAAQ,CAAC,CAAC"}
1
+ {"version":3,"file":"tdigest-schema.js","names":[],"sources":["../../../../shared/src/tdigest-schema.ts"],"sourcesContent":["import * as v from './valita.ts';\n\n/**\n * Valita schema for TDigest JSON representation.\n * Matches the structure returned by TDigest.toJSON().\n */\n// oxlint-disable-next-line e18e/prefer-spread-syntax\nexport const tdigestSchema = v.tuple([v.number()]).concat(v.array(v.number()));\n\nexport type TDigestJSON = v.Infer<typeof tdigestSchema>;\n"],"mappings":";;;;;;AAOA,IAAa,gBAAgB,eAAE,MAAM,CAAC,eAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,eAAE,MAAM,eAAE,QAAQ,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tdigest.d.ts","sourceRoot":"","sources":["../../../../shared/src/tdigest.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,QAAQ,EAAoB,KAAK,YAAY,EAAC,MAAM,eAAe,CAAC;AAC5E,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,qBAAqB,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CACrC;AAID,qBAAa,OAAO;;IAClB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAYjB,WAAW,GAAE,MAAa;IAOtC;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,OAAO;IAWrD,KAAK,IAAI,IAAI;IAUb,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU;IAIpC,0DAA0D;IAC1D,eAAe,CAAC,YAAY,EAAE,YAAY;IAM1C;;;OAGG;IACH,WAAW,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI;IAqB9B;;;;QAII;IACJ,KAAK,CAAC,EAAE,EAAE,OAAO;IA4CjB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,GAAE,YAAiB,GAAG,YAAY;IAK9C,KAAK,IAAI,MAAM;IAQf;;;OAGG;IACH,MAAM,IAAI,WAAW;IAqCrB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;IA6C3B;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;CAyFvB;AAID,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoB3D"}
1
+ {"version":3,"file":"tdigest.d.ts","sourceRoot":"","sources":["../../../../shared/src/tdigest.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,QAAQ,EAAoB,KAAK,YAAY,EAAC,MAAM,eAAe,CAAC;AAC5E,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,qBAAqB,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CACrC;AAID,qBAAa,OAAO;;IAClB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAYjB,WAAW,GAAE,MAAa;IAOtC;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,OAAO;IAWrD,KAAK,IAAI,IAAI;IAUb,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU;IAIpC,0DAA0D;IAC1D,eAAe,CAAC,YAAY,EAAE,YAAY;IAM1C;;;OAGG;IACH,WAAW,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI;IAqB9B;;;;QAII;IACJ,KAAK,CAAC,EAAE,EAAE,OAAO;IA2CjB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,GAAE,YAAiB,GAAG,YAAY;IAK9C,KAAK,IAAI,MAAM;IAQf;;;OAGG;IACH,MAAM,IAAI,WAAW;IAqCrB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;IAyC3B;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;CA2FvB;AAID,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoB3D"}
@@ -78,7 +78,7 @@ var TDigest = class TDigest {
78
78
  const projected = soFar + centroid.weight;
79
79
  if (projected <= limit) {
80
80
  soFar = projected;
81
- this.#processed[this.#processed.length - 1].add(centroid);
81
+ this.#processed.at(-1).add(centroid);
82
82
  } else {
83
83
  const k1 = this.#integratedLocation(soFar / this.#processedWeight);
84
84
  limit = this.#processedWeight * this.#integratedQ(k1 + 1);
@@ -87,7 +87,7 @@ var TDigest = class TDigest {
87
87
  }
88
88
  }
89
89
  this.#min = Math.min(this.#min, this.#processed[0].mean);
90
- this.#max = Math.max(this.#max, this.#processed[this.#processed.length - 1].mean);
90
+ this.#max = Math.max(this.#max, this.#processed.at(-1).mean);
91
91
  this.#unprocessed.length = 0;
92
92
  }
93
93
  }
@@ -100,7 +100,7 @@ var TDigest = class TDigest {
100
100
  */
101
101
  centroids(cl = []) {
102
102
  this.#process();
103
- return cl.concat(this.#processed);
103
+ return [...cl, ...this.#processed];
104
104
  }
105
105
  count() {
106
106
  this.#process();
@@ -117,7 +117,7 @@ var TDigest = class TDigest {
117
117
  return data;
118
118
  }
119
119
  #updateCumulative() {
120
- if (this.#cumulative.length > 0 && this.#cumulative[this.#cumulative.length - 1] === this.#processedWeight) return;
120
+ if (this.#cumulative.length > 0 && this.#cumulative.at(-1) === this.#processedWeight) return;
121
121
  const n = this.#processed.length + 1;
122
122
  if (this.#cumulative.length > n) this.#cumulative.length = n;
123
123
  let prev = 0;
@@ -143,7 +143,7 @@ var TDigest = class TDigest {
143
143
  }
144
144
  const z1 = index - this.#processedWeight - this.#processed[lower - 1].weight / 2;
145
145
  const z2 = this.#processed[lower - 1].weight / 2 - z1;
146
- return weightedAverage(this.#processed[this.#processed.length - 1].mean, z1, this.#max, z2);
146
+ return weightedAverage(this.#processed.at(-1).mean, z1, this.#max, z2);
147
147
  }
148
148
  /**
149
149
  * CDF returns the cumulative distribution function for a given value x.
@@ -168,9 +168,9 @@ var TDigest = class TDigest {
168
168
  if (m0 - this.#min > 0) return (x - this.#min) / (m0 - this.#min) * this.#processed[0].weight / this.#processedWeight / 2;
169
169
  return 0;
170
170
  }
171
- const mn = this.#processed[this.#processed.length - 1].mean;
171
+ const mn = this.#processed.at(-1).mean;
172
172
  if (x >= mn) {
173
- if (this.#max - mn > 0) return 1 - (this.#max - x) / (this.#max - mn) * this.#processed[this.#processed.length - 1].weight / this.#processedWeight / 2;
173
+ if (this.#max - mn > 0) return 1 - (this.#max - x) / (this.#max - mn) * this.#processed.at(-1).weight / this.#processedWeight / 2;
174
174
  return 1;
175
175
  }
176
176
  const upper = binarySearch(this.#processed.length, (i) => x - this.#processed[i].mean || 1);
@@ -1 +1 @@
1
- {"version":3,"file":"tdigest.js","names":["#maxProcessed","#maxUnprocessed","#processed","#unprocessed","#cumulative","#processedWeight","#unprocessedWeight","#min","#max","#process","#integratedQ","#integratedLocation","#updateCumulative"],"sources":["../../../../shared/src/tdigest.ts"],"sourcesContent":["// Apache License 2.0\n// https://github.com/influxdata/tdigest\n\nimport {binarySearch} from './binary-search.ts';\nimport {Centroid, sortCentroidList, type CentroidList} from './centroid.ts';\nimport type {TDigestJSON} from './tdigest-schema.ts';\n\nexport interface ReadonlyTDigest {\n readonly count: () => number;\n readonly quantile: (q: number) => number;\n readonly cdf: (x: number) => number;\n}\n\n// TDigest is a data structure for accurate on-line accumulation of\n// rank-based statistics such as quantiles and trimmed means.\nexport class TDigest {\n readonly compression: number;\n\n #maxProcessed: number;\n #maxUnprocessed: number;\n #processed!: CentroidList;\n #unprocessed!: CentroidList;\n #cumulative!: number[];\n #processedWeight!: number;\n #unprocessedWeight!: number;\n #min!: number;\n #max!: number;\n\n constructor(compression: number = 1000) {\n this.compression = compression;\n this.#maxProcessed = processedSize(0, this.compression);\n this.#maxUnprocessed = unprocessedSize(0, this.compression);\n this.reset();\n }\n\n /**\n * fromJSON creates a TDigest from a JSON-serializable representation.\n * The data should be an object with compression and centroids array.\n */\n static fromJSON(data: Readonly<TDigestJSON>): TDigest {\n const digest = new TDigest(data[0]);\n if (data.length % 2 !== 1) {\n throw new Error('Invalid centroids array');\n }\n for (let i = 1; i < data.length; i += 2) {\n digest.add(data[i], data[i + 1]);\n }\n return digest;\n }\n\n reset(): void {\n this.#processed = [];\n this.#unprocessed = [];\n this.#cumulative = [];\n this.#processedWeight = 0;\n this.#unprocessedWeight = 0;\n this.#min = Number.MAX_VALUE;\n this.#max = -Number.MAX_VALUE;\n }\n\n add(mean: number, weight: number = 1) {\n this.addCentroid(new Centroid(mean, weight));\n }\n\n /** AddCentroidList can quickly add multiple centroids. */\n addCentroidList(centroidList: CentroidList) {\n for (const c of centroidList) {\n this.addCentroid(c);\n }\n }\n\n /**\n * AddCentroid adds a single centroid.\n * Weights which are not a number or are <= 0 are ignored, as are NaN means.\n */\n addCentroid(c: Centroid): void {\n if (\n Number.isNaN(c.mean) ||\n c.weight <= 0 ||\n Number.isNaN(c.weight) ||\n !Number.isFinite(c.weight)\n ) {\n return;\n }\n\n this.#unprocessed.push(new Centroid(c.mean, c.weight));\n this.#unprocessedWeight += c.weight;\n\n if (\n this.#processed.length > this.#maxProcessed ||\n this.#unprocessed.length > this.#maxUnprocessed\n ) {\n this.#process();\n }\n }\n\n /**\n * Merges the supplied digest into this digest. Functionally equivalent to\n * calling t.AddCentroidList(t2.Centroids(nil)), but avoids making an extra\n * copy of the CentroidList.\n **/\n merge(t2: TDigest) {\n t2.#process();\n this.addCentroidList(t2.#processed);\n }\n\n #process() {\n if (\n this.#unprocessed.length > 0 ||\n this.#processed.length > this.#maxProcessed\n ) {\n // Append all processed centroids to the unprocessed list and sort\n this.#unprocessed.push(...this.#processed);\n sortCentroidList(this.#unprocessed);\n\n // Reset processed list with first centroid\n this.#processed.length = 0;\n this.#processed.push(this.#unprocessed[0]);\n\n this.#processedWeight += this.#unprocessedWeight;\n this.#unprocessedWeight = 0;\n let soFar = this.#unprocessed[0].weight;\n let limit = this.#processedWeight * this.#integratedQ(1);\n for (let i = 1; i < this.#unprocessed.length; i++) {\n const centroid = this.#unprocessed[i];\n const projected = soFar + centroid.weight;\n if (projected <= limit) {\n soFar = projected;\n this.#processed[this.#processed.length - 1].add(centroid);\n } else {\n const k1 = this.#integratedLocation(soFar / this.#processedWeight);\n limit = this.#processedWeight * this.#integratedQ(k1 + 1);\n soFar += centroid.weight;\n this.#processed.push(centroid);\n }\n }\n this.#min = Math.min(this.#min, this.#processed[0].mean);\n this.#max = Math.max(\n this.#max,\n this.#processed[this.#processed.length - 1].mean,\n );\n this.#unprocessed.length = 0;\n }\n }\n\n /**\n * Centroids returns a copy of processed centroids.\n * Useful when aggregating multiple t-digests.\n *\n * Centroids are appended to the passed CentroidList; if you're re-using a\n * buffer, be sure to pass cl[:0].\n */\n centroids(cl: CentroidList = []): CentroidList {\n this.#process();\n return cl.concat(this.#processed);\n }\n\n count(): number {\n this.#process();\n\n // this.process always updates this.processedWeight to the total count of all\n // centroids, so we don't need to re-count here.\n return this.#processedWeight;\n }\n\n /**\n * toJSON returns a JSON-serializable representation of the digest.\n * This processes the digest and returns an object with compression and centroid data.\n */\n toJSON(): TDigestJSON {\n this.#process();\n const data: TDigestJSON = [this.compression];\n for (const centroid of this.#processed) {\n data.push(centroid.mean, centroid.weight);\n }\n return data;\n }\n\n #updateCumulative() {\n // Weight can only increase, so the final cumulative value will always be\n // either equal to, or less than, the total weight. If they are the same,\n // then nothing has changed since the last update.\n if (\n this.#cumulative.length > 0 &&\n this.#cumulative[this.#cumulative.length - 1] === this.#processedWeight\n ) {\n return;\n }\n const n = this.#processed.length + 1;\n if (this.#cumulative.length > n) {\n this.#cumulative.length = n;\n }\n\n let prev = 0;\n for (let i = 0; i < this.#processed.length; i++) {\n const centroid = this.#processed[i];\n const cur = centroid.weight;\n this.#cumulative[i] = prev + cur / 2;\n prev += cur;\n }\n this.#cumulative[this.#processed.length] = prev;\n }\n\n // Quantile returns the (approximate) quantile of\n // the distribution. Accepted values for q are between 0 and 1.\n // Returns NaN if Count is zero or bad inputs.\n quantile(q: number): number {\n this.#process();\n this.#updateCumulative();\n if (q < 0 || q > 1 || this.#processed.length === 0) {\n return NaN;\n }\n if (this.#processed.length === 1) {\n return this.#processed[0].mean;\n }\n const index = q * this.#processedWeight;\n if (index <= this.#processed[0].weight / 2) {\n return (\n this.#min +\n ((2 * index) / this.#processed[0].weight) *\n (this.#processed[0].mean - this.#min)\n );\n }\n\n const lower = binarySearch(\n this.#cumulative.length,\n (i: number) => -this.#cumulative[i] + index,\n );\n\n if (lower + 1 !== this.#cumulative.length) {\n const z1 = index - this.#cumulative[lower - 1];\n const z2 = this.#cumulative[lower] - index;\n return weightedAverage(\n this.#processed[lower - 1].mean,\n z2,\n this.#processed[lower].mean,\n z1,\n );\n }\n\n const z1 =\n index - this.#processedWeight - this.#processed[lower - 1].weight / 2;\n const z2 = this.#processed[lower - 1].weight / 2 - z1;\n return weightedAverage(\n this.#processed[this.#processed.length - 1].mean,\n z1,\n this.#max,\n z2,\n );\n }\n\n /**\n * CDF returns the cumulative distribution function for a given value x.\n */\n cdf(x: number): number {\n this.#process();\n this.#updateCumulative();\n switch (this.#processed.length) {\n case 0:\n return 0;\n case 1: {\n const width = this.#max - this.#min;\n if (x <= this.#min) {\n return 0;\n }\n if (x >= this.#max) {\n return 1;\n }\n if (x - this.#min <= width) {\n // min and max are too close together to do any viable interpolation\n return 0.5;\n }\n return (x - this.#min) / width;\n }\n }\n\n if (x <= this.#min) {\n return 0;\n }\n if (x >= this.#max) {\n return 1;\n }\n const m0 = this.#processed[0].mean;\n // Left Tail\n if (x <= m0) {\n if (m0 - this.#min > 0) {\n return (\n (((x - this.#min) / (m0 - this.#min)) * this.#processed[0].weight) /\n this.#processedWeight /\n 2\n );\n }\n return 0;\n }\n // Right Tail\n const mn = this.#processed[this.#processed.length - 1].mean;\n if (x >= mn) {\n if (this.#max - mn > 0) {\n return (\n 1 -\n (((this.#max - x) / (this.#max - mn)) *\n this.#processed[this.#processed.length - 1].weight) /\n this.#processedWeight /\n 2\n );\n }\n return 1;\n }\n\n const upper = binarySearch(\n this.#processed.length,\n // Treat equals as greater than, so we can use the upper index\n // This is equivalent to:\n // i => this.#processed[i].mean > x ? -1 : 1,\n i => x - this.#processed[i].mean || 1,\n );\n\n const z1 = x - this.#processed[upper - 1].mean;\n const z2 = this.#processed[upper].mean - x;\n return (\n weightedAverage(\n this.#cumulative[upper - 1],\n z2,\n this.#cumulative[upper],\n z1,\n ) / this.#processedWeight\n );\n }\n\n #integratedQ(k: number): number {\n return (\n (Math.sin(\n (Math.min(k, this.compression) * Math.PI) / this.compression -\n Math.PI / 2,\n ) +\n 1) /\n 2\n );\n }\n\n #integratedLocation(q: number): number {\n return (this.compression * (Math.asin(2 * q - 1) + Math.PI / 2)) / Math.PI;\n }\n}\n\n// Calculate number of bytes needed for a tdigest of size c,\n// where c is the compression value\nexport function byteSizeForCompression(comp: number): number {\n const c = comp | 0;\n // // A centroid is 2 float64s, so we need 16 bytes for each centroid\n // float_size := 8\n // centroid_size := 2 * float_size\n\n // // Unprocessed and processed can grow up to length c\n // unprocessed_size := centroid_size * c\n // processed_size := unprocessed_size\n\n // // the cumulative field can also be of length c, but each item is a single float64\n // cumulative_size := float_size * c // <- this could also be unprocessed_size / 2\n\n // return unprocessed_size + processed_size + cumulative_size\n\n // // or, more succinctly:\n // return float_size * c * 5\n\n // or even more succinctly\n return c * 40;\n}\n\nfunction weightedAverage(\n x1: number,\n w1: number,\n x2: number,\n w2: number,\n): number {\n if (x1 <= x2) {\n return weightedAverageSorted(x1, w1, x2, w2);\n }\n return weightedAverageSorted(x2, w2, x1, w1);\n}\n\nfunction weightedAverageSorted(\n x1: number,\n w1: number,\n x2: number,\n w2: number,\n): number {\n const x = (x1 * w1 + x2 * w2) / (w1 + w2);\n return Math.max(x1, Math.min(x, x2));\n}\n\nfunction processedSize(size: number, compression: number): number {\n if (size === 0) {\n return Math.ceil(compression) * 2;\n }\n return size;\n}\n\nfunction unprocessedSize(size: number, compression: number): number {\n if (size === 0) {\n return Math.ceil(compression) * 8;\n }\n return size;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tdigest.js","names":["#maxProcessed","#maxUnprocessed","#processed","#unprocessed","#cumulative","#processedWeight","#unprocessedWeight","#min","#max","#process","#integratedQ","#integratedLocation","#updateCumulative"],"sources":["../../../../shared/src/tdigest.ts"],"sourcesContent":["// Apache License 2.0\n// https://github.com/influxdata/tdigest\n\nimport {binarySearch} from './binary-search.ts';\nimport {Centroid, sortCentroidList, type CentroidList} from './centroid.ts';\nimport type {TDigestJSON} from './tdigest-schema.ts';\n\nexport interface ReadonlyTDigest {\n readonly count: () => number;\n readonly quantile: (q: number) => number;\n readonly cdf: (x: number) => number;\n}\n\n// TDigest is a data structure for accurate on-line accumulation of\n// rank-based statistics such as quantiles and trimmed means.\nexport class TDigest {\n readonly compression: number;\n\n #maxProcessed: number;\n #maxUnprocessed: number;\n #processed!: CentroidList;\n #unprocessed!: CentroidList;\n #cumulative!: number[];\n #processedWeight!: number;\n #unprocessedWeight!: number;\n #min!: number;\n #max!: number;\n\n constructor(compression: number = 1000) {\n this.compression = compression;\n this.#maxProcessed = processedSize(0, this.compression);\n this.#maxUnprocessed = unprocessedSize(0, this.compression);\n this.reset();\n }\n\n /**\n * fromJSON creates a TDigest from a JSON-serializable representation.\n * The data should be an object with compression and centroids array.\n */\n static fromJSON(data: Readonly<TDigestJSON>): TDigest {\n const digest = new TDigest(data[0]);\n if (data.length % 2 !== 1) {\n throw new Error('Invalid centroids array');\n }\n for (let i = 1; i < data.length; i += 2) {\n digest.add(data[i], data[i + 1]);\n }\n return digest;\n }\n\n reset(): void {\n this.#processed = [];\n this.#unprocessed = [];\n this.#cumulative = [];\n this.#processedWeight = 0;\n this.#unprocessedWeight = 0;\n this.#min = Number.MAX_VALUE;\n this.#max = -Number.MAX_VALUE;\n }\n\n add(mean: number, weight: number = 1) {\n this.addCentroid(new Centroid(mean, weight));\n }\n\n /** AddCentroidList can quickly add multiple centroids. */\n addCentroidList(centroidList: CentroidList) {\n for (const c of centroidList) {\n this.addCentroid(c);\n }\n }\n\n /**\n * AddCentroid adds a single centroid.\n * Weights which are not a number or are <= 0 are ignored, as are NaN means.\n */\n addCentroid(c: Centroid): void {\n if (\n Number.isNaN(c.mean) ||\n c.weight <= 0 ||\n Number.isNaN(c.weight) ||\n !Number.isFinite(c.weight)\n ) {\n return;\n }\n\n this.#unprocessed.push(new Centroid(c.mean, c.weight));\n this.#unprocessedWeight += c.weight;\n\n if (\n this.#processed.length > this.#maxProcessed ||\n this.#unprocessed.length > this.#maxUnprocessed\n ) {\n this.#process();\n }\n }\n\n /**\n * Merges the supplied digest into this digest. Functionally equivalent to\n * calling t.AddCentroidList(t2.Centroids(nil)), but avoids making an extra\n * copy of the CentroidList.\n **/\n merge(t2: TDigest) {\n t2.#process();\n this.addCentroidList(t2.#processed);\n }\n\n #process() {\n if (\n this.#unprocessed.length > 0 ||\n this.#processed.length > this.#maxProcessed\n ) {\n // Append all processed centroids to the unprocessed list and sort\n this.#unprocessed.push(...this.#processed);\n sortCentroidList(this.#unprocessed);\n\n // Reset processed list with first centroid\n this.#processed.length = 0;\n this.#processed.push(this.#unprocessed[0]);\n\n this.#processedWeight += this.#unprocessedWeight;\n this.#unprocessedWeight = 0;\n let soFar = this.#unprocessed[0].weight;\n let limit = this.#processedWeight * this.#integratedQ(1);\n for (let i = 1; i < this.#unprocessed.length; i++) {\n const centroid = this.#unprocessed[i];\n const projected = soFar + centroid.weight;\n if (projected <= limit) {\n soFar = projected;\n // oxlint-disable-next-line typescript/no-non-null-assertion\n this.#processed.at(-1)!.add(centroid);\n } else {\n const k1 = this.#integratedLocation(soFar / this.#processedWeight);\n limit = this.#processedWeight * this.#integratedQ(k1 + 1);\n soFar += centroid.weight;\n this.#processed.push(centroid);\n }\n }\n this.#min = Math.min(this.#min, this.#processed[0].mean);\n // oxlint-disable-next-line typescript/no-non-null-assertion\n this.#max = Math.max(this.#max, this.#processed.at(-1)!.mean);\n this.#unprocessed.length = 0;\n }\n }\n\n /**\n * Centroids returns a copy of processed centroids.\n * Useful when aggregating multiple t-digests.\n *\n * Centroids are appended to the passed CentroidList; if you're re-using a\n * buffer, be sure to pass cl[:0].\n */\n centroids(cl: CentroidList = []): CentroidList {\n this.#process();\n return [...cl, ...this.#processed];\n }\n\n count(): number {\n this.#process();\n\n // this.process always updates this.processedWeight to the total count of all\n // centroids, so we don't need to re-count here.\n return this.#processedWeight;\n }\n\n /**\n * toJSON returns a JSON-serializable representation of the digest.\n * This processes the digest and returns an object with compression and centroid data.\n */\n toJSON(): TDigestJSON {\n this.#process();\n const data: TDigestJSON = [this.compression];\n for (const centroid of this.#processed) {\n data.push(centroid.mean, centroid.weight);\n }\n return data;\n }\n\n #updateCumulative() {\n // Weight can only increase, so the final cumulative value will always be\n // either equal to, or less than, the total weight. If they are the same,\n // then nothing has changed since the last update.\n if (\n this.#cumulative.length > 0 &&\n this.#cumulative.at(-1) === this.#processedWeight\n ) {\n return;\n }\n const n = this.#processed.length + 1;\n if (this.#cumulative.length > n) {\n this.#cumulative.length = n;\n }\n\n let prev = 0;\n for (let i = 0; i < this.#processed.length; i++) {\n const centroid = this.#processed[i];\n const cur = centroid.weight;\n this.#cumulative[i] = prev + cur / 2;\n prev += cur;\n }\n this.#cumulative[this.#processed.length] = prev;\n }\n\n // Quantile returns the (approximate) quantile of\n // the distribution. Accepted values for q are between 0 and 1.\n // Returns NaN if Count is zero or bad inputs.\n quantile(q: number): number {\n this.#process();\n this.#updateCumulative();\n if (q < 0 || q > 1 || this.#processed.length === 0) {\n return NaN;\n }\n if (this.#processed.length === 1) {\n return this.#processed[0].mean;\n }\n const index = q * this.#processedWeight;\n if (index <= this.#processed[0].weight / 2) {\n return (\n this.#min +\n ((2 * index) / this.#processed[0].weight) *\n (this.#processed[0].mean - this.#min)\n );\n }\n\n const lower = binarySearch(\n this.#cumulative.length,\n (i: number) => -this.#cumulative[i] + index,\n );\n\n if (lower + 1 !== this.#cumulative.length) {\n const z1 = index - this.#cumulative[lower - 1];\n const z2 = this.#cumulative[lower] - index;\n return weightedAverage(\n this.#processed[lower - 1].mean,\n z2,\n this.#processed[lower].mean,\n z1,\n );\n }\n\n const z1 =\n index - this.#processedWeight - this.#processed[lower - 1].weight / 2;\n const z2 = this.#processed[lower - 1].weight / 2 - z1;\n // oxlint-disable-next-line typescript/no-non-null-assertion\n return weightedAverage(this.#processed.at(-1)!.mean, z1, this.#max, z2);\n }\n\n /**\n * CDF returns the cumulative distribution function for a given value x.\n */\n cdf(x: number): number {\n this.#process();\n this.#updateCumulative();\n switch (this.#processed.length) {\n case 0:\n return 0;\n case 1: {\n const width = this.#max - this.#min;\n if (x <= this.#min) {\n return 0;\n }\n if (x >= this.#max) {\n return 1;\n }\n if (x - this.#min <= width) {\n // min and max are too close together to do any viable interpolation\n return 0.5;\n }\n return (x - this.#min) / width;\n }\n }\n\n if (x <= this.#min) {\n return 0;\n }\n if (x >= this.#max) {\n return 1;\n }\n const m0 = this.#processed[0].mean;\n // Left Tail\n if (x <= m0) {\n if (m0 - this.#min > 0) {\n return (\n (((x - this.#min) / (m0 - this.#min)) * this.#processed[0].weight) /\n this.#processedWeight /\n 2\n );\n }\n return 0;\n }\n // Right Tail\n // oxlint-disable-next-line typescript/no-non-null-assertion\n const mn = this.#processed.at(-1)!.mean;\n if (x >= mn) {\n if (this.#max - mn > 0) {\n return (\n 1 -\n (((this.#max - x) / (this.#max - mn)) *\n // oxlint-disable-next-line typescript/no-non-null-assertion\n this.#processed.at(-1)!.weight) /\n this.#processedWeight /\n 2\n );\n }\n return 1;\n }\n\n const upper = binarySearch(\n this.#processed.length,\n // Treat equals as greater than, so we can use the upper index\n // This is equivalent to:\n // i => this.#processed[i].mean > x ? -1 : 1,\n i => x - this.#processed[i].mean || 1,\n );\n\n const z1 = x - this.#processed[upper - 1].mean;\n const z2 = this.#processed[upper].mean - x;\n return (\n weightedAverage(\n this.#cumulative[upper - 1],\n z2,\n this.#cumulative[upper],\n z1,\n ) / this.#processedWeight\n );\n }\n\n #integratedQ(k: number): number {\n return (\n (Math.sin(\n (Math.min(k, this.compression) * Math.PI) / this.compression -\n Math.PI / 2,\n ) +\n 1) /\n 2\n );\n }\n\n #integratedLocation(q: number): number {\n return (this.compression * (Math.asin(2 * q - 1) + Math.PI / 2)) / Math.PI;\n }\n}\n\n// Calculate number of bytes needed for a tdigest of size c,\n// where c is the compression value\nexport function byteSizeForCompression(comp: number): number {\n const c = comp | 0;\n // // A centroid is 2 float64s, so we need 16 bytes for each centroid\n // float_size := 8\n // centroid_size := 2 * float_size\n\n // // Unprocessed and processed can grow up to length c\n // unprocessed_size := centroid_size * c\n // processed_size := unprocessed_size\n\n // // the cumulative field can also be of length c, but each item is a single float64\n // cumulative_size := float_size * c // <- this could also be unprocessed_size / 2\n\n // return unprocessed_size + processed_size + cumulative_size\n\n // // or, more succinctly:\n // return float_size * c * 5\n\n // or even more succinctly\n return c * 40;\n}\n\nfunction weightedAverage(\n x1: number,\n w1: number,\n x2: number,\n w2: number,\n): number {\n if (x1 <= x2) {\n return weightedAverageSorted(x1, w1, x2, w2);\n }\n return weightedAverageSorted(x2, w2, x1, w1);\n}\n\nfunction weightedAverageSorted(\n x1: number,\n w1: number,\n x2: number,\n w2: number,\n): number {\n const x = (x1 * w1 + x2 * w2) / (w1 + w2);\n return Math.max(x1, Math.min(x, x2));\n}\n\nfunction processedSize(size: number, compression: number): number {\n if (size === 0) {\n return Math.ceil(compression) * 2;\n }\n return size;\n}\n\nfunction unprocessedSize(size: number, compression: number): number {\n if (size === 0) {\n return Math.ceil(compression) * 8;\n }\n return size;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"valita.d.ts","sourceRoot":"","sources":["../../../../shared/src/valita.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"valita.d.ts","sourceRoot":"","sources":["../../../../shared/src/valita.ts"],"names":[],"mappings":"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"}
@@ -39,7 +39,7 @@ function toDisplayAtPath(v, path) {
39
39
  }
40
40
  function displayList(word, expected, toDisplay = (x) => String(x)) {
41
41
  if (expected.length === 1) return toDisplay(expected[0]);
42
- const suffix = `${toDisplay(expected[expected.length - 2])} ${word} ${toDisplay(expected[expected.length - 1])}`;
42
+ const suffix = `${toDisplay(expected[expected.length - 2])} ${word} ${toDisplay(expected.at(-1))}`;
43
43
  if (expected.length === 2) return suffix;
44
44
  return `${expected.slice(0, -2).map(toDisplay).join(", ")}, ${suffix}`;
45
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"valita.js","names":[],"sources":["../../../../shared/src/valita.ts"],"sourcesContent":["import * as v from '@badrap/valita';\n\nexport * from '@badrap/valita';\n\nfunction toDisplay(value: unknown): string {\n switch (typeof value) {\n case 'string':\n case 'number':\n case 'boolean':\n return JSON.stringify(value);\n case 'undefined':\n return 'undefined';\n case 'bigint':\n return value.toString() + 'n';\n default:\n if (value === null) {\n return 'null';\n }\n if (Array.isArray(value)) {\n return 'array';\n }\n return typeof value;\n }\n}\n\ntype Key = string | number;\n\nfunction toDisplayAtPath(v: unknown, path: Key[] | undefined): string {\n if (!path?.length) {\n return toDisplay(v);\n }\n\n let cur = v;\n for (const p of path) {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n cur = (cur as any)[p];\n }\n return toDisplay(cur);\n}\n\nfunction displayList<T>(\n word: string,\n expected: T[],\n toDisplay: (x: T) => string | number = x => String(x),\n): string | number {\n if (expected.length === 1) {\n return toDisplay(expected[0]);\n }\n\n const suffix = `${toDisplay(\n expected[expected.length - 2],\n )} ${word} ${toDisplay(expected[expected.length - 1])}`;\n if (expected.length === 2) {\n return suffix;\n }\n return `${expected.slice(0, -2).map(toDisplay).join(', ')}, ${suffix}`;\n}\n\nfunction getMessage(\n err: v.Err | v.ValitaError,\n v: unknown,\n schema: v.Type | v.Optional,\n mode: ParseOptionsMode | undefined,\n): string {\n const firstIssue = err.issues[0];\n const {path} = firstIssue;\n const atPath = path?.length ? ` at ${path.join('.')}` : '';\n\n switch (firstIssue.code) {\n case 'invalid_type':\n return `Expected ${displayList(\n 'or',\n firstIssue.expected,\n )}${atPath}. Got ${toDisplayAtPath(v, path)}`;\n case 'missing_value': {\n const atPath =\n path && path.length > 1 ? ` at ${path.slice(0, -1).join('.')}` : '';\n\n if (firstIssue.path?.length) {\n return `Missing property ${firstIssue.path.at(-1)}${atPath}`;\n }\n return `TODO Unknown missing property${atPath}`;\n }\n\n case 'invalid_literal':\n return `Expected literal value ${displayList(\n 'or',\n firstIssue.expected,\n toDisplay,\n )}${atPath} Got ${toDisplayAtPath(v, path)}`;\n\n case 'invalid_length': {\n return `Expected array with length ${\n firstIssue.minLength === firstIssue.maxLength\n ? firstIssue.minLength\n : `between ${firstIssue.minLength} and ${firstIssue.maxLength}`\n }${atPath}. Got array with length ${(v as {length: number}).length}`;\n }\n\n case 'unrecognized_keys':\n if (firstIssue.keys.length === 1) {\n return `Unexpected property ${firstIssue.keys[0]}${atPath}`;\n }\n return `Unexpected properties ${displayList(\n 'and',\n firstIssue.keys,\n )}${atPath}`;\n\n case 'invalid_union':\n return schema.name === 'union'\n ? getDeepestUnionParseError(v, schema as v.UnionType, mode ?? 'strict')\n : `Invalid union value${atPath}`;\n\n case 'custom_error': {\n const {error} = firstIssue;\n const message = !error\n ? 'unknown'\n : typeof error === 'string'\n ? error\n : (error.message ?? 'unknown');\n return `${message}${atPath}. Got ${toDisplayAtPath(v, path)}`;\n }\n }\n}\n\ntype FailedType = {type: v.Type; err: v.Err};\n\nfunction getDeepestUnionParseError(\n value: unknown,\n schema: v.UnionType,\n mode: ParseOptionsMode,\n): string {\n const failures: FailedType[] = [];\n for (const type of schema.options) {\n const r = type.try(value, {mode});\n if (!r.ok) {\n failures.push({type, err: r});\n }\n }\n if (failures.length) {\n // compare the first and second longest-path errors\n failures.sort(pathCmp);\n if (failures.length === 1 || pathCmp(failures[0], failures[1]) < 0) {\n return getMessage(failures[0].err, value, failures[0].type, mode);\n }\n }\n // paths are equivalent\n try {\n const str = JSON.stringify(value);\n return `Invalid union value: ${str}`;\n } catch {\n // fallback if the value could not be stringified\n return `Invalid union value`;\n }\n}\n\n// Descending-order comparison of Issue paths.\n// * [1, 'a'] sorts before [1]\n// * [1] sorts before [0] (i.e. errors later in the tuple sort before earlier errors)\nfunction pathCmp(a: FailedType, b: FailedType) {\n const aPath = a.err.issues[0].path;\n const bPath = b.err.issues[0].path;\n if (aPath.length !== bPath.length) {\n return bPath.length - aPath.length;\n }\n for (let i = 0; i < aPath.length; i++) {\n if (bPath[i] > aPath[i]) {\n return -1;\n }\n if (bPath[i] < aPath[i]) {\n return 1;\n }\n }\n return 0;\n}\n\n/**\n * 'strip' allows unknown properties and removes unknown properties.\n * 'strict' errors if there are unknown properties.\n * 'passthrough' allows unknown properties.\n */\nexport type ParseOptionsMode = 'passthrough' | 'strict' | 'strip';\n\nexport function parse<T>(\n value: unknown,\n schema: v.Type<T>,\n mode?: ParseOptionsMode,\n): T {\n const res = test(value, schema, mode);\n if (!res.ok) {\n throw new TypeError(res.error);\n }\n return res.value;\n}\n\nexport function is<T>(\n value: unknown,\n schema: v.Type<T>,\n mode?: ParseOptionsMode,\n): value is T {\n return test(value, schema, mode).ok;\n}\n\nexport function assert<T>(\n value: unknown,\n schema: v.Type<T>,\n mode?: ParseOptionsMode,\n): asserts value is T {\n parse(value, schema, mode);\n}\n\ntype Result<T> = {ok: true; value: T} | {ok: false; error: string};\n\nexport function test<T>(\n value: unknown,\n schema: v.Type<T>,\n mode?: ParseOptionsMode,\n): Result<T> {\n const res = schema.try(value, mode ? {mode} : undefined);\n if (!res.ok) {\n return {\n ok: false,\n error: getMessage(res, value, schema, mode),\n };\n }\n return res;\n}\n\n/**\n * Similar to {@link test} but works for AbstractTypes such as Optional.\n * This is for advanced usage. Prefer {@link test} unless you really need\n * to operate directly on an Optional field.\n */\nexport function testOptional<T>(\n value: unknown,\n schema: v.Type<T> | v.Optional<T>,\n mode?: ParseOptionsMode,\n): Result<T | undefined> {\n let flags = 0x1; // FLAG_FORBID_EXTRA_KEYS;\n if (mode === 'passthrough') {\n flags = 0;\n } else if (mode === 'strip') {\n flags = 0x2; // FLAG_STRIP_EXTRA_KEYS;\n }\n const res = schema.func(value, flags);\n if (res === undefined) {\n return {ok: true, value} as Result<T>;\n } else if (res.ok) {\n return res;\n }\n const err = new v.ValitaError(res);\n return {ok: false, error: getMessage(err, value, schema, mode)};\n}\n\n/**\n * Shallowly marks the schema as readonly.\n */\nexport function readonly<T extends v.Type>(t: T): v.Type<Readonly<v.Infer<T>>> {\n return t as v.Type<Readonly<v.Infer<T>>>;\n}\n\nexport function readonlyObject<T extends Record<string, v.Type | v.Optional>>(\n t: T,\n): v.ObjectType<Readonly<T>, undefined> {\n return v.object(t);\n}\n\nexport function readonlyArray<T extends v.Type>(\n t: T,\n): v.Type<readonly v.Infer<T>[]> {\n return v.array(t);\n}\n\nexport function readonlyRecord<T extends v.Type>(\n t: T,\n): v.Type<Readonly<Record<string, v.Infer<T>>>> {\n return v.record(t);\n}\n\nconst AbstractType = Object.getPrototypeOf(\n Object.getPrototypeOf(v.string().optional()),\n).constructor;\n\nexport function instanceOfAbstractType<T = unknown>(\n obj: unknown,\n): obj is v.Type<T> | v.Optional<T> {\n return obj instanceof AbstractType;\n}\n\ntype ObjectShape = Record<string, typeof AbstractType>;\n\n/**\n * Similar to `ObjectType.partial()` except it recurses into nested objects.\n * Rest types are not supported.\n */\nexport function deepPartial<Shape extends ObjectShape>(\n s: v.ObjectType<Shape, undefined>,\n) {\n const shape = {} as Record<string, unknown>;\n for (const [key, type] of Object.entries(s.shape)) {\n if (type.name === 'object') {\n shape[key] = deepPartial(type as v.ObjectType).optional();\n } else {\n shape[key] = type.optional();\n }\n }\n return v.object(shape as {[K in keyof Shape]: v.Optional<v.Infer<Shape[K]>>});\n}\n\ntype Literal = string | number | bigint | boolean;\n\nexport function literalUnion<T extends [...Literal[]]>(\n ...literals: T\n): v.Type<T[number]> {\n return v.union(...literals.map(v.literal));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"valita.js","names":[],"sources":["../../../../shared/src/valita.ts"],"sourcesContent":["import * as v from '@badrap/valita';\n\nexport * from '@badrap/valita';\n\nfunction toDisplay(value: unknown): string {\n switch (typeof value) {\n case 'string':\n case 'number':\n case 'boolean':\n return JSON.stringify(value);\n case 'undefined':\n return 'undefined';\n case 'bigint':\n return value.toString() + 'n';\n default:\n if (value === null) {\n return 'null';\n }\n if (Array.isArray(value)) {\n return 'array';\n }\n return typeof value;\n }\n}\n\ntype Key = string | number;\n\nfunction toDisplayAtPath(v: unknown, path: Key[] | undefined): string {\n if (!path?.length) {\n return toDisplay(v);\n }\n\n let cur = v;\n for (const p of path) {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n cur = (cur as any)[p];\n }\n return toDisplay(cur);\n}\n\nfunction displayList<T>(\n word: string,\n expected: T[],\n toDisplay: (x: T) => string | number = x => String(x),\n): string | number {\n if (expected.length === 1) {\n return toDisplay(expected[0]);\n }\n\n const suffix = `${toDisplay(\n expected[expected.length - 2],\n // oxlint-disable-next-line typescript/no-non-null-assertion\n )} ${word} ${toDisplay(expected.at(-1)!)}`;\n if (expected.length === 2) {\n return suffix;\n }\n return `${expected.slice(0, -2).map(toDisplay).join(', ')}, ${suffix}`;\n}\n\nfunction getMessage(\n err: v.Err | v.ValitaError,\n v: unknown,\n schema: v.Type | v.Optional,\n mode: ParseOptionsMode | undefined,\n): string {\n const firstIssue = err.issues[0];\n const {path} = firstIssue;\n const atPath = path?.length ? ` at ${path.join('.')}` : '';\n\n switch (firstIssue.code) {\n case 'invalid_type':\n return `Expected ${displayList(\n 'or',\n firstIssue.expected,\n )}${atPath}. Got ${toDisplayAtPath(v, path)}`;\n case 'missing_value': {\n const atPath =\n path && path.length > 1 ? ` at ${path.slice(0, -1).join('.')}` : '';\n\n if (firstIssue.path?.length) {\n return `Missing property ${firstIssue.path.at(-1)}${atPath}`;\n }\n return `TODO Unknown missing property${atPath}`;\n }\n\n case 'invalid_literal':\n return `Expected literal value ${displayList(\n 'or',\n firstIssue.expected,\n toDisplay,\n )}${atPath} Got ${toDisplayAtPath(v, path)}`;\n\n case 'invalid_length': {\n return `Expected array with length ${\n firstIssue.minLength === firstIssue.maxLength\n ? firstIssue.minLength\n : `between ${firstIssue.minLength} and ${firstIssue.maxLength}`\n }${atPath}. Got array with length ${(v as {length: number}).length}`;\n }\n\n case 'unrecognized_keys':\n if (firstIssue.keys.length === 1) {\n return `Unexpected property ${firstIssue.keys[0]}${atPath}`;\n }\n return `Unexpected properties ${displayList(\n 'and',\n firstIssue.keys,\n )}${atPath}`;\n\n case 'invalid_union':\n return schema.name === 'union'\n ? getDeepestUnionParseError(v, schema as v.UnionType, mode ?? 'strict')\n : `Invalid union value${atPath}`;\n\n case 'custom_error': {\n const {error} = firstIssue;\n const message = !error\n ? 'unknown'\n : typeof error === 'string'\n ? error\n : (error.message ?? 'unknown');\n return `${message}${atPath}. Got ${toDisplayAtPath(v, path)}`;\n }\n }\n}\n\ntype FailedType = {type: v.Type; err: v.Err};\n\nfunction getDeepestUnionParseError(\n value: unknown,\n schema: v.UnionType,\n mode: ParseOptionsMode,\n): string {\n const failures: FailedType[] = [];\n for (const type of schema.options) {\n const r = type.try(value, {mode});\n if (!r.ok) {\n failures.push({type, err: r});\n }\n }\n if (failures.length) {\n // compare the first and second longest-path errors\n failures.sort(pathCmp);\n if (failures.length === 1 || pathCmp(failures[0], failures[1]) < 0) {\n return getMessage(failures[0].err, value, failures[0].type, mode);\n }\n }\n // paths are equivalent\n try {\n const str = JSON.stringify(value);\n return `Invalid union value: ${str}`;\n } catch {\n // fallback if the value could not be stringified\n return `Invalid union value`;\n }\n}\n\n// Descending-order comparison of Issue paths.\n// * [1, 'a'] sorts before [1]\n// * [1] sorts before [0] (i.e. errors later in the tuple sort before earlier errors)\nfunction pathCmp(a: FailedType, b: FailedType) {\n const aPath = a.err.issues[0].path;\n const bPath = b.err.issues[0].path;\n if (aPath.length !== bPath.length) {\n return bPath.length - aPath.length;\n }\n for (let i = 0; i < aPath.length; i++) {\n if (bPath[i] > aPath[i]) {\n return -1;\n }\n if (bPath[i] < aPath[i]) {\n return 1;\n }\n }\n return 0;\n}\n\n/**\n * 'strip' allows unknown properties and removes unknown properties.\n * 'strict' errors if there are unknown properties.\n * 'passthrough' allows unknown properties.\n */\nexport type ParseOptionsMode = 'passthrough' | 'strict' | 'strip';\n\nexport function parse<T>(\n value: unknown,\n schema: v.Type<T>,\n mode?: ParseOptionsMode,\n): T {\n const res = test(value, schema, mode);\n if (!res.ok) {\n throw new TypeError(res.error);\n }\n return res.value;\n}\n\nexport function is<T>(\n value: unknown,\n schema: v.Type<T>,\n mode?: ParseOptionsMode,\n): value is T {\n return test(value, schema, mode).ok;\n}\n\nexport function assert<T>(\n value: unknown,\n schema: v.Type<T>,\n mode?: ParseOptionsMode,\n): asserts value is T {\n parse(value, schema, mode);\n}\n\ntype Result<T> = {ok: true; value: T} | {ok: false; error: string};\n\nexport function test<T>(\n value: unknown,\n schema: v.Type<T>,\n mode?: ParseOptionsMode,\n): Result<T> {\n const res = schema.try(value, mode ? {mode} : undefined);\n if (!res.ok) {\n return {\n ok: false,\n error: getMessage(res, value, schema, mode),\n };\n }\n return res;\n}\n\n/**\n * Similar to {@link test} but works for AbstractTypes such as Optional.\n * This is for advanced usage. Prefer {@link test} unless you really need\n * to operate directly on an Optional field.\n */\nexport function testOptional<T>(\n value: unknown,\n schema: v.Type<T> | v.Optional<T>,\n mode?: ParseOptionsMode,\n): Result<T | undefined> {\n let flags = 0x1; // FLAG_FORBID_EXTRA_KEYS;\n if (mode === 'passthrough') {\n flags = 0;\n } else if (mode === 'strip') {\n flags = 0x2; // FLAG_STRIP_EXTRA_KEYS;\n }\n const res = schema.func(value, flags);\n if (res === undefined) {\n return {ok: true, value} as Result<T>;\n } else if (res.ok) {\n return res;\n }\n const err = new v.ValitaError(res);\n return {ok: false, error: getMessage(err, value, schema, mode)};\n}\n\n/**\n * Shallowly marks the schema as readonly.\n */\nexport function readonly<T extends v.Type>(t: T): v.Type<Readonly<v.Infer<T>>> {\n return t as v.Type<Readonly<v.Infer<T>>>;\n}\n\nexport function readonlyObject<T extends Record<string, v.Type | v.Optional>>(\n t: T,\n): v.ObjectType<Readonly<T>, undefined> {\n return v.object(t);\n}\n\nexport function readonlyArray<T extends v.Type>(\n t: T,\n): v.Type<readonly v.Infer<T>[]> {\n return v.array(t);\n}\n\nexport function readonlyRecord<T extends v.Type>(\n t: T,\n): v.Type<Readonly<Record<string, v.Infer<T>>>> {\n return v.record(t);\n}\n\nconst AbstractType = Object.getPrototypeOf(\n Object.getPrototypeOf(v.string().optional()),\n).constructor;\n\nexport function instanceOfAbstractType<T = unknown>(\n obj: unknown,\n): obj is v.Type<T> | v.Optional<T> {\n return obj instanceof AbstractType;\n}\n\ntype ObjectShape = Record<string, typeof AbstractType>;\n\n/**\n * Similar to `ObjectType.partial()` except it recurses into nested objects.\n * Rest types are not supported.\n */\nexport function deepPartial<Shape extends ObjectShape>(\n s: v.ObjectType<Shape, undefined>,\n) {\n const shape = {} as Record<string, unknown>;\n for (const [key, type] of Object.entries(s.shape)) {\n if (type.name === 'object') {\n shape[key] = deepPartial(type as v.ObjectType).optional();\n } else {\n shape[key] = type.optional();\n }\n }\n return v.object(shape as {[K in keyof Shape]: v.Optional<v.Infer<Shape[K]>>});\n}\n\ntype Literal = string | number | bigint | boolean;\n\nexport function literalUnion<T extends [...Literal[]]>(\n ...literals: T\n): v.Type<T[number]> {\n return v.union(...literals.map(v.literal));\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { SQLQuery } from '@databases/sql';
2
- import baseSql from '@databases/sql';
2
+ import sql from '@databases/sql';
3
3
  import type { ServerColumnSchema } from '../../zero-types/src/server-schema.ts';
4
4
  export declare function formatPg(sql: SQLQuery): {
5
5
  text: string;
@@ -18,5 +18,5 @@ export type PluralLiteralType = Exclude<LiteralType, 'null'>;
18
18
  export declare function sqlConvertSingularLiteralArg(value: string | boolean | number | null): SQLQuery;
19
19
  export declare function sqlConvertPluralLiteralArg(type: PluralLiteralType, value: PluralLiteralType[]): SQLQuery;
20
20
  export declare function sqlConvertColumnArg(serverColumnSchema: ServerColumnSchema, value: unknown, plural: boolean, isComparison: boolean): SQLQuery;
21
- export declare const sql: baseSql.SQL;
21
+ export { sql };
22
22
  //# sourceMappingURL=sql.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../../../z2s/src/sql.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAwB,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AACpE,OAAO,OAAsB,MAAM,gBAAgB,CAAC;AAOpD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,uCAAuC,CAAC;AAE9E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,QAAQ;UA0Q9B,MAAM;YACJ,OAAO,EAAE;EAxQlB;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,QAAQ;UAqQ7C,MAAM;YACJ,OAAO,EAAE;EAnQlB;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,QAAQ;UAgQlC,MAAM;YACJ,OAAO,EAAE;EA9PlB;AAID,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AACnE,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAwB7D,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,GACtC,QAAQ,CAQV;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,iBAAiB,EAAE,GACzB,QAAQ,CAQV;AAED,wBAAgB,mBAAmB,CACjC,kBAAkB,EAAE,kBAAkB,EACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,EACf,YAAY,EAAE,OAAO,GACpB,QAAQ,CASV;AAiLD,eAAO,MAAM,GAAG,aAAkB,CAAC"}
1
+ {"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../../../z2s/src/sql.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAwB,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AACpE,OAAO,GAAkB,MAAM,gBAAgB,CAAC;AAOhD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,uCAAuC,CAAC;AAE9E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,QAAQ;UA4Q9B,MAAM;YACJ,OAAO,EAAE;EA1QlB;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,QAAQ;UAuQ7C,MAAM;YACJ,OAAO,EAAE;EArQlB;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,QAAQ;UAkQlC,MAAM;YACJ,OAAO,EAAE;EAhQlB;AAID,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AACnE,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAwB7D,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,GACtC,QAAQ,CAQV;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,iBAAiB,EAAE,GACzB,QAAQ,CAQV;AAED,wBAAgB,mBAAmB,CACjC,kBAAkB,EAAE,kBAAkB,EACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,EACf,YAAY,EAAE,OAAO,GACpB,QAAQ,CASV;AAiLD,OAAO,EAAC,GAAG,EAAC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { assert, unreachable } from "../../shared/src/asserts.js";
2
2
  import { isPgNumberType, isPgStringType } from "../../zero-cache/src/types/pg-data-type.js";
3
3
  import { escapePostgresIdentifier } from "@databases/escape-identifier";
4
- import baseSql, { SQLItemType } from "@databases/sql";
4
+ import sql, { SQLItemType } from "@databases/sql";
5
5
  //#region ../z2s/src/sql.ts
6
6
  function formatPg(sql) {
7
7
  const format = new ReusingFormat(escapePostgresIdentifier);
@@ -113,7 +113,7 @@ function formatCommonToSingularAndPlural(index, arg) {
113
113
  case "timestamp with time zone": atTimeZone = "";
114
114
  case "date":
115
115
  case "timestamp":
116
- case "timestamp without time zone": return `to_timestamp(${valuePlaceholder}::text::bigint / 1000.0)${atTimeZone}`;
116
+ case "timestamp without time zone": return `to_timestamp(${valuePlaceholder}::text::numeric / 1000.0)${atTimeZone}`;
117
117
  case "timetz":
118
118
  case "time with time zone": atTimeZone = "";
119
119
  case "time":
@@ -138,8 +138,8 @@ function pgTypeForLiteralType(type) {
138
138
  default: unreachable(type);
139
139
  }
140
140
  }
141
- var sql = baseSql.default;
142
141
  var PREVIOUSLY_SEEN_VALUE = Symbol("PREVIOUSLY_SEEN_VALUE");
142
+ var whitespacePrefixRe = /^\s*/;
143
143
  function formatFn(items, { escapeIdentifier, formatValue }) {
144
144
  let text = "";
145
145
  const values = [];
@@ -166,7 +166,7 @@ function formatFn(items, { escapeIdentifier, formatValue }) {
166
166
  }
167
167
  if (text.trim()) {
168
168
  const lines = text.split("\n");
169
- const min = Math.min(...lines.filter((l) => l.trim() !== "").map((l) => /^\s*/.exec(l)[0].length));
169
+ const min = Math.min(...lines.filter((l) => l.trim() !== "").map((l) => whitespacePrefixRe.exec(l)[0].length));
170
170
  if (min) text = lines.map((line) => line.substr(min)).join("\n");
171
171
  }
172
172
  return {