@kehto/paja 0.16.2 → 0.16.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.
package/README.md CHANGED
@@ -186,7 +186,8 @@ When `PAJA_UPLOAD_SERVERS` is set, the runtime enables the Blossom upload rail
186
186
  and also makes those servers explicit NAP-RESOURCE fallbacks. It is not needed
187
187
  for read-side discovery: resources learned through OUTBOX use their event hints
188
188
  and hinted-author/publisher server lists first, then the active shell user's
189
- published list.
189
+ published list, the current window's verified pointer-manifest servers, and
190
+ finally configured runtime fallbacks.
190
191
 
191
192
  ## Installed intent handlers and delivery
192
193
 
@@ -324,8 +325,8 @@ without prefetching bytes. Resolution tries request and
324
325
  event-local server hints first, then lazily queries hinted authors' and the
325
326
  event publisher's newest BUD-03 kind `10063` lists through the verified
326
327
  NIP-65-aware OUTBOX router, then queries the active shell user's BUD-03 list
327
- through that same router, then uses host-configured runtime-pointer and
328
- upload-runtime fallbacks. The user-list
328
+ through that same router, then uses the current window's verified
329
+ pointer-manifest servers, followed by upload-runtime fallbacks. The user-list
329
330
  lookup works independently of upload mode; an upload runtime may reuse the same
330
331
  servers when present. ROM-specific event and publisher locations retain
331
332
  priority over the user/runtime fallbacks. The combined list is capped at eight
@@ -333,8 +334,14 @@ candidates. The only accepted identifier is `blossom:sha256:<hex>`;
333
334
  Paja refuses redirects, verifies the requested SHA-256, and permits plain-HTTP
334
335
  transport only for configured loopback development defaults. Browser-only Paja
335
336
  cannot pin DNS results, so production runtimes must add the draft's DNS-time
336
- private-address checks. This behavior targets draft
337
- [NAP-RESOURCE at `9511232`](https://github.com/napplet/naps/blob/9511232f69313aa7953d110e35d32cc28d506f66/naps/NAP-RESOURCE.md), with the merged package implementation
337
+ private-address checks. The current
338
+ [NAP-RESOURCE draft at `fa6bcc6`](https://github.com/napplet/naps/blob/fa6bcc6935aa19e7b70ab2a2c721dafca77c78e1/naps/NAP-RESOURCE.md)
339
+ assigns fetching and policy to the runtime and defines no wire-level Blossom
340
+ server-hint field. Retaining verified manifest servers per window is therefore
341
+ Paja host policy, informed by the current
342
+ [NIP-5D draft at `24711d9`](https://github.com/nostr-protocol/nips/blob/24711d9c47bbdd07908bf1d52bf677d9cbc530f0/5D.md),
343
+ which defines manifest `server` tags. The existing request-server compatibility
344
+ path comes from the earlier NAP-RESOURCE draft at `9511232`, with the merged package implementation
338
345
  [`napplet/web#206@19e0029b`](https://github.com/napplet/web/pull/206) released as
339
346
  `@napplet/core`/`@napplet/nap` 0.32.0, `@napplet/shim` 0.30.0, and
340
347
  `@napplet/sdk` 0.28.0. Publisher discovery follows
@@ -17220,6 +17220,7 @@ function createPajaBlossomEventResolver(options) {
17220
17220
  const now2 = options.now ?? Date.now;
17221
17221
  const ttl = Math.max(0, options.serverListTtlMs ?? DEFAULT_SERVER_LIST_TTL_MS);
17222
17222
  const windows = /* @__PURE__ */ new Map();
17223
+ const windowServers = /* @__PURE__ */ new Map();
17223
17224
  const serverLists = /* @__PURE__ */ new Map();
17224
17225
  const pendingServerLists = /* @__PURE__ */ new Map();
17225
17226
  function observe(windowId, results) {
@@ -17297,9 +17298,20 @@ function createPajaBlossomEventResolver(options) {
17297
17298
  );
17298
17299
  for (const list of lists) appendUnique(servers, list);
17299
17300
  }
17301
+ if (windowId) appendUnique(servers, windowServers.get(windowId) ?? []);
17300
17302
  appendUnique(servers, options.getConfiguredServers());
17301
17303
  return servers.slice(0, PAJA_RESOURCE_MAX_SERVERS);
17302
17304
  }
17305
+ function setWindowServers(windowId, servers) {
17306
+ if (!windowId) return;
17307
+ const normalized = [];
17308
+ for (const value of servers) {
17309
+ const server = normalizePublicBlossomServer(value);
17310
+ if (server) appendUnique(normalized, [server]);
17311
+ }
17312
+ if (normalized.length > 0) windowServers.set(windowId, normalized);
17313
+ else windowServers.delete(windowId);
17314
+ }
17303
17315
  async function discoverServerList(pubkey2) {
17304
17316
  const cached = serverLists.get(pubkey2);
17305
17317
  if (cached && cached.expiresAt > now2()) return [...cached.servers];
@@ -17344,7 +17356,11 @@ function createPajaBlossomEventResolver(options) {
17344
17356
  observe,
17345
17357
  decorate,
17346
17358
  getServers,
17347
- clearWindow: (windowId) => windows.delete(windowId)
17359
+ setWindowServers,
17360
+ clearWindow(windowId) {
17361
+ windows.delete(windowId);
17362
+ windowServers.delete(windowId);
17363
+ }
17348
17364
  };
17349
17365
  }
17350
17366
  function extractEventResourceLocations(event) {
@@ -20240,7 +20256,11 @@ function createDevServices(backend, getSimulation, relayConfig, onThemeService,
20240
20256
  return wasWebrtcEnabled !== webrtcEnabled || dmChanged;
20241
20257
  }
20242
20258
  refreshAvailability();
20243
- return { services, refreshAvailability };
20259
+ return {
20260
+ services,
20261
+ refreshAvailability,
20262
+ setWindowBlossomServers: blossomEventResolver.setWindowServers
20263
+ };
20244
20264
  }
20245
20265
  function createPajaAdapter(config, getSimulation, onThemeService, onThemeBroadcast, confirmRequest, signerProvider, getIdentity, onEnvironmentChanged, intentHost, userActivation, notifyOptions, configOptions) {
20246
20266
  const resolveIdentity = (windowId) => getIdentity?.(windowId) ?? {
@@ -20308,6 +20328,7 @@ function createPajaAdapter(config, getSimulation, onThemeService, onThemeBroadca
20308
20328
  });
20309
20329
  return {
20310
20330
  ready,
20331
+ setWindowBlossomServers: serviceBundle.setWindowBlossomServers,
20311
20332
  relayPool: createPajaRelayHooks(relayBackend, getSimulation, relayConfig),
20312
20333
  relayConfig,
20313
20334
  windowManager: { createWindow: () => null },
@@ -20400,7 +20421,7 @@ async function resolvePajaPointer(value, options = {}) {
20400
20421
  const ownsPool = options.pool === void 0;
20401
20422
  try {
20402
20423
  const event = await resolvePointerEvent(pointer, pool, relays, normalizeMaxWaitMs(options.maxWaitMs));
20403
- const blossomServers = [...options.blossomServers ?? []];
20424
+ const blossomServers = resolvePointerBlossomServers(event, options.blossomServers ?? []);
20404
20425
  const resolved = await resolveNapplet({
20405
20426
  event,
20406
20427
  cache: await openNappletArtifactCache({ requireStorageEstimate: false }),
@@ -20427,6 +20448,20 @@ async function resolvePajaPointer(value, options = {}) {
20427
20448
  }
20428
20449
  }
20429
20450
  }
20451
+ function resolvePointerBlossomServers(event, configured) {
20452
+ const servers = [];
20453
+ for (const value of event.tags.flatMap(
20454
+ (tag) => tag[0] === "server" && tag[1] ? [tag[1]] : []
20455
+ )) {
20456
+ const normalized = normalizePublicBlossomServer(value);
20457
+ if (normalized && !servers.includes(normalized)) servers.push(normalized);
20458
+ }
20459
+ for (const value of configured) {
20460
+ const server = normalizePublicBlossomServer(value) ?? value;
20461
+ if (!servers.includes(server)) servers.push(server);
20462
+ }
20463
+ return servers;
20464
+ }
20430
20465
  function injectPajaRuntimeCsp(html, origins) {
20431
20466
  const grantedOrigins = [...new Set(origins)].sort();
20432
20467
  const connectSrc = grantedOrigins.length > 0 ? `connect-src ${grantedOrigins.join(" ")}` : "connect-src 'none'";
@@ -21852,6 +21887,9 @@ function resolvedTargetKey(target) {
21852
21887
  function runtimeTabGenerationId(tab) {
21853
21888
  return `${tab.id}:${tab.generation}`;
21854
21889
  }
21890
+ function bindRuntimeTabBlossomServers(adapter, windowId, resolvedTarget) {
21891
+ adapter.setWindowBlossomServers(windowId, resolvedTarget.blossomServers);
21892
+ }
21855
21893
  function getActiveTab(state) {
21856
21894
  return state.tabs.find((tab) => tab.id === state.activeTabId) ?? null;
21857
21895
  }
@@ -22129,23 +22167,25 @@ function startRuntimeTabNavigation(tab, state, context) {
22129
22167
  tab.status = "booting";
22130
22168
  context.setStatus(state, "booting");
22131
22169
  renderRuntimeTabs(state);
22170
+ const windowId = runtimeTabWindowId(context.config, tab);
22171
+ bindRuntimeTabBlossomServers(context.adapter, windowId, tab.resolvedTarget);
22132
22172
  void context.navigateFrame(
22133
22173
  tab.frame,
22134
22174
  context.config,
22135
22175
  generation,
22136
22176
  context.adapter,
22137
22177
  tab.resolvedTarget,
22138
- runtimeTabWindowId(context.config, tab),
22178
+ windowId,
22139
22179
  () => tab.generation === generation,
22140
- (windowId) => {
22180
+ (windowId2) => {
22141
22181
  if (tab.generation !== generation) return;
22142
- tab.windowId = windowId;
22143
- if (state.activeTabId === tab.id) context.runtime.currentWindowId = windowId;
22182
+ tab.windowId = windowId2;
22183
+ if (state.activeTabId === tab.id) context.runtime.currentWindowId = windowId2;
22144
22184
  }
22145
- ).then((windowId) => {
22185
+ ).then((windowId2) => {
22146
22186
  if (tab.generation !== generation) return;
22147
- tab.windowId = windowId;
22148
- if (state.activeTabId === tab.id) context.runtime.currentWindowId = windowId;
22187
+ tab.windowId = windowId2;
22188
+ if (state.activeTabId === tab.id) context.runtime.currentWindowId = windowId2;
22149
22189
  }).catch((error) => {
22150
22190
  if (tab.generation !== generation) return;
22151
22191
  tab.frame.removeAttribute("src");