@opendatalabs/personal-server-ts-server 1.34.1 → 1.34.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.
@@ -93745,10 +93745,6 @@ function withLegacyProjection(raw, options = {}) {
93745
93745
  return view ? (await builtBlocks(scope, view)).manifest : rawManifest(scope, collectedAt);
93746
93746
  };
93747
93747
  }
93748
- if (raw.hasScopeBlocks) {
93749
- const rawHas = raw.hasScopeBlocks.bind(raw);
93750
- overrides.hasScopeBlocks = async (scope, collectedAt) => await rawHas(scope, collectedAt) || await projected(scope, collectedAt) !== null;
93751
- }
93752
93748
  if (raw.canReadScopeBlocks) {
93753
93749
  const rawCan = raw.canReadScopeBlocks.bind(raw);
93754
93750
  overrides.canReadScopeBlocks = async (scope, collectedAt) => await rawCan(scope, collectedAt) || await projected(scope, collectedAt) !== null;
@@ -117422,6 +117418,27 @@ function isTombstoneRecord(record2) {
117422
117418
  var DEFAULT_SCOPE_DELETION_MAX_STALENESS_MS = 12e4;
117423
117419
  var DEFAULT_SCOPE_DELETION_GATEWAY_RETRY_MS = 15e3;
117424
117420
  var DEFAULT_MAX_LIVE_ENTRIES = 1e4;
117421
+ var DeletionLookupTimeout = class extends Error {
117422
+ };
117423
+ async function beforeDeadline(request2, timeoutMs, onTimeout) {
117424
+ if (timeoutMs === void 0)
117425
+ return request2;
117426
+ let timer;
117427
+ try {
117428
+ return await Promise.race([
117429
+ request2,
117430
+ new Promise((_11, reject) => {
117431
+ timer = setTimeout(() => {
117432
+ reject(new DeletionLookupTimeout("Deletion lookup deadline exceeded"));
117433
+ onTimeout?.();
117434
+ }, timeoutMs);
117435
+ })
117436
+ ]);
117437
+ } finally {
117438
+ if (timer !== void 0)
117439
+ clearTimeout(timer);
117440
+ }
117441
+ }
117425
117442
  function createScopeDeletionTracker(options = {}) {
117426
117443
  const maxStalenessMs = options.maxStalenessMs ?? DEFAULT_SCOPE_DELETION_MAX_STALENESS_MS;
117427
117444
  const gatewayRetryMs = options.gatewayRetryMs ?? DEFAULT_SCOPE_DELETION_GATEWAY_RETRY_MS;
@@ -117494,24 +117511,32 @@ function createScopeDeletionTracker(options = {}) {
117494
117511
  rememberLive(scope, nowMs2());
117495
117512
  return { deleted: false, source: "gateway", verified: true };
117496
117513
  }
117497
- async function lookup2(scope) {
117514
+ async function lookup2(scope, timeoutMs) {
117498
117515
  const feed = options.feed;
117499
117516
  const owner = options.serverOwner;
117500
- if (!feed || !owner)
117517
+ if (!feed || !owner || timeoutMs !== void 0 && timeoutMs <= 0)
117501
117518
  return null;
117502
117519
  if (lastGatewayFailureMs !== null && nowMs2() - lastGatewayFailureMs < gatewayRetryMs) {
117503
117520
  return null;
117504
117521
  }
117505
117522
  const pending = inflight.get(scope);
117506
- if (pending)
117507
- return pending;
117523
+ if (pending) {
117524
+ return beforeDeadline(pending, timeoutMs).catch((error51) => {
117525
+ if (error51 instanceof DeletionLookupTimeout)
117526
+ return null;
117527
+ throw error51;
117528
+ });
117529
+ }
117530
+ const deletionAtStart = deleted.get(scope);
117508
117531
  const request2 = (async () => {
117509
117532
  let record2;
117533
+ const controller = timeoutMs === void 0 ? void 0 : new AbortController();
117510
117534
  try {
117511
- record2 = await feed.getDataPoint({
117535
+ record2 = await beforeDeadline(feed.getDataPoint({
117512
117536
  ownerAddress: owner,
117513
- scope
117514
- });
117537
+ scope,
117538
+ ...controller ? { signal: controller.signal } : {}
117539
+ }), timeoutMs, () => controller?.abort());
117515
117540
  lastGatewayFailureMs = null;
117516
117541
  } catch (err2) {
117517
117542
  lastGatewayFailureMs = nowMs2();
@@ -117522,11 +117547,23 @@ function createScopeDeletionTracker(options = {}) {
117522
117547
  }, "Could not check gateway deletion state; serving last known state");
117523
117548
  return null;
117524
117549
  }
117550
+ if (deleted.get(scope) !== deletionAtStart)
117551
+ return lastKnownVerdict(scope);
117525
117552
  return verdictFromRecord(scope, record2);
117526
117553
  })().finally(() => inflight.delete(scope));
117527
117554
  inflight.set(scope, request2);
117528
117555
  return request2;
117529
117556
  }
117557
+ function lastKnownVerdict(scope) {
117558
+ const known = deleted.get(scope);
117559
+ return known ? {
117560
+ deleted: true,
117561
+ deletedAt: known.deletedAt,
117562
+ version: known.version,
117563
+ source: known.source,
117564
+ verified: false
117565
+ } : { deleted: false, source: "assumed-live", verified: false };
117566
+ }
117530
117567
  return {
117531
117568
  maxStalenessMs,
117532
117569
  deletionHistory,
@@ -117565,16 +117602,10 @@ function createScopeDeletionTracker(options = {}) {
117565
117602
  verified: true
117566
117603
  };
117567
117604
  }
117568
- const rechecked = await lookup2(scope);
117605
+ const rechecked = await lookup2(scope, resolveOptions?.gatewayTimeoutMs);
117569
117606
  if (rechecked !== null)
117570
117607
  return rechecked;
117571
- return {
117572
- deleted: true,
117573
- deletedAt: known.deletedAt,
117574
- version: known.version,
117575
- source: known.source,
117576
- verified: false
117577
- };
117608
+ return lastKnownVerdict(scope);
117578
117609
  }
117579
117610
  if (isFresh(live.get(scope) ?? null)) {
117580
117611
  return { deleted: false, source: "gateway", verified: true };
@@ -117583,11 +117614,7 @@ function createScopeDeletionTracker(options = {}) {
117583
117614
  if (consult === "if-stale" && isFresh(lastFeedSyncMs)) {
117584
117615
  return { deleted: false, source: "feed", verified: true };
117585
117616
  }
117586
- return await lookup2(scope) ?? {
117587
- deleted: false,
117588
- source: "assumed-live",
117589
- verified: false
117590
- };
117617
+ return await lookup2(scope, resolveOptions?.gatewayTimeoutMs) ?? lastKnownVerdict(scope);
117591
117618
  }
117592
117619
  };
117593
117620
  }
@@ -118655,11 +118682,12 @@ async function parseProducerProvenance(encoded, body) {
118655
118682
  return errorResponse(400, "INVALID_PROVENANCE", "Vana-Producer-Provenance is not base64url JSON");
118656
118683
  }
118657
118684
  }
118658
- async function resolveReadDeletion(deps, scope, entry, body = "file") {
118685
+ async function resolveReadDeletion(deps, scope, entry, body = "file", gatewayTimeoutMs) {
118659
118686
  if (!deps.scopeDeletions)
118660
118687
  return null;
118661
118688
  const verdict = await deps.scopeDeletions.resolve(scope, {
118662
- consultGateway: entry ? "if-stale" : "always"
118689
+ consultGateway: entry ? "if-stale" : "always",
118690
+ ...gatewayTimeoutMs === void 0 ? {} : { gatewayTimeoutMs }
118663
118691
  });
118664
118692
  const tombstone = body === "canonical" ? deps.scopeDeletions.deletionHistory?.get(scope) ?? (verdict.deleted ? verdict : null) : verdict.deleted ? verdict : null;
118665
118693
  if (!tombstone)
@@ -118683,8 +118711,8 @@ function discoveryVisibility(deps) {
118683
118711
  return void 0;
118684
118712
  return async (scope, entry) => await resolveReadDeletion(deps, scope, entry) === null;
118685
118713
  }
118686
- function listingVisibility(deps) {
118687
- const deletion = discoveryVisibility(deps);
118714
+ function listingVisibility(deps, deadlineAtMs) {
118715
+ const deletion = deps.scopeDeletions ? async (scope, entry) => await resolveReadDeletion(deps, scope, entry, "file", Math.max(0, deadlineAtMs - Date.now())) === null : void 0;
118688
118716
  const view = deps.legacyScopeView;
118689
118717
  if (!view)
118690
118718
  return deletion;
@@ -118693,10 +118721,10 @@ function listingVisibility(deps) {
118693
118721
  if (listing.kind === "refused")
118694
118722
  return false;
118695
118723
  const canonicalOwned = view.ownsScope(scope);
118696
- return await resolveReadDeletion(deps, scope, canonicalOwned ? void 0 : entry, canonicalOwned ? "canonical" : "file") === null;
118724
+ return await resolveReadDeletion(deps, scope, canonicalOwned ? void 0 : entry, canonicalOwned ? "canonical" : "file", Math.max(0, deadlineAtMs - Date.now())) === null;
118697
118725
  };
118698
118726
  }
118699
- function canonicalOnlyScopes(deps) {
118727
+ function canonicalOnlyScopes(deps, deadlineAtMs) {
118700
118728
  const view = deps.legacyScopeView;
118701
118729
  if (!view)
118702
118730
  return void 0;
@@ -118705,7 +118733,7 @@ function canonicalOnlyScopes(deps) {
118705
118733
  for (const { scope, collectedAt } of view.listCanonicalScopes(scopePrefix)) {
118706
118734
  if (stored.has(scope))
118707
118735
  continue;
118708
- if (await resolveReadDeletion(deps, scope, void 0, "canonical") !== null) {
118736
+ if (await resolveReadDeletion(deps, scope, void 0, "canonical", Math.max(0, deadlineAtMs - Date.now())) !== null) {
118709
118737
  continue;
118710
118738
  }
118711
118739
  listed.push({ scope, latestCollectedAt: collectedAt, versionCount: 0 });
@@ -118907,14 +118935,15 @@ async function handlePersonalServerDataRequest(request2, deps, options = {}) {
118907
118935
  const listAuth = await deps.auth.authorizeBuilderList(request2, {
118908
118936
  grantId: selectedGrantId(request2, url2)
118909
118937
  });
118938
+ const deletionDeadlineAtMs = Date.now() + 250;
118910
118939
  const result = await listDataScopesContract({
118911
118940
  storage: deps.storage,
118912
118941
  scopePrefix: url2.searchParams.get("scopePrefix") ?? void 0,
118913
118942
  limit: normalizeLimit2(url2.searchParams.get("limit"), 20),
118914
118943
  offset: normalizeLimit2(url2.searchParams.get("offset"), 0),
118915
- isVisible: listingVisibility(deps),
118944
+ isVisible: listingVisibility(deps, deletionDeadlineAtMs),
118916
118945
  isListable: (scope) => !isSystemScope(scope) && (!listAuth || listAuthCovers(listAuth, scope)),
118917
- extraScopes: canonicalOnlyScopes(deps)
118946
+ extraScopes: canonicalOnlyScopes(deps, deletionDeadlineAtMs)
118918
118947
  });
118919
118948
  return jsonResponse({
118920
118949
  ...result.response,
@@ -120628,6 +120657,7 @@ function normalizeState(state) {
120628
120657
  schemaId: entry.schemaId ?? null
120629
120658
  })),
120630
120659
  envelopes: state.envelopes,
120660
+ readyBlockManifests: state.readyBlockManifests ?? [],
120631
120661
  blockManifests: state.blockManifests ?? [],
120632
120662
  blockPayloads: state.blockPayloads ?? [],
120633
120663
  ...state.pendingLedgerDeletes?.length ? { pendingLedgerDeletes: state.pendingLedgerDeletes } : {}
@@ -120877,6 +120907,10 @@ async function createPersistentPsLiteStorage(adapter, persistence = createIndexe
120877
120907
  envelope
120878
120908
  ]));
120879
120909
  const fallbackBlockManifests = new Map((state.blockManifests ?? []).map(({ path, manifest }) => [path, manifest]));
120910
+ const readyBlockManifests = /* @__PURE__ */ new Set([
120911
+ ...state.readyBlockManifests ?? [],
120912
+ ...fallbackBlockManifests.keys()
120913
+ ]);
120880
120914
  const fallbackBlockPayloads = new Map((state.blockPayloads ?? []).map(({ path, block }) => [path, block]));
120881
120915
  const ledgerAux = (scope) => `first-seen:${scope}`;
120882
120916
  const firstSeenLedgers = /* @__PURE__ */ new Map();
@@ -120892,6 +120926,7 @@ async function createPersistentPsLiteStorage(adapter, persistence = createIndexe
120892
120926
  async function persist() {
120893
120927
  const snapshot = {
120894
120928
  ...state,
120929
+ readyBlockManifests: Array.from(readyBlockManifests),
120895
120930
  envelopes: fileStore.kind === "indexeddb" ? Array.from(fallbackEnvelopes.values()) : [],
120896
120931
  blockManifests: Array.from(fallbackBlockManifests.entries()).map(([path, manifest]) => ({ path, manifest })),
120897
120932
  blockPayloads: Array.from(fallbackBlockPayloads.entries()).map(([path, block]) => ({ path, block })),
@@ -121054,7 +121089,7 @@ async function createPersistentPsLiteStorage(adapter, persistence = createIndexe
121054
121089
  return await fileStore.readBlockManifest?.(manifestPath) ?? (fileStore === fallbackStore ? null : await fallbackStore.readBlockManifest?.(manifestPath)) ?? null;
121055
121090
  },
121056
121091
  async hasScopeBlocks(scope, collectedAt) {
121057
- return Boolean(await storagePort.readBlockManifest?.(scope, collectedAt));
121092
+ return readyBlockManifests.has(blockManifestPath(scope, collectedAt));
121058
121093
  },
121059
121094
  async canReadScopeBlocks(scope, collectedAt) {
121060
121095
  if (await storagePort.hasScopeBlocks?.(scope, collectedAt)) {
@@ -121068,6 +121103,8 @@ async function createPersistentPsLiteStorage(adapter, persistence = createIndexe
121068
121103
  return Boolean(envelope);
121069
121104
  },
121070
121105
  async writeBlockManifest(scope, collectedAt, manifest, blocks) {
121106
+ readyBlockManifests.delete(blockManifestPath(scope, collectedAt));
121107
+ await persist();
121071
121108
  const writeTree = async (store) => {
121072
121109
  if (!store.writeBlockManifest || !store.writeBlockPayload) {
121073
121110
  throw new Error("Block sidecar storage is not available");
@@ -121098,6 +121135,7 @@ async function createPersistentPsLiteStorage(adapter, persistence = createIndexe
121098
121135
  if (wrotePrimary && fileStore.kind !== "indexeddb") {
121099
121136
  await fallbackStore.deleteBlockTree?.(blockTreePath(scope, collectedAt));
121100
121137
  }
121138
+ readyBlockManifests.add(blockManifestPath(scope, collectedAt));
121101
121139
  await persist();
121102
121140
  },
121103
121141
  async insertEntry(entry) {
@@ -121195,6 +121233,10 @@ async function createPersistentPsLiteStorage(adapter, persistence = createIndexe
121195
121233
  deleteScope(scope) {
121196
121234
  return withScopeLock(scope, async () => {
121197
121235
  await dropLedger(scope);
121236
+ for (const entry of entriesForScope(scope)) {
121237
+ readyBlockManifests.delete(blockManifestPath(scope, entry.collectedAt));
121238
+ }
121239
+ await persist();
121198
121240
  let deleted = 0;
121199
121241
  const deletedPaths = [];
121200
121242
  const deletedBlockTrees = [];
@@ -121266,6 +121308,8 @@ async function createPersistentPsLiteStorage(adapter, persistence = createIndexe
121266
121308
  }
121267
121309
  async function removeEntryLocked(entry) {
121268
121310
  const blobPath = envelopePath(entry.scope, entry.collectedAt);
121311
+ readyBlockManifests.delete(blockManifestPath(entry.scope, entry.collectedAt));
121312
+ await persist();
121269
121313
  await Promise.all([
121270
121314
  fileStore.deleteEnvelope(blobPath),
121271
121315
  fallbackStore.deleteEnvelope(blobPath),
@@ -140164,6 +140208,7 @@ function createGatewayDataPointFeed(options) {
140164
140208
  const url2 = `${base}${uri}?includeDeleted=true`;
140165
140209
  const ownerSigner = isSystemScope(input.scope) ? options.ownerRequestSigner : void 0;
140166
140210
  const res = ownerSigner ? await fetchImpl(url2, {
140211
+ ...input.signal ? { signal: input.signal } : {},
140167
140212
  headers: {
140168
140213
  Authorization: await ownerSigner.signRequest({
140169
140214
  aud: new URL(base).origin,
@@ -140171,7 +140216,7 @@ function createGatewayDataPointFeed(options) {
140171
140216
  uri
140172
140217
  })
140173
140218
  }
140174
- }) : await fetchImpl(url2);
140219
+ }) : input.signal ? await fetchImpl(url2, { signal: input.signal }) : await fetchImpl(url2);
140175
140220
  if (res.status === 404)
140176
140221
  return null;
140177
140222
  if (res.status === 410) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opendatalabs/personal-server-ts-server",
3
- "version": "1.34.1",
3
+ "version": "1.34.2",
4
4
  "description": "Hono HTTP server for the Vana Personal Server — routes, middleware, composition root",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -55,8 +55,8 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "@hono/node-server": "^1.19.17",
58
- "@opendatalabs/personal-server-ts-core": "1.34.1",
59
- "@opendatalabs/personal-server-ts-lite": "1.34.1",
58
+ "@opendatalabs/personal-server-ts-core": "1.34.2",
59
+ "@opendatalabs/personal-server-ts-lite": "1.34.2",
60
60
  "@opendatalabs/vana-sdk": "3.23.0-pr.211.36da1d8",
61
61
  "ajv": "^8.20.0",
62
62
  "better-sqlite3": "^12.11.1",