@davesheffer/hunch 1.20.0-rc.2 → 1.20.0-rc.3

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.
@@ -197,6 +197,37 @@ export class HunchStore {
197
197
  }
198
198
  return home === "private" ? this.putPrivate(kind, record) : this.json.put(kind, record);
199
199
  }
200
+ /** Replace one capture kind in its routed home as a single bulk operation.
201
+ *
202
+ * Snapshot producers use this instead of calling putCapture once per record.
203
+ * That distinction is material for array-backed graph kinds: repeated puts
204
+ * parse, sort, and atomically rewrite the complete index for every symbol or
205
+ * edge, while JsonStore.replaceAll validates the full input before performing
206
+ * one write. Routing and cross-home collision rules remain identical to an
207
+ * ordinary capture, so the optimization cannot create a second source of truth.
208
+ */
209
+ replaceCaptures(kind, records, isPrivate = false) {
210
+ const home = this.captureHome(isPrivate);
211
+ const target = home === "private" ? this.privateJson : this.json;
212
+ if (!target) {
213
+ throw new Error("No private store configured — set HUNCH_PRIVATE_DIR to a directory Hunch can write sensitive records into.");
214
+ }
215
+ const targetIds = new Set(target.loadAll(kind).map((record) => record.id));
216
+ const other = home === "private" ? this.json : this.privateJson;
217
+ const otherIds = new Set((other?.loadAll(kind) ?? []).map((record) => record.id));
218
+ const incomingIds = new Set();
219
+ for (const record of records) {
220
+ const id = record.id;
221
+ if (incomingIds.has(id))
222
+ throw new Error(`${kind} replacement contains duplicate record id ${id}`);
223
+ incomingIds.add(id);
224
+ if (!targetIds.has(id) && otherIds.has(id)) {
225
+ throw new Error(`${kind} record ${id} already exists in the other memory home; refusing to create a public/private id collision`);
226
+ }
227
+ }
228
+ target.ensureDirs();
229
+ target.replaceAll(kind, records);
230
+ }
200
231
  /** Read a record by id from wherever it lives (private overlay wins on collision). */
201
232
  getRec(kind, id) {
202
233
  return this.privateJson?.get(kind, id) ?? this.json.get(kind, id);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davesheffer/hunch",
3
- "version": "1.20.0-rc.2",
3
+ "version": "1.20.0-rc.3",
4
4
  "mcpName": "io.github.davesheffer/hunch",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Dave Sheffer <dave.sheffer1@gmail.com>",
package/server.json CHANGED
@@ -7,13 +7,13 @@
7
7
  "source": "github"
8
8
  },
9
9
  "websiteUrl": "https://hunch-pi.vercel.app",
10
- "version": "1.20.0-rc.2",
10
+ "version": "1.20.0-rc.3",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "registryBaseUrl": "https://registry.npmjs.org",
15
15
  "identifier": "@davesheffer/hunch",
16
- "version": "1.20.0-rc.2",
16
+ "version": "1.20.0-rc.3",
17
17
  "runtimeHint": "npx",
18
18
  "packageArguments": [
19
19
  {