@mason-data/cli 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +101 -73
  2. package/dist/src/api/error.js +3 -0
  3. package/dist/src/api/postgres/catalog-worker.js +49 -2
  4. package/dist/src/api/postgres/catalog.js +368 -25
  5. package/dist/src/api/postgres/encode.js +3 -1
  6. package/dist/src/api/postgres/explain.js +3 -2
  7. package/dist/src/api/postgres/listener.js +11 -3
  8. package/dist/src/api/postgres/protocol.js +39 -23
  9. package/dist/src/api/postgres/proxy.js +283 -0
  10. package/dist/src/api/postgres/schema.js +6 -0
  11. package/dist/src/api/postgres/server.js +1617 -245
  12. package/dist/src/api/postgres/translate.js +127 -10
  13. package/dist/src/api/request-log.js +18 -5
  14. package/dist/src/cdc/poll.js +5 -5
  15. package/dist/src/cli/background.js +47 -25
  16. package/dist/src/cli/bridge-stdin.js +101 -0
  17. package/dist/src/cli/cancel.js +75 -0
  18. package/dist/src/cli/command.js +170 -11
  19. package/dist/src/cli/commands.js +804 -209
  20. package/dist/src/cli/control.js +59 -0
  21. package/dist/src/cli/credentials.js +182 -0
  22. package/dist/src/cli/demo.js +20 -11
  23. package/dist/src/cli/deploy.js +574 -0
  24. package/dist/src/cli/dev.js +491 -130
  25. package/dist/src/cli/doctor.js +131 -38
  26. package/dist/src/cli/generated-files.js +143 -0
  27. package/dist/src/cli/guides.js +175 -36
  28. package/dist/src/cli/hosted.js +850 -0
  29. package/dist/src/cli/init.js +162 -65
  30. package/dist/src/cli/login.js +289 -0
  31. package/dist/src/cli/machine.js +13 -12
  32. package/dist/src/cli/main.js +11 -5
  33. package/dist/src/cli/mason.cjs +17 -0
  34. package/dist/src/cli/mcp.js +31 -22
  35. package/dist/src/cli/metrics.js +79 -0
  36. package/dist/src/cli/output-gate.js +176 -0
  37. package/dist/src/cli/page-share.js +96 -0
  38. package/dist/src/cli/pg-tls.js +14 -4
  39. package/dist/src/cli/pg-url.js +4 -0
  40. package/dist/src/cli/pin.js +19 -14
  41. package/dist/src/cli/pool-size.cjs +85 -0
  42. package/dist/src/cli/ports.js +2 -0
  43. package/dist/src/cli/preflight.js +138 -46
  44. package/dist/src/cli/project.js +142 -4
  45. package/dist/src/cli/readiness.js +76 -6
  46. package/dist/src/cli/registry.js +65 -38
  47. package/dist/src/cli/replica-hosted.js +665 -0
  48. package/dist/src/cli/replica.js +76 -0
  49. package/dist/src/cli/replication-checks.js +7 -5
  50. package/dist/src/cli/replication-mode.js +105 -26
  51. package/dist/src/cli/request-filter.js +134 -0
  52. package/dist/src/cli/roles.js +585 -0
  53. package/dist/src/cli/run-server.js +637 -48
  54. package/dist/src/cli/runs.js +1 -1
  55. package/dist/src/cli/security.js +67 -18
  56. package/dist/src/cli/serve.js +204 -46
  57. package/dist/src/cli/share-run.js +329 -0
  58. package/dist/src/cli/share.js +286 -0
  59. package/dist/src/cli/source-edit.js +75 -17
  60. package/dist/src/cli/source-role.js +344 -0
  61. package/dist/src/cli/sources.js +306 -47
  62. package/dist/src/cli/style.js +2 -1
  63. package/dist/src/cli/supervise.js +27 -24
  64. package/dist/src/cli/sync.js +55 -25
  65. package/dist/src/cli/token-hosted.js +337 -0
  66. package/dist/src/cli/tunnel.js +200 -0
  67. package/dist/src/cli/ui-ssh.js +460 -0
  68. package/dist/src/cli/ui.js +124 -17
  69. package/dist/src/cli/usage.js +128 -0
  70. package/dist/src/cli/user-hosted.js +299 -0
  71. package/dist/src/cli/user.js +573 -65
  72. package/dist/src/cli/version.js +9 -7
  73. package/dist/src/demo/seed.js +29 -0
  74. package/dist/src/duck/analyze.js +36 -20
  75. package/dist/src/duck/cancel.js +10 -1
  76. package/dist/src/duck/collation.js +266 -0
  77. package/dist/src/duck/constant-key.js +94 -0
  78. package/dist/src/duck/distinct-key.js +283 -26
  79. package/dist/src/duck/events.js +165 -0
  80. package/dist/src/duck/executor-worker.js +20 -11
  81. package/dist/src/duck/executor.js +47 -33
  82. package/dist/src/duck/explain.js +60 -46
  83. package/dist/src/duck/extensions.js +160 -0
  84. package/dist/src/duck/functions.js +461 -63
  85. package/dist/src/duck/gaps.js +48 -21
  86. package/dist/src/duck/generated-plan.js +1070 -0
  87. package/dist/src/duck/generated.js +906 -0
  88. package/dist/src/duck/grants.js +176 -0
  89. package/dist/src/duck/held-types.js +64 -0
  90. package/dist/src/duck/history.js +127 -0
  91. package/dist/src/duck/jsonb-order.js +9 -12
  92. package/dist/src/duck/kept-route.js +6 -5
  93. package/dist/src/duck/kept.js +15 -13
  94. package/dist/src/duck/late.js +1469 -40
  95. package/dist/src/duck/libc-bound.js +341 -0
  96. package/dist/src/duck/libc-order.js +892 -126
  97. package/dist/src/duck/pg-eval-worker.js +7 -1
  98. package/dist/src/duck/pg-eval.js +6 -4
  99. package/dist/src/duck/pgtree.js +774 -23
  100. package/dist/src/duck/plan.js +369 -47
  101. package/dist/src/duck/publication.js +20 -6
  102. package/dist/src/duck/requests.js +269 -93
  103. package/dist/src/duck/resolved.js +117 -2
  104. package/dist/src/duck/rewrite.js +4584 -580
  105. package/dist/src/duck/row-filter.js +655 -0
  106. package/dist/src/duck/statement.js +19 -0
  107. package/dist/src/duck/store.js +439 -177
  108. package/dist/src/duck/stream.js +19 -10
  109. package/dist/src/duck/sync.js +1411 -368
  110. package/dist/src/duck/token.js +4 -1
  111. package/dist/src/duck/types.js +69 -12
  112. package/dist/src/duck/usage.js +326 -0
  113. package/dist/src/duck/users.js +69 -15
  114. package/dist/src/duck/verified.js +161 -1
  115. package/dist/src/duck/views.js +5 -5
  116. package/dist/src/lib/database-name.js +62 -0
  117. package/dist/src/lib/database-url.js +55 -10
  118. package/dist/src/lib/dotenv.js +17 -4
  119. package/dist/src/lib/instant.js +50 -0
  120. package/dist/src/lib/log-buffer.js +77 -0
  121. package/dist/src/lib/log-read.js +196 -0
  122. package/dist/src/lib/pg-numeric.js +390 -49
  123. package/dist/src/lib/project-version.js +23 -23
  124. package/dist/src/lib/secret-mask.js +142 -0
  125. package/dist/src/lib/table-sync.js +282 -0
  126. package/dist/src/web/app.css +706 -66
  127. package/dist/src/web/app.js +331 -409
  128. package/dist/src/web/charts.js +229 -0
  129. package/dist/src/web/index.html +82 -18
  130. package/dist/src/web/pages/queries.js +192 -0
  131. package/dist/src/web/pages/status.js +611 -0
  132. package/dist/src/web/pages/syncs.js +155 -0
  133. package/dist/src/web/pages/tables.js +439 -0
  134. package/dist/src/web/pages/usage.js +397 -0
  135. package/dist/src/web/pages/users.js +219 -0
  136. package/dist/src/web/shared.js +584 -0
  137. package/dist/src/web/vendor/README.md +25 -0
  138. package/dist/src/web/vendor/geist-1.7.2/Geist-Variable.woff2 +0 -0
  139. package/dist/src/web/vendor/geist-1.7.2/GeistMono-Variable.woff2 +0 -0
  140. package/dist/src/web/vendor/geist-1.7.2/LICENSE.txt +92 -0
  141. package/dist/src/web/vendor/lucide-1.56.0/LICENSE.txt +43 -0
  142. package/dist/src/web/vendor/lucide-1.56.0/chart-column.mjs +29 -0
  143. package/dist/src/web/vendor/lucide-1.56.0/layout-dashboard.mjs +29 -0
  144. package/dist/src/web/vendor/lucide-1.56.0/logs.mjs +34 -0
  145. package/dist/src/web/vendor/lucide-1.56.0/menu.mjs +28 -0
  146. package/dist/src/web/vendor/lucide-1.56.0/square-terminal.mjs +28 -0
  147. package/dist/src/web/vendor/lucide-1.56.0/table.mjs +29 -0
  148. package/dist/src/web/vendor/lucide-1.56.0/users.mjs +29 -0
  149. package/dist/src/web/vendor/lucide-1.56.0/x.mjs +27 -0
  150. package/dist/src/web/vendor/uplot-1.6.32/LICENSE.txt +21 -0
  151. package/dist/src/web/vendor/uplot-1.6.32/uPlot.esm.js +6140 -0
  152. package/dist/src/web/vendor/uplot-1.6.32/uPlot.min.css +1 -0
  153. package/dist/src/web/vendor/zilla-slab-5.3.0/LICENSE.txt +93 -0
  154. package/dist/src/web/vendor/zilla-slab-5.3.0/zilla-slab-latin-700-normal.woff2 +0 -0
  155. package/package.json +12 -4
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * THE DUCKDB COPY KEPT CURRENT BY LOGICAL REPLICATION (replication for the DuckDB case, only to sync the copied tables).
3
- * `mason start --replication` on Mason's own publication and
3
+ * The tables whose `sync:` is `replication`, on Mason's own publication (or the one the sources file names) and
4
4
  * slot on the developer's database (src/cli/replication-mode.ts), the slot's `pgoutput` stream (src/cdc/pgoutput.ts,
5
5
  * over src/cdc/pg-wire.ts) applied to the copied tables (src/duck/sync.ts `applyChanges`) instead of polling them.
6
6
  *
@@ -45,6 +45,7 @@
45
45
  * unchanged-TOAST update) whose earlier row went in an earlier piece is applied as an UPDATE of the columns it carries,
46
46
  * as one whose row the copy holds always is.
47
47
  */
48
+ import { errorText, messageOf } from "../lib/secret-mask.js";
48
49
  import { decode } from "../cdc/pgoutput.js";
49
50
  import { PgConnection, formatLsn, pgIdent, pgLiteral } from "../cdc/pg-wire.js";
50
51
  const lit = (s) => `'${s.replace(/'/g, "''")}'`;
@@ -187,7 +188,7 @@ export function countsText(c) {
187
188
  return `${n(total)} change${total === 1 ? "" : "s"}${parts.length ? ` (${parts.join(", ")})` : ""}`;
188
189
  }
189
190
  /** a table's changes, none yet */
190
- export const noChanges = (columns = null) => ({ columns, truncated: false, keys: new Map(), counts: noCounts() });
191
+ export const noChanges = (stay = null) => ({ stay, truncated: false, keys: new Map(), counts: noCounts() });
191
192
  /** The change folded into what the batch holds for its key: a later whole row or delete replaces it, a later partial
192
193
  * row keeps the earlier row's values where it carries none. */
193
194
  export function fold(t, key, change) {
@@ -217,7 +218,7 @@ export function fold(t, key, change) {
217
218
  */
218
219
  export const PIECE_CHANGES = 10_000;
219
220
  /**
220
- * A BATCH THAT CHANGES A BIG TABLE (one over src/duck/sync.ts POLL_ROW_LIMIT, `big` in `StreamTarget.tables`) is
221
+ * A BATCH THAT CHANGES A BIG TABLE (one over src/lib/table-sync.ts BIG_TABLE_ROWS, `big` in `StreamTarget.tables`) is
221
222
  * applied at most every `BIG_APPLY_MS`, and a transaction's piece holds up to `BIG_PIECE_CHANGES`: each application
222
223
  * scans that table's key column (`PIECE_CHANGES` says what that costs), so fewer, larger ones — a 12 M-row migration is
223
224
  * 240 scans where it would be 1,200. The other tables in such a batch wait with it (seconds of staleness, said in
@@ -234,7 +235,7 @@ export function applySize(big, flushMs, flushRows) {
234
235
  /** A later batch's changes of a table folded into what is held of it (Sync `catchUp`): what they mean once applied in
235
236
  * commit order after it, as `fold` does within a batch */
236
237
  export function foldInto(held, later) {
237
- held.columns ??= later.columns;
238
+ held.stay ??= later.stay;
238
239
  if (later.truncated) {
239
240
  held.truncated = true;
240
241
  held.keys.clear();
@@ -262,6 +263,7 @@ export class ReplicationStream {
262
263
  publication;
263
264
  target;
264
265
  log;
266
+ errorText;
265
267
  flushMs;
266
268
  flushRows;
267
269
  constructor(o) {
@@ -270,6 +272,7 @@ export class ReplicationStream {
270
272
  this.publication = o.publication;
271
273
  this.target = o.target;
272
274
  this.log = o.log;
275
+ this.errorText = o.errorText ?? ((e) => errorText(e));
273
276
  this.flushMs = o.flushMs ?? 500;
274
277
  this.flushRows = o.flushRows ?? PIECE_CHANGES;
275
278
  this.acked = this.target.applied();
@@ -289,7 +292,7 @@ export class ReplicationStream {
289
292
  this.repl?.sendStatus(this.acked, true);
290
293
  }
291
294
  catch (e) {
292
- this.log(`replication: could not ask the source for its position (${e.message})`);
295
+ this.log(`replication: could not ask the source for its position (${this.errorText(e)})`);
293
296
  }
294
297
  }
295
298
  async run() {
@@ -302,7 +305,7 @@ export class ReplicationStream {
302
305
  if (this.stopping)
303
306
  break;
304
307
  const wait = Math.min(30_000, 1_000 * 2 ** Math.min(attempts++, 5));
305
- this.log(`replication: the source is away (${e.message}); trying again in ${wait / 1000} s`);
308
+ this.log(`replication: the source is away (${this.errorText(e)}); trying again in ${wait / 1000} s`);
306
309
  await new Promise((r) => setTimeout(r, wait));
307
310
  continue;
308
311
  }
@@ -329,7 +332,7 @@ export class ReplicationStream {
329
332
  this.repl = null;
330
333
  return e;
331
334
  }
332
- this.log(`replication: the source went away (${e.message}); reconnecting`);
335
+ this.log(`replication: the source went away (${this.errorText(e)}); reconnecting`);
333
336
  }
334
337
  finally {
335
338
  this.repl?.close();
@@ -367,6 +370,7 @@ export class ReplicationStream {
367
370
  firstAt = 0;
368
371
  pieces = 0;
369
372
  big = false;
373
+ this.target.current?.();
370
374
  };
371
375
  // a piece of the open transaction: applied and committed, the position left where it is
372
376
  const piece = async () => {
@@ -386,7 +390,7 @@ export class ReplicationStream {
386
390
  repl.sendStatus(this.acked, true);
387
391
  }
388
392
  catch (e) {
389
- this.log(`replication: the status update could not be sent (${e.message})`);
393
+ this.log(`replication: the status update could not be sent (${this.errorText(e)})`);
390
394
  }
391
395
  }, 10_000);
392
396
  const command = `START_REPLICATION SLOT ${pgIdent(this.slot)} LOGICAL 0/0 (proto_version '1', publication_names ${pgLiteral(`"${this.publication.replace(/"/g, '""')}"`)})`;
@@ -402,6 +406,7 @@ export class ReplicationStream {
402
406
  this.acked = m.walEnd;
403
407
  repl.sendStatus(this.acked);
404
408
  }
409
+ this.target.current?.();
405
410
  }
406
411
  else if (m.replyRequested)
407
412
  repl.sendStatus(this.acked);
@@ -464,7 +469,10 @@ export class ReplicationStream {
464
469
  }
465
470
  if (table.big === true)
466
471
  big = true;
467
- const t = batch.get(rel.source) ?? noChanges(table.columns);
472
+ // ONE STAY A BATCH: what an ended stay left in it would be dropped at the apply (`applyStreamed`), and held
473
+ // beside these it is rows of another shape, or an old change replayed after the poll that read a newer
474
+ const open = batch.get(rel.source);
475
+ const t = open?.stay === table.stay ? open : noChanges(table.stay);
468
476
  batch.set(rel.source, t);
469
477
  txnChanges.set(rel.source, (txnChanges.get(rel.source) ?? 0) + 1);
470
478
  t.counts[msg.type === "insert" ? "inserts" : msg.type === "update" ? "updates" : msg.type === "delete" ? "deletes" : "truncates"]++;
@@ -513,6 +521,7 @@ export function pgTime(us) {
513
521
  }
514
522
  /** the source being away — closed, refused, reset, a shutdown — which a reconnect outlasts; anything else is the stream's */
515
523
  function away(e) {
516
- const m = e instanceof Error ? e.message : String(e);
524
+ // a decision: the raw words (src/lib/secret-mask.ts messageOf), never the ones Mason repeats
525
+ const m = messageOf(e);
517
526
  return /connection closed|ECONNREFUSED|ECONNRESET|EPIPE|ETIMEDOUT|timed out|terminating connection|the database system is (shutting down|starting up)|server closed|is active for PID/i.test(m);
518
527
  }