@hatk/hatk 0.0.1-alpha.64 → 0.0.1-alpha.65

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.
@@ -1,3 +1,13 @@
1
+ /**
2
+ * The collections whose local rows a full re-import may purge before
3
+ * re-inserting from the repo CAR.
4
+ *
5
+ * Private collections are AppView-authoritative and never present in a repo:
6
+ * purging their rows would destroy data the re-import can never restore (this
7
+ * happened — a login-triggered backfill wiped a deployment's activity rows).
8
+ * Exported for tests.
9
+ */
10
+ export declare function purgeableCollections(collections: Iterable<string>): string[];
1
11
  import type { BackfillConfig } from './config.ts';
2
12
  /** Options passed to {@link runBackfill}. */
3
13
  interface BackfillOpts {
@@ -1 +1 @@
1
- {"version":3,"file":"backfill.d.ts","sourceRoot":"","sources":["../src/backfill.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAIjD,6CAA6C;AAC7C,UAAU,YAAY;IACpB,wFAAwF;IACxF,MAAM,EAAE,MAAM,CAAA;IACd,8FAA8F;IAC9F,MAAM,EAAE,MAAM,CAAA;IACd,yEAAyE;IACzE,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACxB,wDAAwD;IACxD,MAAM,EAAE,cAAc,CAAA;CACvB;AA+FD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkK/G;AA8BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAkIrE"}
1
+ {"version":3,"file":"backfill.d.ts","sourceRoot":"","sources":["../src/backfill.ts"],"names":[],"mappings":"AAiBA;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAE5E;AAGD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAIjD,6CAA6C;AAC7C,UAAU,YAAY;IACpB,wFAAwF;IACxF,MAAM,EAAE,MAAM,CAAA;IACd,8FAA8F;IAC9F,MAAM,EAAE,MAAM,CAAA;IACd,yEAAyE;IACzE,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACxB,wDAAwD;IACxD,MAAM,EAAE,cAAc,CAAA;CACvB;AA+FD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkK/G;AA8BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAkIrE"}
package/dist/backfill.js CHANGED
@@ -2,6 +2,19 @@ import { parseCarStream } from "./car.js";
2
2
  import { cborDecode } from "./cbor.js";
3
3
  import { walkMst } from "./mst.js";
4
4
  import { setRepoStatus, getRepoStatus, getRepoRev, getRepoRetryInfo, listRetryEligibleRepos, listPendingRepos, querySQL, runSQL, getSchema, bulkInsertRecords, } from "./database/db.js";
5
+ import { isPrivateCollection } from "./private-collections.js";
6
+ /**
7
+ * The collections whose local rows a full re-import may purge before
8
+ * re-inserting from the repo CAR.
9
+ *
10
+ * Private collections are AppView-authoritative and never present in a repo:
11
+ * purging their rows would destroy data the re-import can never restore (this
12
+ * happened — a login-triggered backfill wiped a deployment's activity rows).
13
+ * Exported for tests.
14
+ */
15
+ export function purgeableCollections(collections) {
16
+ return [...collections].filter((c) => !isPrivateCollection(c));
17
+ }
5
18
  import { emit, timer } from "./logger.js";
6
19
  import { validateRecord } from '@bigmoves/lexicon';
7
20
  import { getLexiconArray } from "./database/schema.js";
@@ -177,7 +190,7 @@ export async function backfillRepo(did, collections, fetchTimeout) {
177
190
  // Delete existing records for this DID before re-importing so deletions are reflected
178
191
  // Only on full imports (no since) — diff CARs only contain changes
179
192
  if (!lastRev) {
180
- for (const col of collections) {
193
+ for (const col of purgeableCollections(collections)) {
181
194
  const schema = getSchema(col);
182
195
  if (!schema)
183
196
  continue;
@@ -198,7 +211,7 @@ export async function backfillRepo(did, collections, fetchTimeout) {
198
211
  const validationSkips = {};
199
212
  for (const entry of entries) {
200
213
  const collection = entry.path.split('/')[0];
201
- if (!collections.has(collection))
214
+ if (!collections.has(collection) || isPrivateCollection(collection))
202
215
  continue;
203
216
  const blockData = blocks.get(entry.cid);
204
217
  if (!blockData)
@@ -1 +1 @@
1
- {"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAsKA;;;;;;;GAOG;AACH,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGxD;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,SAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CA8EjF;AAED,8CAA8C;AAC9C,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACxB,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC/B,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAyBD;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAoDxE"}
1
+ {"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAuKA;;;;;;;GAOG;AACH,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGxD;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,SAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CA8EjF;AAED,8CAA8C;AAC9C,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACxB,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC/B,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAyBD;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAoDxE"}
package/dist/indexer.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { cborDecode } from "./cbor.js";
2
2
  import { parseCarFrame } from "./car.js";
3
+ import { isPrivateCollection } from "./private-collections.js";
3
4
  import { insertRecord, deleteRecord, setCursor, setRepoStatus, getRepoRetryInfo, listAllRepoStatuses, getDatabasePort, updateRepoHandle, } from "./database/db.js";
4
5
  import { backfillRepo } from "./backfill.js";
5
6
  import { rebuildAllIndexes } from "./database/fts.js";
@@ -387,7 +388,13 @@ function processMessage(bytes, collections) {
387
388
  if (indexerPinnedRepos && !indexerPinnedRepos.has(did))
388
389
  return;
389
390
  // Check if any ops in this commit are for collections we care about
390
- const relevantOps = body.value.ops.filter((op) => collections.has(op.path.split('/')[0]));
391
+ // Private collections are AppView-authoritative: nothing on the network may
392
+ // write or delete their rows, so firehose ops naming them are spoofed by
393
+ // definition and must be dropped.
394
+ const relevantOps = body.value.ops.filter((op) => {
395
+ const collection = op.path.split('/')[0];
396
+ return collections.has(collection) && !isPrivateCollection(collection);
397
+ });
391
398
  if (relevantOps.length === 0)
392
399
  return;
393
400
  // Copy blocks out of the original buffer before it can be GC'd
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hatk/hatk",
3
- "version": "0.0.1-alpha.64",
3
+ "version": "0.0.1-alpha.65",
4
4
  "license": "MIT",
5
5
  "bin": {
6
6
  "hatk": "dist/cli.js"