@wizeworks/lens-cloud 0.0.0-stage → 0.3.0-alpha.2

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 (351) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -2
  3. package/dist/alerts/evaluate.d.ts +10 -0
  4. package/dist/alerts/evaluate.d.ts.map +1 -0
  5. package/dist/alerts/evaluate.js +81 -0
  6. package/dist/alerts/evaluate.js.map +1 -0
  7. package/dist/alerts/notify.d.ts +28 -0
  8. package/dist/alerts/notify.d.ts.map +1 -0
  9. package/dist/alerts/notify.js +52 -0
  10. package/dist/alerts/notify.js.map +1 -0
  11. package/dist/app.d.ts +26 -0
  12. package/dist/app.d.ts.map +1 -0
  13. package/dist/app.js +2 -0
  14. package/dist/app.js.map +1 -0
  15. package/dist/auth/auth.d.ts +51 -0
  16. package/dist/auth/auth.d.ts.map +1 -0
  17. package/dist/auth/auth.js +63 -0
  18. package/dist/auth/auth.js.map +1 -0
  19. package/dist/auth/bridge.d.ts +7 -0
  20. package/dist/auth/bridge.d.ts.map +1 -0
  21. package/dist/auth/bridge.js +39 -0
  22. package/dist/auth/bridge.js.map +1 -0
  23. package/dist/auth/crypto.d.ts +14 -0
  24. package/dist/auth/crypto.d.ts.map +1 -0
  25. package/dist/auth/crypto.js +16 -0
  26. package/dist/auth/crypto.js.map +1 -0
  27. package/dist/auth/delete-user.d.ts +16 -0
  28. package/dist/auth/delete-user.d.ts.map +1 -0
  29. package/dist/auth/delete-user.js +21 -0
  30. package/dist/auth/delete-user.js.map +1 -0
  31. package/dist/auth/deps.d.ts +27 -0
  32. package/dist/auth/deps.d.ts.map +1 -0
  33. package/dist/auth/deps.js +3 -0
  34. package/dist/auth/deps.js.map +1 -0
  35. package/dist/auth/email-token.d.ts +8 -0
  36. package/dist/auth/email-token.d.ts.map +1 -0
  37. package/dist/auth/email-token.js +15 -0
  38. package/dist/auth/email-token.js.map +1 -0
  39. package/dist/auth/hooks.d.ts +4 -0
  40. package/dist/auth/hooks.d.ts.map +1 -0
  41. package/dist/auth/hooks.js +143 -0
  42. package/dist/auth/hooks.js.map +1 -0
  43. package/dist/auth/options.d.ts +17 -0
  44. package/dist/auth/options.d.ts.map +1 -0
  45. package/dist/auth/options.js +98 -0
  46. package/dist/auth/options.js.map +1 -0
  47. package/dist/auth/password.d.ts +10 -0
  48. package/dist/auth/password.d.ts.map +1 -0
  49. package/dist/auth/password.js +22 -0
  50. package/dist/auth/password.js.map +1 -0
  51. package/dist/auth/plugins.d.ts +4 -0
  52. package/dist/auth/plugins.d.ts.map +1 -0
  53. package/dist/auth/plugins.js +45 -0
  54. package/dist/auth/plugins.js.map +1 -0
  55. package/dist/auth/principal.d.ts +38 -0
  56. package/dist/auth/principal.d.ts.map +1 -0
  57. package/dist/auth/principal.js +69 -0
  58. package/dist/auth/principal.js.map +1 -0
  59. package/dist/auth/roles.d.ts +50 -0
  60. package/dist/auth/roles.d.ts.map +1 -0
  61. package/dist/auth/roles.js +18 -0
  62. package/dist/auth/roles.js.map +1 -0
  63. package/dist/auth/schema-names.d.ts +130 -0
  64. package/dist/auth/schema-names.d.ts.map +1 -0
  65. package/dist/auth/schema-names.js +53 -0
  66. package/dist/auth/schema-names.js.map +1 -0
  67. package/dist/auth/secret.d.ts +12 -0
  68. package/dist/auth/secret.d.ts.map +1 -0
  69. package/dist/auth/secret.js +32 -0
  70. package/dist/auth/secret.js.map +1 -0
  71. package/dist/auth/security-notices.d.ts +34 -0
  72. package/dist/auth/security-notices.d.ts.map +1 -0
  73. package/dist/auth/security-notices.js +81 -0
  74. package/dist/auth/security-notices.js.map +1 -0
  75. package/dist/auth/signup.d.ts +23 -0
  76. package/dist/auth/signup.d.ts.map +1 -0
  77. package/dist/auth/signup.js +61 -0
  78. package/dist/auth/signup.js.map +1 -0
  79. package/dist/auth/sso.d.ts +21 -0
  80. package/dist/auth/sso.d.ts.map +1 -0
  81. package/dist/auth/sso.js +35 -0
  82. package/dist/auth/sso.js.map +1 -0
  83. package/dist/auth/wire.d.ts +16 -0
  84. package/dist/auth/wire.d.ts.map +1 -0
  85. package/dist/auth/wire.js +47 -0
  86. package/dist/auth/wire.js.map +1 -0
  87. package/dist/cli-args.d.ts +5 -0
  88. package/dist/cli-args.d.ts.map +1 -0
  89. package/dist/cli-args.js +86 -0
  90. package/dist/cli-args.js.map +1 -0
  91. package/dist/cli.d.ts +3 -0
  92. package/dist/cli.d.ts.map +1 -0
  93. package/dist/cli.js +44 -0
  94. package/dist/cli.js.map +1 -0
  95. package/dist/config.d.ts +55 -0
  96. package/dist/config.d.ts.map +1 -0
  97. package/dist/config.js +55 -0
  98. package/dist/config.js.map +1 -0
  99. package/dist/db/db.d.ts +22 -0
  100. package/dist/db/db.d.ts.map +1 -0
  101. package/dist/db/db.js +64 -0
  102. package/dist/db/db.js.map +1 -0
  103. package/dist/db/migrate.d.ts +6 -0
  104. package/dist/db/migrate.d.ts.map +1 -0
  105. package/dist/db/migrate.js +35 -0
  106. package/dist/db/migrate.js.map +1 -0
  107. package/dist/db/schema-auth.d.ts +2 -0
  108. package/dist/db/schema-auth.d.ts.map +1 -0
  109. package/dist/db/schema-auth.js +93 -0
  110. package/dist/db/schema-auth.js.map +1 -0
  111. package/dist/db/schema-mail.d.ts +2 -0
  112. package/dist/db/schema-mail.d.ts.map +1 -0
  113. package/dist/db/schema-mail.js +8 -0
  114. package/dist/db/schema-mail.js.map +1 -0
  115. package/dist/db/schema-notify.d.ts +2 -0
  116. package/dist/db/schema-notify.d.ts.map +1 -0
  117. package/dist/db/schema-notify.js +26 -0
  118. package/dist/db/schema-notify.js.map +1 -0
  119. package/dist/db/schema-sso.d.ts +2 -0
  120. package/dist/db/schema-sso.d.ts.map +1 -0
  121. package/dist/db/schema-sso.js +17 -0
  122. package/dist/db/schema-sso.js.map +1 -0
  123. package/dist/db/schema.d.ts +3 -0
  124. package/dist/db/schema.d.ts.map +1 -0
  125. package/dist/db/schema.js +208 -0
  126. package/dist/db/schema.js.map +1 -0
  127. package/dist/http/http.d.ts +19 -0
  128. package/dist/http/http.d.ts.map +1 -0
  129. package/dist/http/http.js +66 -0
  130. package/dist/http/http.js.map +1 -0
  131. package/dist/http/limiter.d.ts +11 -0
  132. package/dist/http/limiter.d.ts.map +1 -0
  133. package/dist/http/limiter.js +31 -0
  134. package/dist/http/limiter.js.map +1 -0
  135. package/dist/http/router.d.ts +21 -0
  136. package/dist/http/router.d.ts.map +1 -0
  137. package/dist/http/router.js +28 -0
  138. package/dist/http/router.js.map +1 -0
  139. package/dist/index.d.ts +7 -0
  140. package/dist/index.d.ts.map +1 -0
  141. package/dist/index.js +4 -0
  142. package/dist/index.js.map +1 -0
  143. package/dist/jobs.d.ts +4 -0
  144. package/dist/jobs.d.ts.map +1 -0
  145. package/dist/jobs.js +53 -0
  146. package/dist/jobs.js.map +1 -0
  147. package/dist/mail/blocks.d.ts +14 -0
  148. package/dist/mail/blocks.d.ts.map +1 -0
  149. package/dist/mail/blocks.js +35 -0
  150. package/dist/mail/blocks.js.map +1 -0
  151. package/dist/mail/content.d.ts +68 -0
  152. package/dist/mail/content.d.ts.map +1 -0
  153. package/dist/mail/content.js +6 -0
  154. package/dist/mail/content.js.map +1 -0
  155. package/dist/mail/emails-digest.d.ts +10 -0
  156. package/dist/mail/emails-digest.d.ts.map +1 -0
  157. package/dist/mail/emails-digest.js +55 -0
  158. package/dist/mail/emails-digest.js.map +1 -0
  159. package/dist/mail/emails-health.d.ts +6 -0
  160. package/dist/mail/emails-health.d.ts.map +1 -0
  161. package/dist/mail/emails-health.js +36 -0
  162. package/dist/mail/emails-health.js.map +1 -0
  163. package/dist/mail/emails-security.d.ts +14 -0
  164. package/dist/mail/emails-security.d.ts.map +1 -0
  165. package/dist/mail/emails-security.js +27 -0
  166. package/dist/mail/emails-security.js.map +1 -0
  167. package/dist/mail/emails-team.d.ts +11 -0
  168. package/dist/mail/emails-team.d.ts.map +1 -0
  169. package/dist/mail/emails-team.js +45 -0
  170. package/dist/mail/emails-team.js.map +1 -0
  171. package/dist/mail/emails.d.ts +9 -0
  172. package/dist/mail/emails.d.ts.map +1 -0
  173. package/dist/mail/emails.js +49 -0
  174. package/dist/mail/emails.js.map +1 -0
  175. package/dist/mail/layout.d.ts +6 -0
  176. package/dist/mail/layout.d.ts.map +1 -0
  177. package/dist/mail/layout.js +10 -0
  178. package/dist/mail/layout.js.map +1 -0
  179. package/dist/mail/mailer.d.ts +25 -0
  180. package/dist/mail/mailer.d.ts.map +1 -0
  181. package/dist/mail/mailer.js +49 -0
  182. package/dist/mail/mailer.js.map +1 -0
  183. package/dist/mail/preview.d.ts +6 -0
  184. package/dist/mail/preview.d.ts.map +1 -0
  185. package/dist/mail/preview.js +26 -0
  186. package/dist/mail/preview.js.map +1 -0
  187. package/dist/mail/resend.d.ts +11 -0
  188. package/dist/mail/resend.d.ts.map +1 -0
  189. package/dist/mail/resend.js +34 -0
  190. package/dist/mail/resend.js.map +1 -0
  191. package/dist/mail/samples.d.ts +3 -0
  192. package/dist/mail/samples.d.ts.map +1 -0
  193. package/dist/mail/samples.js +63 -0
  194. package/dist/mail/samples.js.map +1 -0
  195. package/dist/mail/stop-route.d.ts +4 -0
  196. package/dist/mail/stop-route.d.ts.map +1 -0
  197. package/dist/mail/stop-route.js +41 -0
  198. package/dist/mail/stop-route.js.map +1 -0
  199. package/dist/mail/svix.d.ts +8 -0
  200. package/dist/mail/svix.d.ts.map +1 -0
  201. package/dist/mail/svix.js +17 -0
  202. package/dist/mail/svix.js.map +1 -0
  203. package/dist/mail/templates.d.ts +12 -0
  204. package/dist/mail/templates.d.ts.map +1 -0
  205. package/dist/mail/templates.js +18 -0
  206. package/dist/mail/templates.js.map +1 -0
  207. package/dist/mail/text.d.ts +4 -0
  208. package/dist/mail/text.d.ts.map +1 -0
  209. package/dist/mail/text.js +17 -0
  210. package/dist/mail/text.js.map +1 -0
  211. package/dist/mail/theme.d.ts +26 -0
  212. package/dist/mail/theme.d.ts.map +1 -0
  213. package/dist/mail/theme.js +21 -0
  214. package/dist/mail/theme.js.map +1 -0
  215. package/dist/mail/unsubscribe.d.ts +14 -0
  216. package/dist/mail/unsubscribe.d.ts.map +1 -0
  217. package/dist/mail/unsubscribe.js +39 -0
  218. package/dist/mail/unsubscribe.js.map +1 -0
  219. package/dist/mail/webhook.d.ts +5 -0
  220. package/dist/mail/webhook.d.ts.map +1 -0
  221. package/dist/mail/webhook.js +41 -0
  222. package/dist/mail/webhook.js.map +1 -0
  223. package/dist/notify/digest-data.d.ts +31 -0
  224. package/dist/notify/digest-data.d.ts.map +1 -0
  225. package/dist/notify/digest-data.js +37 -0
  226. package/dist/notify/digest-data.js.map +1 -0
  227. package/dist/notify/digest.d.ts +17 -0
  228. package/dist/notify/digest.d.ts.map +1 -0
  229. package/dist/notify/digest.js +76 -0
  230. package/dist/notify/digest.js.map +1 -0
  231. package/dist/notify/health.d.ts +6 -0
  232. package/dist/notify/health.d.ts.map +1 -0
  233. package/dist/notify/health.js +43 -0
  234. package/dist/notify/health.js.map +1 -0
  235. package/dist/notify/team-describe.d.ts +22 -0
  236. package/dist/notify/team-describe.d.ts.map +1 -0
  237. package/dist/notify/team-describe.js +67 -0
  238. package/dist/notify/team-describe.js.map +1 -0
  239. package/dist/notify/team.d.ts +6 -0
  240. package/dist/notify/team.d.ts.map +1 -0
  241. package/dist/notify/team.js +56 -0
  242. package/dist/notify/team.js.map +1 -0
  243. package/dist/repo/alerts.d.ts +52 -0
  244. package/dist/repo/alerts.d.ts.map +1 -0
  245. package/dist/repo/alerts.js +38 -0
  246. package/dist/repo/alerts.js.map +1 -0
  247. package/dist/repo/audit.d.ts +11 -0
  248. package/dist/repo/audit.d.ts.map +1 -0
  249. package/dist/repo/audit.js +17 -0
  250. package/dist/repo/audit.js.map +1 -0
  251. package/dist/repo/auth-prune.d.ts +4 -0
  252. package/dist/repo/auth-prune.d.ts.map +1 -0
  253. package/dist/repo/auth-prune.js +8 -0
  254. package/dist/repo/auth-prune.js.map +1 -0
  255. package/dist/repo/mail-prefs.d.ts +35 -0
  256. package/dist/repo/mail-prefs.d.ts.map +1 -0
  257. package/dist/repo/mail-prefs.js +34 -0
  258. package/dist/repo/mail-prefs.js.map +1 -0
  259. package/dist/repo/metric-read.d.ts +12 -0
  260. package/dist/repo/metric-read.d.ts.map +1 -0
  261. package/dist/repo/metric-read.js +11 -0
  262. package/dist/repo/metric-read.js.map +1 -0
  263. package/dist/repo/metric-write.d.ts +9 -0
  264. package/dist/repo/metric-write.d.ts.map +1 -0
  265. package/dist/repo/metric-write.js +53 -0
  266. package/dist/repo/metric-write.js.map +1 -0
  267. package/dist/repo/orgs.d.ts +37 -0
  268. package/dist/repo/orgs.d.ts.map +1 -0
  269. package/dist/repo/orgs.js +33 -0
  270. package/dist/repo/orgs.js.map +1 -0
  271. package/dist/repo/projects.d.ts +37 -0
  272. package/dist/repo/projects.d.ts.map +1 -0
  273. package/dist/repo/projects.js +57 -0
  274. package/dist/repo/projects.js.map +1 -0
  275. package/dist/repo/suppressions.d.ts +8 -0
  276. package/dist/repo/suppressions.d.ts.map +1 -0
  277. package/dist/repo/suppressions.js +16 -0
  278. package/dist/repo/suppressions.js.map +1 -0
  279. package/dist/repo/trace-read.d.ts +28 -0
  280. package/dist/repo/trace-read.d.ts.map +1 -0
  281. package/dist/repo/trace-read.js +76 -0
  282. package/dist/repo/trace-read.js.map +1 -0
  283. package/dist/repo/trace-write.d.ts +9 -0
  284. package/dist/repo/trace-write.d.ts.map +1 -0
  285. package/dist/repo/trace-write.js +82 -0
  286. package/dist/repo/trace-write.js.map +1 -0
  287. package/dist/repo/users.d.ts +13 -0
  288. package/dist/repo/users.d.ts.map +1 -0
  289. package/dist/repo/users.js +7 -0
  290. package/dist/repo/users.js.map +1 -0
  291. package/dist/routes/alerts.d.ts +4 -0
  292. package/dist/routes/alerts.d.ts.map +1 -0
  293. package/dist/routes/alerts.js +116 -0
  294. package/dist/routes/alerts.js.map +1 -0
  295. package/dist/routes/data.d.ts +7 -0
  296. package/dist/routes/data.d.ts.map +1 -0
  297. package/dist/routes/data.js +74 -0
  298. package/dist/routes/data.js.map +1 -0
  299. package/dist/routes/index.d.ts +5 -0
  300. package/dist/routes/index.d.ts.map +1 -0
  301. package/dist/routes/index.js +25 -0
  302. package/dist/routes/index.js.map +1 -0
  303. package/dist/routes/ingest.d.ts +8 -0
  304. package/dist/routes/ingest.d.ts.map +1 -0
  305. package/dist/routes/ingest.js +38 -0
  306. package/dist/routes/ingest.js.map +1 -0
  307. package/dist/routes/mcp.d.ts +4 -0
  308. package/dist/routes/mcp.d.ts.map +1 -0
  309. package/dist/routes/mcp.js +52 -0
  310. package/dist/routes/mcp.js.map +1 -0
  311. package/dist/routes/me.d.ts +4 -0
  312. package/dist/routes/me.d.ts.map +1 -0
  313. package/dist/routes/me.js +37 -0
  314. package/dist/routes/me.js.map +1 -0
  315. package/dist/routes/metrics.d.ts +13 -0
  316. package/dist/routes/metrics.d.ts.map +1 -0
  317. package/dist/routes/metrics.js +29 -0
  318. package/dist/routes/metrics.js.map +1 -0
  319. package/dist/routes/models.d.ts +4 -0
  320. package/dist/routes/models.d.ts.map +1 -0
  321. package/dist/routes/models.js +71 -0
  322. package/dist/routes/models.js.map +1 -0
  323. package/dist/routes/notify.d.ts +4 -0
  324. package/dist/routes/notify.d.ts.map +1 -0
  325. package/dist/routes/notify.js +55 -0
  326. package/dist/routes/notify.js.map +1 -0
  327. package/dist/routes/orgs.d.ts +4 -0
  328. package/dist/routes/orgs.d.ts.map +1 -0
  329. package/dist/routes/orgs.js +73 -0
  330. package/dist/routes/orgs.js.map +1 -0
  331. package/dist/routes/projects.d.ts +4 -0
  332. package/dist/routes/projects.d.ts.map +1 -0
  333. package/dist/routes/projects.js +55 -0
  334. package/dist/routes/projects.js.map +1 -0
  335. package/dist/routes/shares.d.ts +11 -0
  336. package/dist/routes/shares.d.ts.map +1 -0
  337. package/dist/routes/shares.js +61 -0
  338. package/dist/routes/shares.js.map +1 -0
  339. package/dist/scale-exec.d.ts +11 -0
  340. package/dist/scale-exec.d.ts.map +1 -0
  341. package/dist/scale-exec.js +26 -0
  342. package/dist/scale-exec.js.map +1 -0
  343. package/dist/server.d.ts +15 -0
  344. package/dist/server.d.ts.map +1 -0
  345. package/dist/server.js +126 -0
  346. package/dist/server.js.map +1 -0
  347. package/dist/settle.d.ts +26 -0
  348. package/dist/settle.d.ts.map +1 -0
  349. package/dist/settle.js +85 -0
  350. package/dist/settle.js.map +1 -0
  351. package/package.json +76 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scale-exec.d.ts","sourceRoot":"","sources":["../src/scale-exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAc,KAAK,SAAS,EAAe,MAAM,sBAAsB,CAAC;AAC9F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAK5C,yDAAyD;AACzD,eAAO,MAAM,QAAQ,MAAO,SAAS,KAAG,SAA2F,CAAC;AAEpI,gHAAgH;AAChH,wBAAsB,kBAAkB,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/G;AAED,6HAA6H;AAC7H,wBAAgB,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,QAAQ,CAQ1G;AAED,2GAA2G;AAC3G,wBAAsB,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMzG"}
@@ -0,0 +1,26 @@
1
+ import { PG_DIALECT, sqlExecutor } from "@wizeworks/lens-core";
2
+ import { getTrace } from "./repo/trace-read.js";
3
+ const DAY_MS = 86_400_000;
4
+ /** Reads for the SQL executor, on the cloud database. */
5
+ export const pgRunner = (q) => ({ all: (sql, params) => q.query(sql, [...params]) });
6
+ /** How long a project's organization keeps data, in ms; `fallbackDays` when the project has no organization. */
7
+ export async function projectRetentionMs(q, projectId, fallbackDays) {
8
+ const [row] = await q.query("SELECT o.retention_days AS d FROM projects p JOIN orgs o ON o.id = p.org_id WHERE p.id = $1", [projectId]);
9
+ return (row?.d ?? fallbackDays) * DAY_MS;
10
+ }
11
+ /** Page needs from a project's stats tables, optionally one environment. The 1 h tier keeps the organization's retention. */
12
+ export function cloudExecutor(q, projectId, retentionMs, env) {
13
+ return sqlExecutor({
14
+ d: PG_DIALECT,
15
+ run: pgRunner(q),
16
+ scope: { project: projectId, env },
17
+ retentionMs,
18
+ loadTrace: async (id) => (await getTrace(q, projectId, id)) ?? null,
19
+ });
20
+ }
21
+ /** Traces of a project still waiting for their stats, for `pageContext(..., settling)`. Null when none. */
22
+ export async function cloudSettling(q, projectId, env) {
23
+ const [row] = await q.query("SELECT count(*)::int AS n FROM traces WHERE project_id = $1 AND settled_ms < updated_ms AND ($2::text = '' OR env = $2::text)", [projectId, env ?? ""]);
24
+ return row?.n || null;
25
+ }
26
+ //# sourceMappingURL=scale-exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scale-exec.js","sourceRoot":"","sources":["../src/scale-exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,UAAU,EAAkB,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE9F,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,MAAM,GAAG,UAAU,CAAC;AAE1B,yDAAyD;AACzD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAY,EAAa,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAA0B,GAAG,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;AAEpI,gHAAgH;AAChH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,CAAY,EAAE,SAAiB,EAAE,YAAoB;IAC5F,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,KAAK,CAAgB,6FAA6F,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IACvJ,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,YAAY,CAAC,GAAG,MAAM,CAAC;AAC3C,CAAC;AAED,6HAA6H;AAC7H,MAAM,UAAU,aAAa,CAAC,CAAY,EAAE,SAAiB,EAAE,WAAmB,EAAE,GAAY;IAC9F,OAAO,WAAW,CAAC;QACjB,CAAC,EAAE,UAAU;QACb,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;QAChB,KAAK,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE;QAClC,WAAW;QACX,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI;KACpE,CAAC,CAAC;AACL,CAAC;AAED,2GAA2G;AAC3G,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,CAAY,EAAE,SAAiB,EAAE,GAAY;IAC/E,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,KAAK,CACzB,+HAA+H,EAC/H,CAAC,SAAS,EAAE,GAAG,IAAI,EAAE,CAAC,CACvB,CAAC;IACF,OAAO,GAAG,EAAE,CAAC,IAAI,IAAI,CAAC;AACxB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { type Server } from "node:http";
2
+ import type { CloudApp } from "./app.js";
3
+ import { type CloudOptions } from "./config.js";
4
+ export declare const CLOUD_VERSION: string;
5
+ export interface Cloud {
6
+ readonly server: Server;
7
+ readonly app: CloudApp;
8
+ listen(): Promise<string>;
9
+ /** The link that makes the first account, while no account exists. */
10
+ setupLink(): string | null;
11
+ close(): Promise<void>;
12
+ }
13
+ /** Open the database, bring its schema up to date, and build the server. Call `listen()` to start. */
14
+ export declare function createCloud(options?: CloudOptions): Promise<Cloud>;
15
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAsC,KAAK,MAAM,EAAuB,MAAM,WAAW,CAAC;AAIjG,OAAO,KAAK,EAAE,QAAQ,EAAO,MAAM,UAAU,CAAC;AAK9C,OAAO,EAAE,KAAK,YAAY,EAAiB,MAAM,aAAa,CAAC;AAgB/D,eAAO,MAAM,aAAa,EAAE,MAAoE,CAAC;AAGjG,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC;IACvB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1B,sEAAsE;IACtE,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAiDD,sGAAsG;AACtG,wBAAsB,WAAW,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,KAAK,CAAC,CAiD5E"}
package/dist/server.js ADDED
@@ -0,0 +1,126 @@
1
+ import { createRequire } from "node:module";
2
+ import { createServer } from "node:http";
3
+ import { otlpSignalOf } from "@wizeworks/lens-hub/kit";
4
+ import { resolveUiDir, serveUi } from "@wizeworks/lens-node/kit";
5
+ import { authHandler } from "./auth/bridge.js";
6
+ import { AUTH_BASE_PATH } from "./auth/options.js";
7
+ import { wireAuth } from "./auth/wire.js";
8
+ import { resolveConfig } from "./config.js";
9
+ import { openDb } from "./db/db.js";
10
+ import { migrate } from "./db/migrate.js";
11
+ import { HttpError, sendJson } from "./http/http.js";
12
+ import { RateLimiter } from "./http/limiter.js";
13
+ import { Router } from "./http/router.js";
14
+ import { startJobs } from "./jobs.js";
15
+ import { createMailer } from "./mail/mailer.js";
16
+ import { stopRoute } from "./mail/stop-route.js";
17
+ import { UNSUBSCRIBE_PATH } from "./mail/unsubscribe.js";
18
+ import { RESEND_WEBHOOK_PATH, resendWebhook } from "./mail/webhook.js";
19
+ import { checkFactsVersion } from "./settle.js";
20
+ import { allRoutes } from "./routes/index.js";
21
+ import { ingestBatch, ingestOtlp } from "./routes/ingest.js";
22
+ const require = createRequire(import.meta.url);
23
+ export const CLOUD_VERSION = require("../package.json").version;
24
+ const BASE = "/_wizelens";
25
+ /** Changes from a browser must carry the dashboard header, so a page on another site cannot send them. */
26
+ const needsClientHeader = (req, sub) => req.method !== "GET" && req.method !== "HEAD" && !req.headers.authorization && sub.startsWith("api/") && sub !== "api/ingest";
27
+ async function routeBase(p, ctx, sub) {
28
+ const { req, res } = ctx;
29
+ if (sub === "api/ingest" && req.method === "POST")
30
+ return ingestBatch(ctx, p.ingest);
31
+ // Resend signs its webhook, so it needs no dashboard header.
32
+ if (sub === RESEND_WEBHOOK_PATH && req.method === "POST")
33
+ return resendWebhook(ctx);
34
+ // Stop links come from mail apps (RFC 8058 one-click POST), with the signed token as the only proof.
35
+ if (sub === UNSUBSCRIBE_PATH && (req.method === "GET" || req.method === "POST"))
36
+ return stopRoute(ctx);
37
+ if (needsClientHeader(req, sub) && req.headers["x-wizelens-client"] !== "dashboard")
38
+ throw new HttpError(403, "Missing the X-WizeLens-Client header.");
39
+ const m = p.router.match(req.method ?? "GET", sub);
40
+ if (m)
41
+ return m.handler({ ...ctx, params: m.params });
42
+ if (sub.startsWith("api/") || sub === "mcp")
43
+ throw new HttpError(p.router.hasPath(sub) ? 405 : 404, "Not found.");
44
+ if (req.method !== "GET" && req.method !== "HEAD")
45
+ return void res.writeHead(405).end();
46
+ await serveUi(p.uiDir, sub, res);
47
+ }
48
+ async function route(p, req, res) {
49
+ const url = new URL(req.url ?? "/", "http://cloud.local");
50
+ const path = url.pathname;
51
+ const ctx = { req, res, url, params: {}, app: p.app };
52
+ if (path === "/healthz")
53
+ return void res.writeHead(200, { "Content-Type": "text/plain" }).end("ok");
54
+ if (path === "/" || path === BASE)
55
+ return void res.writeHead(302, { Location: `${BASE}/${url.search}` }).end();
56
+ if (path.startsWith(`${AUTH_BASE_PATH}/`))
57
+ return p.auth()(req, res);
58
+ const signal = otlpSignalOf(path);
59
+ if (signal && req.method === "POST")
60
+ return ingestOtlp(ctx, signal, p.ingest);
61
+ if (path.startsWith(`${BASE}/`))
62
+ return routeBase(p, ctx, path.slice(BASE.length + 1));
63
+ sendJson(res, 404, { error: "Not found." });
64
+ }
65
+ function onError(err, res) {
66
+ if (res.headersSent)
67
+ return void res.end();
68
+ if (err instanceof HttpError)
69
+ return sendJson(res, err.status, { error: err.message });
70
+ console.error("[wizelens-cloud]", err);
71
+ sendJson(res, 500, { error: "Something went wrong on the server." });
72
+ }
73
+ /** Open the database, bring its schema up to date, and build the server. Call `listen()` to start. */
74
+ export async function createCloud(options = {}) {
75
+ const config = resolveConfig(options);
76
+ const db = await openDb(config.database);
77
+ await migrate(db);
78
+ await checkFactsVersion(db);
79
+ const mailer = await createMailer(config, db);
80
+ const wiring = await wireAuth(db, config, mailer);
81
+ let auth;
82
+ let handler;
83
+ let listenUrl = config.publicUrl ?? `http://localhost:${config.port}`;
84
+ const app = {
85
+ db,
86
+ config,
87
+ version: CLOUD_VERSION,
88
+ startedMs: config.now(),
89
+ mailer,
90
+ secrets: wiring.secrets,
91
+ get auth() {
92
+ if (!auth)
93
+ throw new Error("The cloud is not listening yet.");
94
+ return auth;
95
+ },
96
+ baseUrl: () => config.publicUrl ?? listenUrl,
97
+ };
98
+ const ready = (url) => ((listenUrl = url), (auth = wiring.start(url)), (handler = authHandler(auth, config.trustProxy)));
99
+ if (config.publicUrl)
100
+ ready(config.publicUrl);
101
+ const parts = { app, router: allRoutes(), ingest: new RateLimiter(config.ingestPerMinute, 60_000, config.now), uiDir: resolveUiDir(config.uiDir), auth: () => handler };
102
+ const server = createServer((req, res) => void route(parts, req, res).catch((err) => onError(err, res)));
103
+ const stopJobs = config.jobs ? startJobs(app) : () => { };
104
+ return {
105
+ server,
106
+ app,
107
+ setupLink: wiring.setupLink,
108
+ listen: () => new Promise((resolve, reject) => {
109
+ server.once("error", reject);
110
+ server.listen(config.port, config.host, () => {
111
+ const { port } = server.address();
112
+ if (!config.publicUrl)
113
+ ready(`http://localhost:${port}`);
114
+ resolve(config.publicUrl ?? `http://localhost:${port}`);
115
+ });
116
+ }),
117
+ close: async () => {
118
+ stopJobs();
119
+ server.closeAllConnections?.();
120
+ await new Promise((resolve) => server.close(() => resolve()));
121
+ await mailer.close();
122
+ await db.close();
123
+ },
124
+ };
125
+ }
126
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { type Statement, type TraceState } from "@wizeworks/lens-core";
2
+ import type { Db, Queryable } from "./db/db.js";
3
+ /** Fact, rollup, and hist tables: everything settling builds. */
4
+ export declare const STATS_TABLES: string[];
5
+ export interface TraceStateRow {
6
+ project_id: string;
7
+ trace_id: string;
8
+ env: string;
9
+ updated_ms?: number;
10
+ contrib: string | null;
11
+ retention_days: number | null;
12
+ }
13
+ /** Run statements one by one, in the caller's transaction. */
14
+ export declare function runStatements(q: Queryable, statements: readonly Statement[]): Promise<void>;
15
+ export declare const stateOf: (r: TraceStateRow, defaultDays: number) => TraceState;
16
+ /** Settle dirty traces in batches until none are left or the budget is spent. Returns how many settled. */
17
+ export declare function settleCloud(db: Db, now: number, o?: {
18
+ defaultRetentionDays?: number;
19
+ batch?: number;
20
+ budgetMs?: number;
21
+ }): Promise<number>;
22
+ /** Age out rollup buckets: 10 s and 5 min by their keep time, 1 h by each organization's retention. */
23
+ export declare function pruneRollups(q: Queryable, now: number, empties?: boolean): Promise<void>;
24
+ /** On startup: when the facts version changed, clear the stats so settling rebuilds them. Returns true when it did. */
25
+ export declare function checkFactsVersion(db: Db): Promise<boolean>;
26
+ //# sourceMappingURL=settle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settle.d.ts","sourceRoot":"","sources":["../src/settle.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4D,KAAK,SAAS,EAAuB,KAAK,UAAU,EAAc,MAAM,sBAAsB,CAAC;AAClK,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAUhD,iEAAiE;AACjE,eAAO,MAAM,YAAY,UAAwF,CAAC;AAElH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,8DAA8D;AAC9D,wBAAsB,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjG;AAED,eAAO,MAAM,OAAO,MAAO,aAAa,eAAe,MAAM,KAAG,UAO9D,CAAC;AA6BH,2GAA2G;AAC3G,wBAAsB,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,GAAE;IAAE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CASpJ;AAED,uGAAuG;AACvG,wBAAsB,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ5F;AAED,uHAAuH;AACvH,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAShE"}
package/dist/settle.js ADDED
@@ -0,0 +1,85 @@
1
+ import { FACT_TABLES, FACTS_VERSION, PG_DIALECT, settleStatements, tierPruneStatements } from "@wizeworks/lens-core";
2
+ import { loadTraces } from "./repo/trace-read.js";
3
+ // Settling: traces quiet for a while get their facts and rollups rebuilt from the stored spans and logs (docs/CONTRACT.md).
4
+ const BATCH = 500;
5
+ const BUDGET_MS = 2_000;
6
+ const QUIET_MS = 5_000;
7
+ const BUSY_MS = 30_000;
8
+ const LOCK = 4711;
9
+ const DAY_MS = 86_400_000;
10
+ /** Fact, rollup, and hist tables: everything settling builds. */
11
+ export const STATS_TABLES = [...FACT_TABLES, ...["10s", "5m", "1h"].flatMap((t) => [`rollup_${t}`, `hist_${t}`])];
12
+ /** Run statements one by one, in the caller's transaction. */
13
+ export async function runStatements(q, statements) {
14
+ for (const s of statements)
15
+ await q.query(s.sql, s.params);
16
+ }
17
+ export const stateOf = (r, defaultDays) => ({
18
+ traceId: r.trace_id,
19
+ project: r.project_id,
20
+ env: r.env,
21
+ updatedMs: r.updated_ms ?? 0,
22
+ contrib: r.contrib,
23
+ retentionMs: (r.retention_days ?? defaultDays) * DAY_MS,
24
+ });
25
+ async function loadAll(q, rows) {
26
+ const byProject = new Map();
27
+ for (const r of rows)
28
+ byProject.set(r.project_id, [...(byProject.get(r.project_id) ?? []), r.trace_id]);
29
+ const out = new Map();
30
+ for (const [project, ids] of byProject)
31
+ for (const t of await loadTraces(q, project, ids))
32
+ out.set(`${project} ${t.traceId}`, t);
33
+ return out;
34
+ }
35
+ /** Settle one batch in one transaction. -1 when another instance holds the lock. */
36
+ async function settleBatch(db, now, batch, defaultDays) {
37
+ return db.tx(async (q) => {
38
+ const [lock] = await q.query("SELECT pg_try_advisory_xact_lock($1) AS ok", [LOCK]);
39
+ if (!lock?.ok)
40
+ return -1;
41
+ const rows = await q.query(`SELECT t.project_id, t.trace_id, t.env, t.updated_ms, t.contrib, o.retention_days FROM traces t
42
+ LEFT JOIN projects p ON p.id = t.project_id LEFT JOIN orgs o ON o.id = p.org_id
43
+ WHERE t.settled_ms < t.updated_ms AND (t.updated_ms <= $1 OR t.settled_ms <= $2) ORDER BY t.start_ms DESC LIMIT $3`, [now - QUIET_MS, now - BUSY_MS, batch]);
44
+ if (!rows.length)
45
+ return 0;
46
+ const traces = await loadAll(q, rows);
47
+ const work = rows.map((r) => ({ state: stateOf(r, defaultDays), trace: traces.get(`${r.project_id} ${r.trace_id}`) }));
48
+ await runStatements(q, settleStatements(PG_DIALECT, work, now, true));
49
+ return rows.length;
50
+ });
51
+ }
52
+ /** Settle dirty traces in batches until none are left or the budget is spent. Returns how many settled. */
53
+ export async function settleCloud(db, now, o = {}) {
54
+ const start = Date.now();
55
+ const batch = o.batch ?? BATCH;
56
+ let total = 0;
57
+ for (;;) {
58
+ const n = await settleBatch(db, now, batch, o.defaultRetentionDays ?? 30);
59
+ if (n > 0)
60
+ total += n;
61
+ if (n < batch || Date.now() - start >= (o.budgetMs ?? BUDGET_MS))
62
+ return total;
63
+ }
64
+ }
65
+ /** Age out rollup buckets: 10 s and 5 min by their keep time, 1 h by each organization's retention. */
66
+ export async function pruneRollups(q, now, empties = false) {
67
+ await runStatements(q, tierPruneStatements(now, empties));
68
+ for (const t of ["rollup_1h", "hist_1h"]) {
69
+ await q.query(`DELETE FROM ${t} r USING projects p, orgs o WHERE p.id = r.project_id AND o.id = p.org_id AND r.bucket_ms <= $1 - o.retention_days * 86400000.0`, [now - 3_600_000]);
70
+ }
71
+ }
72
+ /** On startup: when the facts version changed, clear the stats so settling rebuilds them. Returns true when it did. */
73
+ export async function checkFactsVersion(db) {
74
+ const [row] = await db.query("SELECT value FROM scale_meta WHERE key = 'facts'");
75
+ if (row?.value === String(FACTS_VERSION))
76
+ return false;
77
+ await db.tx(async (q) => {
78
+ for (const t of STATS_TABLES)
79
+ await q.query(`DELETE FROM ${t}`);
80
+ await q.query("UPDATE traces SET settled_ms = 0, contrib = NULL");
81
+ await q.query("INSERT INTO scale_meta (key, value) VALUES ('facts', $1) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value", [String(FACTS_VERSION)]);
82
+ });
83
+ return true;
84
+ }
85
+ //# sourceMappingURL=settle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settle.js","sourceRoot":"","sources":["../src/settle.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,79 @@
1
1
  {
2
2
  "name": "@wizeworks/lens-cloud",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.3.0-alpha.2",
4
+ "description": "The WizeLens cloud service: many organizations, accounts and teams, server-side stats, alerts, sharing, and scoped AI access, on Postgres.",
5
+ "license": "MIT",
6
+ "author": "WizeWorks LLC",
7
+ "homepage": "https://github.com/brandonkorous/wizelens#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/brandonkorous/wizelens.git",
11
+ "directory": "js/packages/cloud"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/brandonkorous/wizelens/issues"
15
+ },
16
+ "keywords": [
17
+ "wizelens",
18
+ "cloud",
19
+ "tracing",
20
+ "opentelemetry",
21
+ "otlp",
22
+ "profiler",
23
+ "postgres"
24
+ ],
25
+ "type": "module",
26
+ "main": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "bin": {
29
+ "wizelens-cloud": "./dist/cli.js"
30
+ },
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.ts",
34
+ "import": "./dist/index.js"
35
+ },
36
+ "./package.json": "./package.json"
37
+ },
38
+ "files": [
39
+ "dist"
40
+ ],
41
+ "engines": {
42
+ "node": ">=22.13"
43
+ },
44
+ "dependencies": {
45
+ "@better-auth/passkey": "1.7.10",
46
+ "@better-auth/sso": "1.7.10",
47
+ "@electric-sql/pglite": "^0.5.10",
48
+ "@react-email/components": "1.0.12",
49
+ "better-auth": "1.7.10",
50
+ "kysely": "^0.29.6",
51
+ "kysely-pglite-dialect": "^1.4.0",
52
+ "nodemailer": "^10.1.2",
53
+ "pg": "^8.23.1",
54
+ "react": "^19.3.1",
55
+ "react-dom": "^19.3.1",
56
+ "@wizeworks/lens-core": "^0.3.0-alpha.2",
57
+ "@wizeworks/lens-hub": "^0.3.0-alpha.2",
58
+ "@wizeworks/lens-ui": "^0.3.0-alpha.2",
59
+ "@wizeworks/lens-node": "^0.3.0-alpha.2"
60
+ },
61
+ "devDependencies": {
62
+ "@types/node": "^24.19.2",
63
+ "@types/nodemailer": "^8.0.2",
64
+ "@types/pg": "^8.23.1",
65
+ "@types/react": "^19.3.0",
66
+ "@types/react-dom": "^19.3.0",
67
+ "typescript": "^7.0.2",
68
+ "vitest": "^5.0.5"
69
+ },
70
+ "publishConfig": {
71
+ "access": "public"
72
+ },
73
+ "scripts": {
74
+ "build": "tsc -p tsconfig.build.json",
75
+ "test": "vitest run",
76
+ "start": "node dist/cli.js",
77
+ "email:preview": "node dist/mail/preview.js"
78
+ }
6
79
  }