@rocicorp/zero 0.26.0-canary.0 → 0.26.0-canary.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 (138) hide show
  1. package/out/shared/src/custom-key-map.d.ts +4 -4
  2. package/out/shared/src/custom-key-map.d.ts.map +1 -1
  3. package/out/shared/src/custom-key-map.js.map +1 -1
  4. package/out/shared/src/iterables.d.ts +6 -8
  5. package/out/shared/src/iterables.d.ts.map +1 -1
  6. package/out/shared/src/iterables.js +13 -7
  7. package/out/shared/src/iterables.js.map +1 -1
  8. package/out/shared/src/options.d.ts +1 -0
  9. package/out/shared/src/options.d.ts.map +1 -1
  10. package/out/shared/src/options.js +5 -1
  11. package/out/shared/src/options.js.map +1 -1
  12. package/out/zero/package.json.js +1 -1
  13. package/out/zero/src/zero-cache-dev.js +7 -3
  14. package/out/zero/src/zero-cache-dev.js.map +1 -1
  15. package/out/zero-cache/src/config/zero-config.d.ts +10 -1
  16. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  17. package/out/zero-cache/src/config/zero-config.js +27 -7
  18. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  19. package/out/zero-cache/src/observability/events.d.ts.map +1 -1
  20. package/out/zero-cache/src/observability/events.js +15 -5
  21. package/out/zero-cache/src/observability/events.js.map +1 -1
  22. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  23. package/out/zero-cache/src/server/change-streamer.js +10 -2
  24. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  25. package/out/zero-cache/src/server/syncer.d.ts +1 -0
  26. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  27. package/out/zero-cache/src/server/syncer.js +22 -4
  28. package/out/zero-cache/src/server/syncer.js.map +1 -1
  29. package/out/zero-cache/src/services/change-source/custom/change-source.js +0 -4
  30. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  31. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
  32. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +1 -10
  33. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  34. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  35. package/out/zero-cache/src/services/change-source/pg/schema/init.js +8 -2
  36. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  37. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
  38. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +1 -14
  39. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  40. package/out/zero-cache/src/services/change-source/replica-schema.d.ts.map +1 -1
  41. package/out/zero-cache/src/services/change-source/replica-schema.js +8 -1
  42. package/out/zero-cache/src/services/change-source/replica-schema.js.map +1 -1
  43. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +1 -1
  44. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
  45. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +5 -3
  46. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  47. package/out/zero-cache/src/services/change-streamer/storer.d.ts +1 -1
  48. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  49. package/out/zero-cache/src/services/change-streamer/storer.js +16 -5
  50. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  51. package/out/zero-cache/src/services/life-cycle.d.ts +1 -1
  52. package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
  53. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  54. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  55. package/out/zero-cache/src/services/litestream/commands.js +3 -1
  56. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  57. package/out/zero-cache/src/services/litestream/config.yml +1 -0
  58. package/out/zero-cache/src/services/mutagen/mutagen.d.ts +4 -4
  59. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  60. package/out/zero-cache/src/services/mutagen/mutagen.js +9 -24
  61. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  62. package/out/zero-cache/src/services/mutagen/pusher.d.ts +1 -2
  63. package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
  64. package/out/zero-cache/src/services/mutagen/pusher.js +51 -12
  65. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  66. package/out/zero-cache/src/services/replicator/change-processor.js +4 -3
  67. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  68. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +3 -2
  69. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts.map +1 -1
  70. package/out/zero-cache/src/services/replicator/schema/change-log.js +36 -31
  71. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  72. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +5 -6
  73. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  74. package/out/zero-cache/src/services/view-syncer/client-handler.js +5 -23
  75. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  76. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  77. package/out/zero-cache/src/services/view-syncer/cvr-store.js +6 -4
  78. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  79. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +1 -8
  80. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  81. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +2 -11
  82. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  83. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +0 -2
  84. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  85. package/out/zero-cache/src/services/view-syncer/snapshotter.js +2 -10
  86. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  87. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +1 -2
  88. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  89. package/out/zero-cache/src/services/view-syncer/view-syncer.js +40 -42
  90. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  91. package/out/zero-cache/src/workers/connect-params.d.ts +0 -1
  92. package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
  93. package/out/zero-cache/src/workers/connect-params.js +0 -2
  94. package/out/zero-cache/src/workers/connect-params.js.map +1 -1
  95. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  96. package/out/zero-cache/src/workers/replicator.js +2 -5
  97. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  98. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  99. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +1 -4
  100. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  101. package/out/zero-client/src/client/context.js +1 -0
  102. package/out/zero-client/src/client/context.js.map +1 -1
  103. package/out/zero-client/src/client/options.d.ts +1 -1
  104. package/out/zero-client/src/client/options.js.map +1 -1
  105. package/out/zero-client/src/client/version.js +1 -1
  106. package/out/zero-client/src/client/zero.d.ts +2 -4
  107. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  108. package/out/zero-client/src/client/zero.js +1 -1
  109. package/out/zero-client/src/client/zero.js.map +1 -1
  110. package/out/zero-protocol/src/push.d.ts +7 -0
  111. package/out/zero-protocol/src/push.d.ts.map +1 -1
  112. package/out/zero-protocol/src/push.js +9 -1
  113. package/out/zero-protocol/src/push.js.map +1 -1
  114. package/out/zero-server/src/process-mutations.d.ts +1 -0
  115. package/out/zero-server/src/process-mutations.d.ts.map +1 -1
  116. package/out/zero-server/src/process-mutations.js +41 -2
  117. package/out/zero-server/src/process-mutations.js.map +1 -1
  118. package/out/zero-server/src/zql-database.d.ts.map +1 -1
  119. package/out/zero-server/src/zql-database.js +9 -0
  120. package/out/zero-server/src/zql-database.js.map +1 -1
  121. package/out/zero-solid/src/solid-view.js +1 -0
  122. package/out/zero-solid/src/solid-view.js.map +1 -1
  123. package/out/zero-solid/src/use-query.js +1 -0
  124. package/out/zero-solid/src/use-query.js.map +1 -1
  125. package/out/zql/src/ivm/stream.d.ts.map +1 -1
  126. package/out/zql/src/ivm/stream.js +1 -1
  127. package/out/zql/src/ivm/stream.js.map +1 -1
  128. package/out/zql/src/mutate/mutator.js +4 -4
  129. package/out/zql/src/mutate/mutator.js.map +1 -1
  130. package/out/zql/src/query/create-builder.js +3 -5
  131. package/out/zql/src/query/create-builder.js.map +1 -1
  132. package/out/zql/src/query/query-registry.js +4 -4
  133. package/out/zql/src/query/query-registry.js.map +1 -1
  134. package/package.json +3 -3
  135. package/out/zero-cache/src/types/schema-versions.d.ts +0 -12
  136. package/out/zero-cache/src/types/schema-versions.d.ts.map +0 -1
  137. package/out/zero-cache/src/types/schema-versions.js +0 -28
  138. package/out/zero-cache/src/types/schema-versions.js.map +0 -1
@@ -1,64 +1,70 @@
1
1
  import { jsonObjectSchema, parse as parse$1, stringify } from "../../../../../shared/src/bigint-json.js";
2
2
  import { literalUnion, parse } from "../../../../../shared/src/valita.js";
3
3
  import { normalizedKeyOrder } from "../../../types/row-key.js";
4
- import { object, string } from "@badrap/valita";
4
+ import { object, string, number } from "@badrap/valita";
5
5
  const SET_OP = "s";
6
6
  const DEL_OP = "d";
7
7
  const TRUNCATE_OP = "t";
8
8
  const RESET_OP = "r";
9
9
  const CREATE_CHANGELOG_SCHEMA = (
10
10
  // stateVersion : a.k.a. row version
11
+ // pos : order in which to process the change (within the version)
11
12
  // table : The table associated with the change
12
- // rowKey : JSON row key for a row change. For table-wide changes,
13
- // this is set to '', which guarantees that they sort before
14
- // any (subsequent) row-level changes. Note that because
15
- // RESET and TRUNCATE use the same rowKey, only the last
16
- // one will persist. This is fine because they are both
17
- // handled in the same way, i.e. by resetting the pipelines,
18
- // as they cannot be processed via change log entries.
19
- // op : 't' for table truncation
13
+ // rowKey : JSON row key for a row change. For table-wide changes RESET
14
+ // and TRUNCATE, there is no associated row; instead, `pos` is
15
+ // set to -1 and the rowKey is set to the stateVersion,
16
+ // guaranteeing when attempting to process the transaction,
17
+ // the pipeline is reset (and the change log traversal
18
+ // aborted).
19
+ // op : 's' for set (insert/update)
20
+ // : 'd' for delete
20
21
  // : 'r' for table reset (schema change)
21
- // 's' for set (insert/update)
22
- // 'd' for delete
22
+ // : 't' for table truncation (which also resets the pipeline)
23
+ //
24
+ // Naming note: To maintain compatibility between a new replication-manager
25
+ // and old view-syncers, the previous _zero.changeLog table is preserved
26
+ // and its replacement given a new name "changeLog2".
23
27
  `
24
- CREATE TABLE "_zero.changeLog" (
28
+ CREATE TABLE "_zero.changeLog2" (
25
29
  "stateVersion" TEXT NOT NULL,
30
+ "pos" INT NOT NULL,
26
31
  "table" TEXT NOT NULL,
27
- "rowKey" TEXT,
32
+ "rowKey" TEXT NOT NULL,
28
33
  "op" TEXT NOT NULL,
29
- PRIMARY KEY("stateVersion", "table", "rowKey"),
34
+ PRIMARY KEY("stateVersion", "pos"),
30
35
  UNIQUE("table", "rowKey")
31
36
  )
32
37
  `
33
38
  );
34
39
  const changeLogEntrySchema = object({
35
40
  stateVersion: string(),
41
+ pos: number(),
36
42
  table: string(),
37
- rowKey: string().nullable(),
43
+ rowKey: string(),
38
44
  op: literalUnion(SET_OP, DEL_OP, TRUNCATE_OP, RESET_OP)
39
45
  }).map((val) => ({
40
46
  ...val,
41
- // Note: the empty string "" (for table-wide ops) will result in `null`
42
- rowKey: val.rowKey ? parse(parse$1(val.rowKey), jsonObjectSchema) : null
47
+ // Note: sets the rowKey to `null` for table-wide ops / resets
48
+ rowKey: val.op === "t" || val.op === "r" ? null : parse(parse$1(val.rowKey), jsonObjectSchema)
43
49
  }));
44
50
  function initChangeLog(db) {
45
51
  db.exec(CREATE_CHANGELOG_SCHEMA);
46
52
  }
47
- function logSetOp(db, version, table, row) {
48
- return logRowOp(db, version, table, row, SET_OP);
53
+ function logSetOp(db, version, pos, table, row) {
54
+ return logRowOp(db, version, pos, table, row, SET_OP);
49
55
  }
50
- function logDeleteOp(db, version, table, row) {
51
- return logRowOp(db, version, table, row, DEL_OP);
56
+ function logDeleteOp(db, version, pos, table, row) {
57
+ return logRowOp(db, version, pos, table, row, DEL_OP);
52
58
  }
53
- function logRowOp(db, version, table, row, op) {
59
+ function logRowOp(db, version, pos, table, row, op) {
54
60
  const rowKey = stringify(normalizedKeyOrder(row));
55
61
  db.run(
56
62
  `
57
- INSERT OR REPLACE INTO "_zero.changeLog"
58
- (stateVersion, "table", rowKey, op)
59
- VALUES (@version, @table, JSON(@rowKey), @op)
63
+ INSERT OR REPLACE INTO "_zero.changeLog2"
64
+ (stateVersion, pos, "table", rowKey, op)
65
+ VALUES (@version, @pos, @table, JSON(@rowKey), @op)
60
66
  `,
61
- { version, table, rowKey, op }
67
+ { version, pos, table, rowKey, op }
62
68
  );
63
69
  return rowKey;
64
70
  }
@@ -71,18 +77,17 @@ function logResetOp(db, version, table) {
71
77
  function logTableWideOp(db, version, table, op) {
72
78
  db.run(
73
79
  `
74
- DELETE FROM "_zero.changeLog" WHERE stateVersion = ? AND "table" = ?
80
+ DELETE FROM "_zero.changeLog2" WHERE stateVersion = ? AND "table" = ?
75
81
  `,
76
82
  version,
77
83
  table
78
84
  );
79
85
  db.run(
80
86
  `
81
- INSERT OR REPLACE INTO "_zero.changeLog" (stateVersion, "table", rowKey, op)
82
- VALUES (@version, @table, @rowKey, @op)
87
+ INSERT OR REPLACE INTO "_zero.changeLog2" (stateVersion, pos, "table", rowKey, op)
88
+ VALUES (@version, -1, @table, @version, @op)
83
89
  `,
84
- // See file JSDoc for explanation of the rowKey w.r.t. ordering of table-wide ops.
85
- { version, table, rowKey: "", op }
90
+ { version, table, op }
86
91
  );
87
92
  }
88
93
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"change-log.js","sources":["../../../../../../../zero-cache/src/services/replicator/schema/change-log.ts"],"sourcesContent":["import {\n jsonObjectSchema,\n parse,\n stringify,\n} from '../../../../../shared/src/bigint-json.ts';\nimport * as v from '../../../../../shared/src/valita.ts';\nimport type {Database} from '../../../../../zqlite/src/db.ts';\nimport type {StatementRunner} from '../../../db/statements.ts';\nimport type {LexiVersion} from '../../../types/lexi-version.ts';\nimport type {LiteRowKey} from '../../../types/lite.ts';\nimport {normalizedKeyOrder} from '../../../types/row-key.ts';\n\n/**\n * The Change Log tracks the last operation (set or delete) for each row in the\n * data base, ordered by state version; in other words, a cross-table\n * index of row changes ordered by version. This facilitates a minimal \"diff\"\n * of row changes needed to advance a pipeline from one state version to another.\n *\n * The Change Log stores identifiers only, i.e. it does not store contents.\n * A database snapshot at the previous version can be used to query a row's\n * old contents, if any, and the current snapshot can be used to query a row's\n * new contents. (In the common case, the new contents will have just been applied\n * and thus has a high likelihood of being in the SQLite cache.)\n *\n * There are two table-wide operations:\n * - `t` corresponds to the postgres `TRUNCATE` operation\n * - `r` represents any schema (i.e. column) change\n *\n * For both operations, the corresponding row changes are not explicitly included\n * in the change log. The consumer has the option of simulating them be reading\n * from pre- and post- snapshots, or resetting their state entirely with the current\n * snapshot.\n *\n * To achieve the desired ordering semantics when processing tables that have been\n * truncated, reset, and modified, the \"rowKey\" is set to `null` for resets and\n * the empty string `\"\"` for truncates. This means that resets will be encountered\n * before truncates, which will be processed before any subsequent row changes.\n *\n * This ordering is chosen because resets are currently the more \"destructive\" op\n * and result in aborting the processing (and starting from scratch); doing this\n * earlier reduces wasted work.\n */\n\nexport const SET_OP = 's';\nexport const DEL_OP = 'd';\nexport const TRUNCATE_OP = 't';\nexport const RESET_OP = 'r';\n\nconst CREATE_CHANGELOG_SCHEMA =\n // stateVersion : a.k.a. row version\n // table : The table associated with the change\n // rowKey : JSON row key for a row change. For table-wide changes,\n // this is set to '', which guarantees that they sort before\n // any (subsequent) row-level changes. Note that because\n // RESET and TRUNCATE use the same rowKey, only the last\n // one will persist. This is fine because they are both\n // handled in the same way, i.e. by resetting the pipelines,\n // as they cannot be processed via change log entries.\n // op : 't' for table truncation\n // : 'r' for table reset (schema change)\n // 's' for set (insert/update)\n // 'd' for delete\n `\n CREATE TABLE \"_zero.changeLog\" (\n \"stateVersion\" TEXT NOT NULL,\n \"table\" TEXT NOT NULL,\n \"rowKey\" TEXT,\n \"op\" TEXT NOT NULL,\n PRIMARY KEY(\"stateVersion\", \"table\", \"rowKey\"),\n UNIQUE(\"table\", \"rowKey\")\n )\n `;\n\nexport const changeLogEntrySchema = v\n .object({\n stateVersion: v.string(),\n table: v.string(),\n rowKey: v.string().nullable(),\n op: v.literalUnion(SET_OP, DEL_OP, TRUNCATE_OP, RESET_OP),\n })\n .map(val => ({\n ...val,\n // Note: the empty string \"\" (for table-wide ops) will result in `null`\n rowKey: val.rowKey ? v.parse(parse(val.rowKey), jsonObjectSchema) : null,\n }));\n\nexport type ChangeLogEntry = v.Infer<typeof changeLogEntrySchema>;\n\nexport function initChangeLog(db: Database) {\n db.exec(CREATE_CHANGELOG_SCHEMA);\n}\n\nexport function logSetOp(\n db: StatementRunner,\n version: LexiVersion,\n table: string,\n row: LiteRowKey,\n): string {\n return logRowOp(db, version, table, row, SET_OP);\n}\n\nexport function logDeleteOp(\n db: StatementRunner,\n version: LexiVersion,\n table: string,\n row: LiteRowKey,\n): string {\n return logRowOp(db, version, table, row, DEL_OP);\n}\n\nfunction logRowOp(\n db: StatementRunner,\n version: LexiVersion,\n table: string,\n row: LiteRowKey,\n op: string,\n): string {\n const rowKey = stringify(normalizedKeyOrder(row));\n db.run(\n `\n INSERT OR REPLACE INTO \"_zero.changeLog\" \n (stateVersion, \"table\", rowKey, op)\n VALUES (@version, @table, JSON(@rowKey), @op)\n `,\n {version, table, rowKey, op},\n );\n return rowKey;\n}\nexport function logTruncateOp(\n db: StatementRunner,\n version: LexiVersion,\n table: string,\n) {\n logTableWideOp(db, version, table, TRUNCATE_OP);\n}\n\nexport function logResetOp(\n db: StatementRunner,\n version: LexiVersion,\n table: string,\n) {\n logTableWideOp(db, version, table, RESET_OP);\n}\n\nfunction logTableWideOp(\n db: StatementRunner,\n version: LexiVersion,\n table: string,\n op: 't' | 'r',\n) {\n // Delete any existing changes for the table (in this version) since the\n // table wide op invalidates them.\n db.run(\n `\n DELETE FROM \"_zero.changeLog\" WHERE stateVersion = ? AND \"table\" = ?\n `,\n version,\n table,\n );\n\n db.run(\n `\n INSERT OR REPLACE INTO \"_zero.changeLog\" (stateVersion, \"table\", rowKey, op) \n VALUES (@version, @table, @rowKey, @op)\n `,\n // See file JSDoc for explanation of the rowKey w.r.t. ordering of table-wide ops.\n {version, table, rowKey: '', op},\n );\n}\n"],"names":["v.object","v.string","v.literalUnion","v.parse","parse"],"mappings":";;;;AA2CO,MAAM,SAAS;AACf,MAAM,SAAS;AACf,MAAM,cAAc;AACpB,MAAM,WAAW;AAExB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWK,MAAM,uBAAuBA,OAC1B;AAAA,EACN,cAAcC,OAAE;AAAA,EAChB,OAAOA,OAAE;AAAA,EACT,QAAQA,OAAE,EAAS,SAAA;AAAA,EACnB,IAAIC,aAAe,QAAQ,QAAQ,aAAa,QAAQ;AAC1D,CAAC,EACA,IAAI,CAAA,SAAQ;AAAA,EACX,GAAG;AAAA;AAAA,EAEH,QAAQ,IAAI,SAASC,MAAQC,QAAM,IAAI,MAAM,GAAG,gBAAgB,IAAI;AACtE,EAAE;AAIG,SAAS,cAAc,IAAc;AAC1C,KAAG,KAAK,uBAAuB;AACjC;AAEO,SAAS,SACd,IACA,SACA,OACA,KACQ;AACR,SAAO,SAAS,IAAI,SAAS,OAAO,KAAK,MAAM;AACjD;AAEO,SAAS,YACd,IACA,SACA,OACA,KACQ;AACR,SAAO,SAAS,IAAI,SAAS,OAAO,KAAK,MAAM;AACjD;AAEA,SAAS,SACP,IACA,SACA,OACA,KACA,IACQ;AACR,QAAM,SAAS,UAAU,mBAAmB,GAAG,CAAC;AAChD,KAAG;AAAA,IACD;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,EAAC,SAAS,OAAO,QAAQ,GAAA;AAAA,EAAE;AAE7B,SAAO;AACT;AACO,SAAS,cACd,IACA,SACA,OACA;AACA,iBAAe,IAAI,SAAS,OAAO,WAAW;AAChD;AAEO,SAAS,WACd,IACA,SACA,OACA;AACA,iBAAe,IAAI,SAAS,OAAO,QAAQ;AAC7C;AAEA,SAAS,eACP,IACA,SACA,OACA,IACA;AAGA,KAAG;AAAA,IACD;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,EAAA;AAGF,KAAG;AAAA,IACD;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,EAAC,SAAS,OAAO,QAAQ,IAAI,GAAA;AAAA,EAAE;AAEnC;"}
1
+ {"version":3,"file":"change-log.js","sources":["../../../../../../../zero-cache/src/services/replicator/schema/change-log.ts"],"sourcesContent":["import {\n jsonObjectSchema,\n parse,\n stringify,\n} from '../../../../../shared/src/bigint-json.ts';\nimport * as v from '../../../../../shared/src/valita.ts';\nimport type {Database} from '../../../../../zqlite/src/db.ts';\nimport type {StatementRunner} from '../../../db/statements.ts';\nimport type {LexiVersion} from '../../../types/lexi-version.ts';\nimport type {LiteRowKey} from '../../../types/lite.ts';\nimport {normalizedKeyOrder} from '../../../types/row-key.ts';\n\n/**\n * The Change Log tracks the last operation (set or delete) for each row in the\n * data base, ordered by state version; in other words, a cross-table\n * index of row changes ordered by version. This facilitates a minimal \"diff\"\n * of row changes needed to advance a pipeline from one state version to another.\n *\n * The Change Log stores identifiers only, i.e. it does not store contents.\n * A database snapshot at the previous version can be used to query a row's\n * old contents, if any, and the current snapshot can be used to query a row's\n * new contents. (In the common case, the new contents will have just been applied\n * and thus has a high likelihood of being in the SQLite cache.)\n *\n * There are two table-wide operations:\n * - `t` corresponds to the postgres `TRUNCATE` operation\n * - `r` represents any schema (i.e. column) change\n *\n * For both operations, the corresponding row changes are not explicitly included\n * in the change log. The consumer has the option of simulating them be reading\n * from pre- and post- snapshots, or resetting their state entirely with the current\n * snapshot.\n *\n * To achieve the desired ordering semantics when processing tables that have been\n * truncated, reset, and modified, the \"rowKey\" is set to `null` for resets and\n * the empty string `\"\"` for truncates. This means that resets will be encountered\n * before truncates, which will be processed before any subsequent row changes.\n *\n * This ordering is chosen because resets are currently the more \"destructive\" op\n * and result in aborting the processing (and starting from scratch); doing this\n * earlier reduces wasted work.\n */\n\nexport const SET_OP = 's';\nexport const DEL_OP = 'd';\nexport const TRUNCATE_OP = 't';\nexport const RESET_OP = 'r';\n\nconst CREATE_CHANGELOG_SCHEMA =\n // stateVersion : a.k.a. row version\n // pos : order in which to process the change (within the version)\n // table : The table associated with the change\n // rowKey : JSON row key for a row change. For table-wide changes RESET\n // and TRUNCATE, there is no associated row; instead, `pos` is\n // set to -1 and the rowKey is set to the stateVersion,\n // guaranteeing when attempting to process the transaction,\n // the pipeline is reset (and the change log traversal\n // aborted).\n // op : 's' for set (insert/update)\n // : 'd' for delete\n // : 'r' for table reset (schema change)\n // : 't' for table truncation (which also resets the pipeline)\n //\n // Naming note: To maintain compatibility between a new replication-manager\n // and old view-syncers, the previous _zero.changeLog table is preserved\n // and its replacement given a new name \"changeLog2\".\n `\n CREATE TABLE \"_zero.changeLog2\" (\n \"stateVersion\" TEXT NOT NULL,\n \"pos\" INT NOT NULL,\n \"table\" TEXT NOT NULL,\n \"rowKey\" TEXT NOT NULL,\n \"op\" TEXT NOT NULL,\n PRIMARY KEY(\"stateVersion\", \"pos\"),\n UNIQUE(\"table\", \"rowKey\")\n )\n `;\n\nexport const changeLogEntrySchema = v\n .object({\n stateVersion: v.string(),\n pos: v.number(),\n table: v.string(),\n rowKey: v.string(),\n op: v.literalUnion(SET_OP, DEL_OP, TRUNCATE_OP, RESET_OP),\n })\n .map(val => ({\n ...val,\n // Note: sets the rowKey to `null` for table-wide ops / resets\n rowKey:\n val.op === 't' || val.op === 'r'\n ? null\n : v.parse(parse(val.rowKey), jsonObjectSchema),\n }));\n\nexport type ChangeLogEntry = v.Infer<typeof changeLogEntrySchema>;\n\nexport function initChangeLog(db: Database) {\n db.exec(CREATE_CHANGELOG_SCHEMA);\n}\n\nexport function logSetOp(\n db: StatementRunner,\n version: LexiVersion,\n pos: number,\n table: string,\n row: LiteRowKey,\n): string {\n return logRowOp(db, version, pos, table, row, SET_OP);\n}\n\nexport function logDeleteOp(\n db: StatementRunner,\n version: LexiVersion,\n pos: number,\n table: string,\n row: LiteRowKey,\n): string {\n return logRowOp(db, version, pos, table, row, DEL_OP);\n}\n\nfunction logRowOp(\n db: StatementRunner,\n version: LexiVersion,\n pos: number,\n table: string,\n row: LiteRowKey,\n op: string,\n): string {\n const rowKey = stringify(normalizedKeyOrder(row));\n db.run(\n `\n INSERT OR REPLACE INTO \"_zero.changeLog2\" \n (stateVersion, pos, \"table\", rowKey, op)\n VALUES (@version, @pos, @table, JSON(@rowKey), @op)\n `,\n {version, pos, table, rowKey, op},\n );\n return rowKey;\n}\nexport function logTruncateOp(\n db: StatementRunner,\n version: LexiVersion,\n table: string,\n) {\n logTableWideOp(db, version, table, TRUNCATE_OP);\n}\n\nexport function logResetOp(\n db: StatementRunner,\n version: LexiVersion,\n table: string,\n) {\n logTableWideOp(db, version, table, RESET_OP);\n}\n\nfunction logTableWideOp(\n db: StatementRunner,\n version: LexiVersion,\n table: string,\n op: 't' | 'r',\n) {\n // Delete any existing changes for the table (in this version) since the\n // table wide op invalidates them.\n db.run(\n `\n DELETE FROM \"_zero.changeLog2\" WHERE stateVersion = ? AND \"table\" = ?\n `,\n version,\n table,\n );\n\n db.run(\n `\n INSERT OR REPLACE INTO \"_zero.changeLog2\" (stateVersion, pos, \"table\", rowKey, op) \n VALUES (@version, -1, @table, @version, @op)\n `,\n {version, table, op},\n );\n}\n"],"names":["v.object","v.string","v.number","v.literalUnion","v.parse","parse"],"mappings":";;;;AA2CO,MAAM,SAAS;AACf,MAAM,SAAS;AACf,MAAM,cAAc;AACpB,MAAM,WAAW;AAExB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYK,MAAM,uBAAuBA,OAC1B;AAAA,EACN,cAAcC,OAAE;AAAA,EAChB,KAAKC,OAAE;AAAA,EACP,OAAOD,OAAE;AAAA,EACT,QAAQA,OAAE;AAAA,EACV,IAAIE,aAAe,QAAQ,QAAQ,aAAa,QAAQ;AAC1D,CAAC,EACA,IAAI,CAAA,SAAQ;AAAA,EACX,GAAG;AAAA;AAAA,EAEH,QACE,IAAI,OAAO,OAAO,IAAI,OAAO,MACzB,OACAC,MAAQC,QAAM,IAAI,MAAM,GAAG,gBAAgB;AACnD,EAAE;AAIG,SAAS,cAAc,IAAc;AAC1C,KAAG,KAAK,uBAAuB;AACjC;AAEO,SAAS,SACd,IACA,SACA,KACA,OACA,KACQ;AACR,SAAO,SAAS,IAAI,SAAS,KAAK,OAAO,KAAK,MAAM;AACtD;AAEO,SAAS,YACd,IACA,SACA,KACA,OACA,KACQ;AACR,SAAO,SAAS,IAAI,SAAS,KAAK,OAAO,KAAK,MAAM;AACtD;AAEA,SAAS,SACP,IACA,SACA,KACA,OACA,KACA,IACQ;AACR,QAAM,SAAS,UAAU,mBAAmB,GAAG,CAAC;AAChD,KAAG;AAAA,IACD;AAAA;AAAA;AAAA;AAAA;AAAA,IAKA,EAAC,SAAS,KAAK,OAAO,QAAQ,GAAA;AAAA,EAAE;AAElC,SAAO;AACT;AACO,SAAS,cACd,IACA,SACA,OACA;AACA,iBAAe,IAAI,SAAS,OAAO,WAAW;AAChD;AAEO,SAAS,WACd,IACA,SACA,OACA;AACA,iBAAe,IAAI,SAAS,OAAO,QAAQ;AAC7C;AAEA,SAAS,eACP,IACA,SACA,OACA,IACA;AAGA,KAAG;AAAA,IACD;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,EAAA;AAGF,KAAG;AAAA,IACD;AAAA;AAAA;AAAA;AAAA,IAIA,EAAC,SAAS,OAAO,GAAA;AAAA,EAAE;AAEvB;"}
@@ -1,14 +1,13 @@
1
1
  import type { LogContext } from '@rocicorp/logger';
2
2
  import type { JSONObject } from '../../../../shared/src/bigint-json.ts';
3
3
  import { type JSONObject as SafeJSONObject } from '../../../../shared/src/json.ts';
4
+ import type { ErroredQuery } from '../../../../zero-protocol/src/custom-queries.ts';
4
5
  import type { Downstream } from '../../../../zero-protocol/src/down.ts';
6
+ import { type TransformFailedBody } from '../../../../zero-protocol/src/error.ts';
5
7
  import type { InspectDownBody } from '../../../../zero-protocol/src/inspect-down.ts';
6
- import { type SchemaVersions } from '../../types/schema-versions.ts';
7
8
  import { type ShardID } from '../../types/shards.ts';
8
9
  import type { Subscription } from '../../types/subscription.ts';
9
10
  import { type CVRVersion, type DelQueryPatch, type NullableCVRVersion, type PutQueryPatch, type RowID } from './schema/types.ts';
10
- import type { ErroredQuery } from '../../../../zero-protocol/src/custom-queries.ts';
11
- import { type TransformFailedBody } from '../../../../zero-protocol/src/error.ts';
12
11
  export type PutRowPatch = {
13
12
  type: 'row';
14
13
  op: 'put';
@@ -33,7 +32,7 @@ export interface PokeHandler {
33
32
  end(finalVersion: CVRVersion): Promise<void>;
34
33
  }
35
34
  /** Wraps PokeHandlers for multiple clients in a single PokeHandler. */
36
- export declare function startPoke(clients: ClientHandler[], tentativeVersion: CVRVersion, schemaVersions?: SchemaVersions): PokeHandler;
35
+ export declare function startPoke(clients: ClientHandler[], tentativeVersion: CVRVersion): PokeHandler;
37
36
  /**
38
37
  * Handles a single `ViewSyncer` connection.
39
38
  */
@@ -41,11 +40,11 @@ export declare class ClientHandler {
41
40
  #private;
42
41
  readonly clientID: string;
43
42
  readonly wsID: string;
44
- constructor(lc: LogContext, clientGroupID: string, clientID: string, wsID: string, shard: ShardID, baseCookie: string | null, schemaVersion: number | null, downstream: Subscription<Downstream>);
43
+ constructor(lc: LogContext, clientGroupID: string, clientID: string, wsID: string, shard: ShardID, baseCookie: string | null, downstream: Subscription<Downstream>);
45
44
  version(): NullableCVRVersion;
46
45
  fail(e: unknown): void;
47
46
  close(reason: string): void;
48
- startPoke(tentativeVersion: CVRVersion, schemaVersions?: SchemaVersions): PokeHandler;
47
+ startPoke(tentativeVersion: CVRVersion): PokeHandler;
49
48
  sendDeleteClients(lc: LogContext, deletedClientIDs: string[], deletedClientGroupIDs: string[]): Promise<void>;
50
49
  sendQueryTransformApplicationErrors(errors: ErroredQuery[]): void;
51
50
  sendQueryTransformFailedError(error: TransformFailedBody): void;
@@ -1 +1 @@
1
- {"version":3,"file":"client-handler.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/client-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client-handler.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/client-handler.ts"],"names":[],"mappings":"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"}
@@ -3,24 +3,21 @@ import { assertJSONValue } from "../../../../shared/src/json.js";
3
3
  import { promiseVoid } from "../../../../shared/src/resolved-promises.js";
4
4
  import { parse } from "../../../../shared/src/valita.js";
5
5
  import { rowSchema } from "../../../../zero-protocol/src/data.js";
6
+ import { ProtocolError } from "../../../../zero-protocol/src/error.js";
6
7
  import { primaryKeyValueRecordSchema } from "../../../../zero-protocol/src/primary-key.js";
7
8
  import { mutationResultSchema } from "../../../../zero-protocol/src/push.js";
8
9
  import { getOrCreateHistogram, getOrCreateCounter } from "../../observability/metrics.js";
9
10
  import { getLogLevel, wrapWithProtocolError } from "../../types/error-with-level.js";
10
- import { getProtocolErrorIfSchemaVersionNotSupported } from "../../types/schema-versions.js";
11
11
  import { upstreamSchema } from "../../types/shards.js";
12
12
  import { cookieToVersion, versionToCookie, cmpVersions, versionToNullableCookie } from "./schema/types.js";
13
- import { ProtocolError } from "../../../../zero-protocol/src/error.js";
14
13
  import { object, number, string } from "@badrap/valita";
15
14
  const NOOP = {
16
15
  addPatch: () => promiseVoid,
17
16
  cancel: () => promiseVoid,
18
17
  end: () => promiseVoid
19
18
  };
20
- function startPoke(clients, tentativeVersion, schemaVersions) {
21
- const pokers = clients.map(
22
- (c) => c.startPoke(tentativeVersion, schemaVersions)
23
- );
19
+ function startPoke(clients, tentativeVersion) {
20
+ const pokers = clients.map((c) => c.startPoke(tentativeVersion));
24
21
  return {
25
22
  addPatch: async (patch) => {
26
23
  await Promise.allSettled(pokers.map((poker) => poker.addPatch(patch)));
@@ -43,7 +40,6 @@ class ClientHandler {
43
40
  #lc;
44
41
  #downstream;
45
42
  #baseVersion;
46
- #schemaVersion;
47
43
  #pokeTime = getOrCreateHistogram("sync", "poke.time", {
48
44
  description: "Time elapsed for each poke transaction. Canceled / noop pokes are excluded.",
49
45
  unit: "s"
@@ -58,7 +54,7 @@ class ClientHandler {
58
54
  "poke.rows",
59
55
  "Count of poked rows."
60
56
  );
61
- constructor(lc, clientGroupID, clientID, wsID, shard, baseCookie, schemaVersion, downstream) {
57
+ constructor(lc, clientGroupID, clientID, wsID, shard, baseCookie, downstream) {
62
58
  lc.debug?.("new client handler");
63
59
  this.#clientGroupID = clientGroupID;
64
60
  this.clientID = clientID;
@@ -68,7 +64,6 @@ class ClientHandler {
68
64
  this.#lc = lc;
69
65
  this.#downstream = downstream;
70
66
  this.#baseVersion = cookieToVersion(baseCookie);
71
- this.#schemaVersion = schemaVersion;
72
67
  }
73
68
  version() {
74
69
  return this.#baseVersion;
@@ -88,19 +83,9 @@ class ClientHandler {
88
83
  this.#lc.debug?.(`view-syncer closing connection: ${reason}`);
89
84
  this.#downstream.cancel();
90
85
  }
91
- startPoke(tentativeVersion, schemaVersions) {
86
+ startPoke(tentativeVersion) {
92
87
  const pokeID = versionToCookie(tentativeVersion);
93
88
  const lc = this.#lc.withContext("pokeID", pokeID);
94
- if (schemaVersions && this.#schemaVersion) {
95
- const schemaVersionError = getProtocolErrorIfSchemaVersionNotSupported(
96
- this.#schemaVersion,
97
- schemaVersions
98
- );
99
- if (schemaVersionError) {
100
- this.fail(schemaVersionError);
101
- return NOOP;
102
- }
103
- }
104
89
  if (cmpVersions(this.#baseVersion, tentativeVersion) >= 0) {
105
90
  lc.info?.(`already caught up, not sending poke.`);
106
91
  return NOOP;
@@ -110,9 +95,6 @@ class ClientHandler {
110
95
  lc.info?.(`starting poke from ${baseCookie} to ${cookie}`);
111
96
  const start = performance.now();
112
97
  const pokeStart = { pokeID, baseCookie };
113
- if (schemaVersions) {
114
- pokeStart.schemaVersions = schemaVersions;
115
- }
116
98
  let pokeStarted = false;
117
99
  let body;
118
100
  let partCount = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"client-handler.js","sources":["../../../../../../zero-cache/src/services/view-syncer/client-handler.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {assert, unreachable} from '../../../../shared/src/asserts.ts';\nimport type {JSONObject} from '../../../../shared/src/bigint-json.ts';\nimport {\n assertJSONValue,\n type JSONObject as SafeJSONObject,\n} from '../../../../shared/src/json.ts';\nimport {promiseVoid} from '../../../../shared/src/resolved-promises.ts';\nimport * as v from '../../../../shared/src/valita.ts';\nimport type {Writable} from '../../../../shared/src/writable.ts';\nimport {rowSchema} from '../../../../zero-protocol/src/data.ts';\nimport type {DeleteClientsBody} from '../../../../zero-protocol/src/delete-clients.ts';\nimport type {Downstream} from '../../../../zero-protocol/src/down.ts';\nimport type {InspectDownBody} from '../../../../zero-protocol/src/inspect-down.ts';\nimport type {\n PokePartBody,\n PokeStartBody,\n} from '../../../../zero-protocol/src/poke.ts';\nimport {primaryKeyValueRecordSchema} from '../../../../zero-protocol/src/primary-key.ts';\nimport {mutationResultSchema} from '../../../../zero-protocol/src/push.ts';\nimport type {RowPatchOp} from '../../../../zero-protocol/src/row-patch.ts';\nimport {\n getOrCreateCounter,\n getOrCreateHistogram,\n} from '../../observability/metrics.ts';\nimport {\n getLogLevel,\n wrapWithProtocolError,\n} from '../../types/error-with-level.ts';\nimport {\n getProtocolErrorIfSchemaVersionNotSupported,\n type SchemaVersions,\n} from '../../types/schema-versions.ts';\nimport {upstreamSchema, type ShardID} from '../../types/shards.ts';\nimport type {Subscription} from '../../types/subscription.ts';\nimport {\n cmpVersions,\n cookieToVersion,\n versionToCookie,\n versionToNullableCookie,\n type CVRVersion,\n type DelQueryPatch,\n type NullableCVRVersion,\n type PutQueryPatch,\n type RowID,\n} from './schema/types.ts';\nimport type {ErroredQuery} from '../../../../zero-protocol/src/custom-queries.ts';\nimport {\n ProtocolError,\n type TransformFailedBody,\n} from '../../../../zero-protocol/src/error.ts';\n\nexport type PutRowPatch = {\n type: 'row';\n op: 'put';\n id: RowID;\n contents: JSONObject;\n};\n\nexport type DeleteRowPatch = {\n type: 'row';\n op: 'del';\n id: RowID;\n};\n\nexport type RowPatch = PutRowPatch | DeleteRowPatch;\nexport type ConfigPatch = DelQueryPatch | PutQueryPatch;\n\nexport type Patch = ConfigPatch | RowPatch;\n\nexport type PatchToVersion = {\n patch: Patch;\n toVersion: CVRVersion;\n};\n\nexport interface PokeHandler {\n addPatch(patch: PatchToVersion): Promise<void>;\n cancel(): Promise<void>;\n end(finalVersion: CVRVersion): Promise<void>;\n}\n\nconst NOOP: PokeHandler = {\n addPatch: () => promiseVoid,\n cancel: () => promiseVoid,\n end: () => promiseVoid,\n};\n\n/** Wraps PokeHandlers for multiple clients in a single PokeHandler. */\nexport function startPoke(\n clients: ClientHandler[],\n tentativeVersion: CVRVersion,\n schemaVersions?: SchemaVersions, // absent for config-only pokes\n): PokeHandler {\n const pokers = clients.map(c =>\n c.startPoke(tentativeVersion, schemaVersions),\n );\n\n // Promise.allSettled() ensures that a failed (e.g. disconnected) client\n // does not prevent other clients from receiving the pokes. However, the\n // rate (per client group) will be limited by the slowest connection.\n return {\n addPatch: async patch => {\n await Promise.allSettled(pokers.map(poker => poker.addPatch(patch)));\n },\n cancel: async () => {\n await Promise.allSettled(pokers.map(poker => poker.cancel()));\n },\n end: async finalVersion => {\n await Promise.allSettled(pokers.map(poker => poker.end(finalVersion)));\n },\n };\n}\n\n// Semi-arbitrary threshold at which poke body parts are flushed.\n// When row size is being computed, that should be used as a threshold instead.\nconst PART_COUNT_FLUSH_THRESHOLD = 100;\n\n/**\n * Handles a single `ViewSyncer` connection.\n */\nexport class ClientHandler {\n readonly #clientGroupID: string;\n readonly clientID: string;\n readonly wsID: string;\n readonly #zeroClientsTable: string;\n readonly #zeroMutationsTable: string;\n readonly #lc: LogContext;\n readonly #downstream: Subscription<Downstream>;\n #baseVersion: NullableCVRVersion;\n readonly #schemaVersion: number | null;\n\n readonly #pokeTime = getOrCreateHistogram('sync', 'poke.time', {\n description:\n 'Time elapsed for each poke transaction. Canceled / noop pokes are excluded.',\n unit: 's',\n });\n\n readonly #pokeTransactions = getOrCreateCounter(\n 'sync',\n 'poke.transactions',\n 'Count of poke transactions.',\n );\n\n readonly #pokedRows = getOrCreateCounter(\n 'sync',\n 'poke.rows',\n 'Count of poked rows.',\n );\n\n constructor(\n lc: LogContext,\n clientGroupID: string,\n clientID: string,\n wsID: string,\n shard: ShardID,\n baseCookie: string | null,\n schemaVersion: number | null,\n downstream: Subscription<Downstream>,\n ) {\n lc.debug?.('new client handler');\n this.#clientGroupID = clientGroupID;\n this.clientID = clientID;\n this.wsID = wsID;\n this.#zeroClientsTable = `${upstreamSchema(shard)}.clients`;\n this.#zeroMutationsTable = `${upstreamSchema(shard)}.mutations`;\n this.#lc = lc;\n this.#downstream = downstream;\n this.#baseVersion = cookieToVersion(baseCookie);\n this.#schemaVersion = schemaVersion;\n }\n\n version(): NullableCVRVersion {\n return this.#baseVersion;\n }\n\n async #push(msg: Downstream): Promise<void> {\n const {result} = this.#downstream.push(msg);\n await result;\n }\n\n fail(e: unknown) {\n this.#lc[getLogLevel(e)]?.(\n `view-syncer closing connection with error: ${String(e)}`,\n e,\n );\n this.#downstream.fail(wrapWithProtocolError(e));\n }\n\n close(reason: string) {\n this.#lc.debug?.(`view-syncer closing connection: ${reason}`);\n this.#downstream.cancel();\n }\n\n startPoke(\n tentativeVersion: CVRVersion,\n schemaVersions?: SchemaVersions, // absent for config-only pokes\n ): PokeHandler {\n const pokeID = versionToCookie(tentativeVersion);\n const lc = this.#lc.withContext('pokeID', pokeID);\n\n if (schemaVersions && this.#schemaVersion) {\n const schemaVersionError = getProtocolErrorIfSchemaVersionNotSupported(\n this.#schemaVersion,\n schemaVersions,\n );\n\n if (schemaVersionError) {\n this.fail(schemaVersionError);\n return NOOP;\n }\n }\n\n if (cmpVersions(this.#baseVersion, tentativeVersion) >= 0) {\n lc.info?.(`already caught up, not sending poke.`);\n return NOOP;\n }\n\n const baseCookie = versionToNullableCookie(this.#baseVersion);\n const cookie = versionToCookie(tentativeVersion);\n lc.info?.(`starting poke from ${baseCookie} to ${cookie}`);\n\n const start = performance.now();\n\n const pokeStart: PokeStartBody = {pokeID, baseCookie};\n if (schemaVersions) {\n pokeStart.schemaVersions = schemaVersions;\n }\n\n let pokeStarted = false;\n let body: PokePartBody | undefined;\n let partCount = 0;\n const ensureBody = async () => {\n if (!pokeStarted) {\n await this.#push(['pokeStart', pokeStart]);\n pokeStarted = true;\n }\n return (body ??= {pokeID});\n };\n const flushBody = async () => {\n if (body) {\n await this.#push(['pokePart', body]);\n body = undefined;\n partCount = 0;\n }\n };\n\n const addPatch = async (patchToVersion: PatchToVersion) => {\n const {patch, toVersion} = patchToVersion;\n if (cmpVersions(toVersion, this.#baseVersion) <= 0) {\n return;\n }\n const body = await ensureBody();\n\n const {type, op} = patch;\n switch (type) {\n case 'query': {\n const patches = patch.clientID\n ? ((body.desiredQueriesPatches ??= {})[patch.clientID] ??= [])\n : (body.gotQueriesPatch ??= []);\n if (op === 'put') {\n patches.push({op, hash: patch.id});\n } else {\n patches.push({op, hash: patch.id});\n }\n break;\n }\n case 'row':\n if (patch.id.table === this.#zeroClientsTable) {\n this.#updateLMIDs((body.lastMutationIDChanges ??= {}), patch);\n } else if (patch.id.table === this.#zeroMutationsTable) {\n const patches = (body.mutationsPatch ??= []);\n if (op === 'put') {\n const row = v.parse(\n ensureSafeJSON(patch.contents),\n mutationRowSchema,\n 'passthrough',\n );\n patches.push({\n op: 'put',\n mutation: {\n id: {\n clientID: row.clientID,\n id: row.mutationID,\n },\n result: row.result,\n },\n });\n } else {\n const {clientID, mutationID} = patch.id.rowKey;\n assert(\n typeof clientID === 'string',\n 'client id must be a string',\n );\n const id = Number(mutationID);\n assert(\n !Number.isNaN(id) && Number.isFinite(id) && id >= 0,\n 'mutation id must be a finite number',\n );\n patches.push({\n op: 'del',\n id: {\n clientID,\n id,\n },\n });\n }\n } else {\n (body.rowsPatch ??= []).push(makeRowPatch(patch));\n }\n break;\n default:\n unreachable(patch);\n }\n\n if (++partCount >= PART_COUNT_FLUSH_THRESHOLD) {\n await flushBody();\n }\n };\n\n return {\n addPatch: async (patchToVersion: PatchToVersion) => {\n try {\n await addPatch(patchToVersion);\n if (patchToVersion.patch.type === 'row') {\n this.#pokedRows.add(1);\n }\n } catch (e) {\n this.#downstream.fail(wrapWithProtocolError(e));\n }\n },\n\n cancel: async () => {\n if (pokeStarted) {\n await this.#push(['pokeEnd', {pokeID, cookie: '', cancel: true}]);\n }\n },\n\n end: async (finalVersion: CVRVersion) => {\n const cookie = versionToCookie(finalVersion);\n if (!pokeStarted) {\n if (cmpVersions(this.#baseVersion, finalVersion) === 0) {\n return; // Nothing changed and nothing was sent.\n }\n await this.#push(['pokeStart', pokeStart]);\n } else if (cmpVersions(this.#baseVersion, finalVersion) >= 0) {\n // Sanity check: If the poke was started, the finalVersion\n // must be > #baseVersion.\n throw new Error(\n `Patches were sent but finalVersion ${finalVersion} is ` +\n `not greater than baseVersion ${this.#baseVersion}`,\n );\n }\n await flushBody();\n await this.#push(['pokeEnd', {pokeID, cookie}]);\n this.#baseVersion = finalVersion;\n\n const elapsed = performance.now() - start;\n this.#pokeTransactions.add(1);\n this.#pokeTime.record(elapsed / 1000);\n },\n };\n }\n\n async sendDeleteClients(\n lc: LogContext,\n deletedClientIDs: string[],\n deletedClientGroupIDs: string[],\n ) {\n const deleteClientsBody: Writable<DeleteClientsBody> = {};\n if (deletedClientIDs.length > 0) {\n deleteClientsBody.clientIDs = deletedClientIDs;\n }\n if (deletedClientGroupIDs.length > 0) {\n deleteClientsBody.clientGroupIDs = deletedClientGroupIDs;\n }\n lc.debug?.('sending deleteClients', deleteClientsBody);\n await this.#push(['deleteClients', deleteClientsBody]);\n }\n\n sendQueryTransformApplicationErrors(errors: ErroredQuery[]) {\n void this.#push(['transformError', errors]);\n }\n\n sendQueryTransformFailedError(error: TransformFailedBody) {\n this.fail(new ProtocolError(error));\n }\n\n sendInspectResponse(lc: LogContext, response: InspectDownBody): void {\n lc.debug?.('sending inspect response', response);\n this.#downstream.push(['inspect', response]);\n }\n\n #updateLMIDs(lmids: Record<string, number>, patch: RowPatch) {\n if (patch.op === 'put') {\n const row = ensureSafeJSON(patch.contents);\n const {clientGroupID, clientID, lastMutationID} = v.parse(\n row,\n lmidRowSchema,\n 'passthrough',\n );\n if (clientGroupID !== this.#clientGroupID) {\n this.#lc.error?.(\n `Received clients row for wrong clientGroupID. Ignoring.`,\n clientGroupID,\n );\n } else {\n lmids[clientID] = lastMutationID;\n }\n } else {\n // The 'constrain' and 'del' ops for clients can be ignored.\n patch.op satisfies 'constrain' | 'del';\n }\n }\n}\n\n// Note: The {APP_ID}_{SHARD_ID}.clients table is set up in replicator/initial-sync.ts.\nconst lmidRowSchema = v.object({\n clientGroupID: v.string(),\n clientID: v.string(),\n lastMutationID: v.number(), // Actually returned as a bigint, but converted by ensureSafeJSON().\n});\n\nconst mutationRowSchema = v.object({\n clientGroupID: v.string(),\n clientID: v.string(),\n mutationID: v.number(),\n result: mutationResultSchema,\n});\n\nfunction makeRowPatch(patch: RowPatch): RowPatchOp {\n const {\n op,\n id: {table: tableName, rowKey: id},\n } = patch;\n\n switch (op) {\n case 'put':\n return {\n op: 'put',\n tableName,\n value: v.parse(ensureSafeJSON(patch.contents), rowSchema),\n };\n\n case 'del':\n return {\n op,\n tableName,\n id: v.parse(id, primaryKeyValueRecordSchema),\n };\n\n default:\n unreachable(op);\n }\n}\n\n/**\n * Column values of type INT8 are returned as the `bigint` from the\n * Postgres library. These are converted to `number` if they are within\n * the safe Number range, allowing the protocol to support numbers larger\n * than 32-bits. Values outside of the safe number range (e.g. > 2^53) will\n * result in an Error.\n */\nexport function ensureSafeJSON(row: JSONObject): SafeJSONObject {\n const modified = Object.entries(row)\n .filter(([k, v]) => {\n if (typeof v === 'bigint') {\n if (v >= Number.MIN_SAFE_INTEGER && v <= Number.MAX_SAFE_INTEGER) {\n return true; // send this entry onto the next map() step.\n }\n throw new Error(`Value of \"${k}\" exceeds safe Number range (${v})`);\n } else if (typeof v === 'object') {\n assertJSONValue(v);\n }\n return false;\n })\n .map(([k, v]) => [k, Number(v)]);\n\n return modified.length\n ? {...row, ...Object.fromEntries(modified)}\n : (row as SafeJSONObject);\n}\n"],"names":["body","v.parse","cookie","v.object","v.string","v.number","v"],"mappings":"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"}
1
+ {"version":3,"file":"client-handler.js","sources":["../../../../../../zero-cache/src/services/view-syncer/client-handler.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {assert, unreachable} from '../../../../shared/src/asserts.ts';\nimport type {JSONObject} from '../../../../shared/src/bigint-json.ts';\nimport {\n assertJSONValue,\n type JSONObject as SafeJSONObject,\n} from '../../../../shared/src/json.ts';\nimport {promiseVoid} from '../../../../shared/src/resolved-promises.ts';\nimport * as v from '../../../../shared/src/valita.ts';\nimport type {Writable} from '../../../../shared/src/writable.ts';\nimport type {ErroredQuery} from '../../../../zero-protocol/src/custom-queries.ts';\nimport {rowSchema} from '../../../../zero-protocol/src/data.ts';\nimport type {DeleteClientsBody} from '../../../../zero-protocol/src/delete-clients.ts';\nimport type {Downstream} from '../../../../zero-protocol/src/down.ts';\nimport {\n ProtocolError,\n type TransformFailedBody,\n} from '../../../../zero-protocol/src/error.ts';\nimport type {InspectDownBody} from '../../../../zero-protocol/src/inspect-down.ts';\nimport type {\n PokePartBody,\n PokeStartBody,\n} from '../../../../zero-protocol/src/poke.ts';\nimport {primaryKeyValueRecordSchema} from '../../../../zero-protocol/src/primary-key.ts';\nimport {mutationResultSchema} from '../../../../zero-protocol/src/push.ts';\nimport type {RowPatchOp} from '../../../../zero-protocol/src/row-patch.ts';\nimport {\n getOrCreateCounter,\n getOrCreateHistogram,\n} from '../../observability/metrics.ts';\nimport {\n getLogLevel,\n wrapWithProtocolError,\n} from '../../types/error-with-level.ts';\nimport {upstreamSchema, type ShardID} from '../../types/shards.ts';\nimport type {Subscription} from '../../types/subscription.ts';\nimport {\n cmpVersions,\n cookieToVersion,\n versionToCookie,\n versionToNullableCookie,\n type CVRVersion,\n type DelQueryPatch,\n type NullableCVRVersion,\n type PutQueryPatch,\n type RowID,\n} from './schema/types.ts';\n\nexport type PutRowPatch = {\n type: 'row';\n op: 'put';\n id: RowID;\n contents: JSONObject;\n};\n\nexport type DeleteRowPatch = {\n type: 'row';\n op: 'del';\n id: RowID;\n};\n\nexport type RowPatch = PutRowPatch | DeleteRowPatch;\nexport type ConfigPatch = DelQueryPatch | PutQueryPatch;\n\nexport type Patch = ConfigPatch | RowPatch;\n\nexport type PatchToVersion = {\n patch: Patch;\n toVersion: CVRVersion;\n};\n\nexport interface PokeHandler {\n addPatch(patch: PatchToVersion): Promise<void>;\n cancel(): Promise<void>;\n end(finalVersion: CVRVersion): Promise<void>;\n}\n\nconst NOOP: PokeHandler = {\n addPatch: () => promiseVoid,\n cancel: () => promiseVoid,\n end: () => promiseVoid,\n};\n\n/** Wraps PokeHandlers for multiple clients in a single PokeHandler. */\nexport function startPoke(\n clients: ClientHandler[],\n tentativeVersion: CVRVersion,\n): PokeHandler {\n const pokers = clients.map(c => c.startPoke(tentativeVersion));\n\n // Promise.allSettled() ensures that a failed (e.g. disconnected) client\n // does not prevent other clients from receiving the pokes. However, the\n // rate (per client group) will be limited by the slowest connection.\n return {\n addPatch: async patch => {\n await Promise.allSettled(pokers.map(poker => poker.addPatch(patch)));\n },\n cancel: async () => {\n await Promise.allSettled(pokers.map(poker => poker.cancel()));\n },\n end: async finalVersion => {\n await Promise.allSettled(pokers.map(poker => poker.end(finalVersion)));\n },\n };\n}\n\n// Semi-arbitrary threshold at which poke body parts are flushed.\n// When row size is being computed, that should be used as a threshold instead.\nconst PART_COUNT_FLUSH_THRESHOLD = 100;\n\n/**\n * Handles a single `ViewSyncer` connection.\n */\nexport class ClientHandler {\n readonly #clientGroupID: string;\n readonly clientID: string;\n readonly wsID: string;\n readonly #zeroClientsTable: string;\n readonly #zeroMutationsTable: string;\n readonly #lc: LogContext;\n readonly #downstream: Subscription<Downstream>;\n #baseVersion: NullableCVRVersion;\n\n readonly #pokeTime = getOrCreateHistogram('sync', 'poke.time', {\n description:\n 'Time elapsed for each poke transaction. Canceled / noop pokes are excluded.',\n unit: 's',\n });\n\n readonly #pokeTransactions = getOrCreateCounter(\n 'sync',\n 'poke.transactions',\n 'Count of poke transactions.',\n );\n\n readonly #pokedRows = getOrCreateCounter(\n 'sync',\n 'poke.rows',\n 'Count of poked rows.',\n );\n\n constructor(\n lc: LogContext,\n clientGroupID: string,\n clientID: string,\n wsID: string,\n shard: ShardID,\n baseCookie: string | null,\n downstream: Subscription<Downstream>,\n ) {\n lc.debug?.('new client handler');\n this.#clientGroupID = clientGroupID;\n this.clientID = clientID;\n this.wsID = wsID;\n this.#zeroClientsTable = `${upstreamSchema(shard)}.clients`;\n this.#zeroMutationsTable = `${upstreamSchema(shard)}.mutations`;\n this.#lc = lc;\n this.#downstream = downstream;\n this.#baseVersion = cookieToVersion(baseCookie);\n }\n\n version(): NullableCVRVersion {\n return this.#baseVersion;\n }\n\n async #push(msg: Downstream): Promise<void> {\n const {result} = this.#downstream.push(msg);\n await result;\n }\n\n fail(e: unknown) {\n this.#lc[getLogLevel(e)]?.(\n `view-syncer closing connection with error: ${String(e)}`,\n e,\n );\n this.#downstream.fail(wrapWithProtocolError(e));\n }\n\n close(reason: string) {\n this.#lc.debug?.(`view-syncer closing connection: ${reason}`);\n this.#downstream.cancel();\n }\n\n startPoke(tentativeVersion: CVRVersion): PokeHandler {\n const pokeID = versionToCookie(tentativeVersion);\n const lc = this.#lc.withContext('pokeID', pokeID);\n\n if (cmpVersions(this.#baseVersion, tentativeVersion) >= 0) {\n lc.info?.(`already caught up, not sending poke.`);\n return NOOP;\n }\n\n const baseCookie = versionToNullableCookie(this.#baseVersion);\n const cookie = versionToCookie(tentativeVersion);\n lc.info?.(`starting poke from ${baseCookie} to ${cookie}`);\n\n const start = performance.now();\n\n const pokeStart: PokeStartBody = {pokeID, baseCookie};\n\n let pokeStarted = false;\n let body: PokePartBody | undefined;\n let partCount = 0;\n const ensureBody = async () => {\n if (!pokeStarted) {\n await this.#push(['pokeStart', pokeStart]);\n pokeStarted = true;\n }\n return (body ??= {pokeID});\n };\n const flushBody = async () => {\n if (body) {\n await this.#push(['pokePart', body]);\n body = undefined;\n partCount = 0;\n }\n };\n\n const addPatch = async (patchToVersion: PatchToVersion) => {\n const {patch, toVersion} = patchToVersion;\n if (cmpVersions(toVersion, this.#baseVersion) <= 0) {\n return;\n }\n const body = await ensureBody();\n\n const {type, op} = patch;\n switch (type) {\n case 'query': {\n const patches = patch.clientID\n ? ((body.desiredQueriesPatches ??= {})[patch.clientID] ??= [])\n : (body.gotQueriesPatch ??= []);\n if (op === 'put') {\n patches.push({op, hash: patch.id});\n } else {\n patches.push({op, hash: patch.id});\n }\n break;\n }\n case 'row':\n if (patch.id.table === this.#zeroClientsTable) {\n this.#updateLMIDs((body.lastMutationIDChanges ??= {}), patch);\n } else if (patch.id.table === this.#zeroMutationsTable) {\n const patches = (body.mutationsPatch ??= []);\n if (op === 'put') {\n const row = v.parse(\n ensureSafeJSON(patch.contents),\n mutationRowSchema,\n 'passthrough',\n );\n patches.push({\n op: 'put',\n mutation: {\n id: {\n clientID: row.clientID,\n id: row.mutationID,\n },\n result: row.result,\n },\n });\n } else {\n const {clientID, mutationID} = patch.id.rowKey;\n assert(\n typeof clientID === 'string',\n 'client id must be a string',\n );\n const id = Number(mutationID);\n assert(\n !Number.isNaN(id) && Number.isFinite(id) && id >= 0,\n 'mutation id must be a finite number',\n );\n patches.push({\n op: 'del',\n id: {\n clientID,\n id,\n },\n });\n }\n } else {\n (body.rowsPatch ??= []).push(makeRowPatch(patch));\n }\n break;\n default:\n unreachable(patch);\n }\n\n if (++partCount >= PART_COUNT_FLUSH_THRESHOLD) {\n await flushBody();\n }\n };\n\n return {\n addPatch: async (patchToVersion: PatchToVersion) => {\n try {\n await addPatch(patchToVersion);\n if (patchToVersion.patch.type === 'row') {\n this.#pokedRows.add(1);\n }\n } catch (e) {\n this.#downstream.fail(wrapWithProtocolError(e));\n }\n },\n\n cancel: async () => {\n if (pokeStarted) {\n await this.#push(['pokeEnd', {pokeID, cookie: '', cancel: true}]);\n }\n },\n\n end: async (finalVersion: CVRVersion) => {\n const cookie = versionToCookie(finalVersion);\n if (!pokeStarted) {\n if (cmpVersions(this.#baseVersion, finalVersion) === 0) {\n return; // Nothing changed and nothing was sent.\n }\n await this.#push(['pokeStart', pokeStart]);\n } else if (cmpVersions(this.#baseVersion, finalVersion) >= 0) {\n // Sanity check: If the poke was started, the finalVersion\n // must be > #baseVersion.\n throw new Error(\n `Patches were sent but finalVersion ${finalVersion} is ` +\n `not greater than baseVersion ${this.#baseVersion}`,\n );\n }\n await flushBody();\n await this.#push(['pokeEnd', {pokeID, cookie}]);\n this.#baseVersion = finalVersion;\n\n const elapsed = performance.now() - start;\n this.#pokeTransactions.add(1);\n this.#pokeTime.record(elapsed / 1000);\n },\n };\n }\n\n async sendDeleteClients(\n lc: LogContext,\n deletedClientIDs: string[],\n deletedClientGroupIDs: string[],\n ) {\n const deleteClientsBody: Writable<DeleteClientsBody> = {};\n if (deletedClientIDs.length > 0) {\n deleteClientsBody.clientIDs = deletedClientIDs;\n }\n if (deletedClientGroupIDs.length > 0) {\n deleteClientsBody.clientGroupIDs = deletedClientGroupIDs;\n }\n lc.debug?.('sending deleteClients', deleteClientsBody);\n await this.#push(['deleteClients', deleteClientsBody]);\n }\n\n sendQueryTransformApplicationErrors(errors: ErroredQuery[]) {\n void this.#push(['transformError', errors]);\n }\n\n sendQueryTransformFailedError(error: TransformFailedBody) {\n this.fail(new ProtocolError(error));\n }\n\n sendInspectResponse(lc: LogContext, response: InspectDownBody): void {\n lc.debug?.('sending inspect response', response);\n this.#downstream.push(['inspect', response]);\n }\n\n #updateLMIDs(lmids: Record<string, number>, patch: RowPatch) {\n if (patch.op === 'put') {\n const row = ensureSafeJSON(patch.contents);\n const {clientGroupID, clientID, lastMutationID} = v.parse(\n row,\n lmidRowSchema,\n 'passthrough',\n );\n if (clientGroupID !== this.#clientGroupID) {\n this.#lc.error?.(\n `Received clients row for wrong clientGroupID. Ignoring.`,\n clientGroupID,\n );\n } else {\n lmids[clientID] = lastMutationID;\n }\n } else {\n // The 'constrain' and 'del' ops for clients can be ignored.\n patch.op satisfies 'constrain' | 'del';\n }\n }\n}\n\n// Note: The {APP_ID}_{SHARD_ID}.clients table is set up in replicator/initial-sync.ts.\nconst lmidRowSchema = v.object({\n clientGroupID: v.string(),\n clientID: v.string(),\n lastMutationID: v.number(), // Actually returned as a bigint, but converted by ensureSafeJSON().\n});\n\nconst mutationRowSchema = v.object({\n clientGroupID: v.string(),\n clientID: v.string(),\n mutationID: v.number(),\n result: mutationResultSchema,\n});\n\nfunction makeRowPatch(patch: RowPatch): RowPatchOp {\n const {\n op,\n id: {table: tableName, rowKey: id},\n } = patch;\n\n switch (op) {\n case 'put':\n return {\n op: 'put',\n tableName,\n value: v.parse(ensureSafeJSON(patch.contents), rowSchema),\n };\n\n case 'del':\n return {\n op,\n tableName,\n id: v.parse(id, primaryKeyValueRecordSchema),\n };\n\n default:\n unreachable(op);\n }\n}\n\n/**\n * Column values of type INT8 are returned as the `bigint` from the\n * Postgres library. These are converted to `number` if they are within\n * the safe Number range, allowing the protocol to support numbers larger\n * than 32-bits. Values outside of the safe number range (e.g. > 2^53) will\n * result in an Error.\n */\nexport function ensureSafeJSON(row: JSONObject): SafeJSONObject {\n const modified = Object.entries(row)\n .filter(([k, v]) => {\n if (typeof v === 'bigint') {\n if (v >= Number.MIN_SAFE_INTEGER && v <= Number.MAX_SAFE_INTEGER) {\n return true; // send this entry onto the next map() step.\n }\n throw new Error(`Value of \"${k}\" exceeds safe Number range (${v})`);\n } else if (typeof v === 'object') {\n assertJSONValue(v);\n }\n return false;\n })\n .map(([k, v]) => [k, Number(v)]);\n\n return modified.length\n ? {...row, ...Object.fromEntries(modified)}\n : (row as SafeJSONObject);\n}\n"],"names":["body","v.parse","cookie","v.object","v.string","v.number","v"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cvr-store.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/cvr-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cvr-store.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/cvr-store.ts"],"names":[],"mappings":"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"}
@@ -239,12 +239,14 @@ class CVRStore {
239
239
  }
240
240
  for (const row of desiresRows) {
241
241
  const client = cvr.clients[row.clientID];
242
- if (client) {
243
- if (!row.deleted && row.inactivatedAt === null) {
242
+ if (!row.deleted && row.inactivatedAt === null) {
243
+ if (client) {
244
244
  client.desiredQueryIDs.push(row.queryHash);
245
+ } else {
246
+ lc.debug?.(
247
+ `Not adding to desiredQueryIDs for client ${row.clientID} because it has been deleted.`
248
+ );
245
249
  }
246
- } else {
247
- lc.debug?.(`Client ${row.clientID} not found`);
248
250
  }
249
251
  const query = cvr.queries[row.queryHash];
250
252
  if (query && query.type !== "internal" && (!row.deleted || row.inactivatedAt !== null)) {