@kehto/paja 0.3.2 → 0.3.4

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,4 +1,4 @@
1
- // ../acl/dist/chunk-6GH7LZSY.js
1
+ // ../acl/dist/chunk-ZI6GTKYN.js
2
2
  var ALL_CAPABILITIES = [
3
3
  // v1.1 kept:
4
4
  "relay:read",
@@ -34,7 +34,11 @@ var ALL_CAPABILITIES = [
34
34
  // handlers introspection (and receipt of shell pushes); write = invoke (the
35
35
  // focus-stealing cross-napplet dispatch op).
36
36
  "intent:read",
37
- "intent:write"
37
+ "intent:write",
38
+ // NAP-DM — runtime-mediated direct messages: read = status/conversations/
39
+ // messages/subscribe/unsubscribe and receive pushes; write = send.
40
+ "dm:read",
41
+ "dm:write"
38
42
  ];
39
43
 
40
44
  // ../acl/dist/index.js
@@ -224,7 +228,7 @@ function configMap(action) {
224
228
  return { senderCap: "config:read", recipientCap: null };
225
229
  }
226
230
  function resourceMap(action) {
227
- if (action === "bytes.result" || action === "bytes.error" || action === "bytesMany.result" || action === "bytesMany.error") {
231
+ if (action === "info.result" || action === "info.error" || action === "bytes.result" || action === "bytes.error" || action === "bytesMany.result" || action === "bytesMany.error") {
228
232
  return { senderCap: null, recipientCap: "resource:fetch" };
229
233
  }
230
234
  return { senderCap: "resource:fetch", recipientCap: null };
@@ -255,6 +259,13 @@ function intentMap(action) {
255
259
  if (action === "invoke") return { senderCap: "intent:write", recipientCap: null };
256
260
  return { senderCap: "intent:read", recipientCap: null };
257
261
  }
262
+ function dmMap(action) {
263
+ if (action === "message" || action.endsWith(".result") || action.endsWith(".error")) {
264
+ return { senderCap: null, recipientCap: "dm:read" };
265
+ }
266
+ if (action === "send") return { senderCap: "dm:write", recipientCap: null };
267
+ return { senderCap: "dm:read", recipientCap: null };
268
+ }
258
269
  function themeMap(action) {
259
270
  if (action === "changed") return { senderCap: null, recipientCap: "theme:read" };
260
271
  return { senderCap: "theme:read", recipientCap: null };
@@ -298,6 +309,9 @@ function resolveCapabilitiesNap(msg) {
298
309
  case "intent":
299
310
  return intentMap(action);
300
311
  // NAP-INTENT archetype intent dispatch
312
+ case "dm":
313
+ return dmMap(action);
314
+ // NAP-DM runtime-mediated direct messages
301
315
  default:
302
316
  return { senderCap: null, recipientCap: null };
303
317
  }
@@ -593,7 +607,7 @@ function deserialize2(json) {
593
607
  return defaultConfig();
594
608
  }
595
609
 
596
- // ../../node_modules/.pnpm/@napplet+core@0.21.0/node_modules/@napplet/core/dist/index.js
610
+ // ../../node_modules/.pnpm/@napplet+core@0.23.0/node_modules/@napplet/core/dist/index.js
597
611
  function createDispatch() {
598
612
  const handlers = /* @__PURE__ */ new Map();
599
613
  function registerNap2(domain, handler) {
@@ -734,6 +748,8 @@ var CAP_OUTBOX_WRITE2 = 1 << 19;
734
748
  var CAP_UPLOAD_WRITE2 = 1 << 20;
735
749
  var CAP_INTENT_READ2 = 1 << 21;
736
750
  var CAP_INTENT_WRITE2 = 1 << 22;
751
+ var CAP_DM_READ2 = 1 << 23;
752
+ var CAP_DM_WRITE2 = 1 << 24;
737
753
  var CAP_MAP = {
738
754
  "relay:read": CAP_RELAY_READ,
739
755
  "relay:write": CAP_RELAY_WRITE,
@@ -756,7 +772,9 @@ var CAP_MAP = {
756
772
  "outbox:write": CAP_OUTBOX_WRITE2,
757
773
  "upload:write": CAP_UPLOAD_WRITE2,
758
774
  "intent:read": CAP_INTENT_READ2,
759
- "intent:write": CAP_INTENT_WRITE2
775
+ "intent:write": CAP_INTENT_WRITE2,
776
+ "dm:read": CAP_DM_READ2,
777
+ "dm:write": CAP_DM_WRITE2
760
778
  };
761
779
  var RUNTIME_CAP_ALL = Object.values(CAP_MAP).reduce((bits, bit) => bits | bit, 0);
762
780
  function capToBit(cap) {
@@ -1825,7 +1843,8 @@ function createRuntimeDomainHandlers(context) {
1825
1843
  lists: (windowId, msg) => handleServiceOnlyMessage(context, "lists", windowId, msg),
1826
1844
  serial: (windowId, msg) => handleServiceOnlyMessage(context, "serial", windowId, msg),
1827
1845
  ble: (windowId, msg) => handleServiceOnlyMessage(context, "ble", windowId, msg),
1828
- webrtc: (windowId, msg) => handleServiceOnlyMessage(context, "webrtc", windowId, msg)
1846
+ webrtc: (windowId, msg) => handleServiceOnlyMessage(context, "webrtc", windowId, msg),
1847
+ dm: (windowId, msg) => handleServiceOnlyMessage(context, "dm", windowId, msg)
1829
1848
  };
1830
1849
  }
1831
1850
  function handleStorageMessage(context, windowId, msg) {
@@ -1972,6 +1991,7 @@ function createNapEnvelopeDispatcher(handlers) {
1972
1991
  napDispatch.registerNap("serial", adapt(handlers.serial));
1973
1992
  napDispatch.registerNap("ble", adapt(handlers.ble));
1974
1993
  napDispatch.registerNap("webrtc", adapt(handlers.webrtc));
1994
+ napDispatch.registerNap("dm", adapt(handlers.dm));
1975
1995
  return (windowId, envelope) => {
1976
1996
  currentWindowId = windowId;
1977
1997
  try {
@@ -2541,6 +2561,7 @@ function adaptHooks(shellHooks, deps) {
2541
2561
  };
2542
2562
  }
2543
2563
  var registry = /* @__PURE__ */ new Map();
2564
+ var nextRegistrationId = 0;
2544
2565
  var originRegistry = {
2545
2566
  /**
2546
2567
  * Register a window reference with a windowId and optional identity metadata.
@@ -2550,10 +2571,16 @@ var originRegistry = {
2550
2571
  * @param identity - Optional NIP-5D identity metadata (dTag and aggregateHash)
2551
2572
  */
2552
2573
  register(win, windowId, identity) {
2574
+ for (const [registeredWin, entry] of registry.entries()) {
2575
+ if (registeredWin === win || entry.windowId === windowId) {
2576
+ registry.delete(registeredWin);
2577
+ }
2578
+ }
2553
2579
  registry.set(win, {
2554
2580
  windowId,
2555
2581
  dTag: identity?.dTag,
2556
- aggregateHash: identity?.aggregateHash
2582
+ aggregateHash: identity?.aggregateHash,
2583
+ registrationId: ++nextRegistrationId
2557
2584
  });
2558
2585
  },
2559
2586
  /**
@@ -2608,6 +2635,15 @@ var originRegistry = {
2608
2635
  if (!entry?.dTag || !entry?.aggregateHash) return void 0;
2609
2636
  return { dTag: entry.dTag, aggregateHash: entry.aggregateHash };
2610
2637
  },
2638
+ /**
2639
+ * Look up the monotonically increasing registration id for a Window.
2640
+ *
2641
+ * @param win - The Window reference to look up
2642
+ * @returns The registration id, or undefined if the Window is not registered
2643
+ */
2644
+ getRegistrationId(win) {
2645
+ return registry.get(win)?.registrationId;
2646
+ },
2611
2647
  /** Clear all registrations. */
2612
2648
  clear() {
2613
2649
  registry.clear();
@@ -3215,6 +3251,7 @@ function buildShellCapabilities(hooks) {
3215
3251
  if (hooks.serial?.isAvailable()) domains.push("serial");
3216
3252
  if (hooks.ble?.isAvailable()) domains.push("ble");
3217
3253
  if (hooks.webrtc?.isAvailable()) domains.push("webrtc");
3254
+ if (hooks.dm) domains.push("dm");
3218
3255
  const sandbox = [];
3219
3256
  domains.push(...sandbox);
3220
3257
  const protocols = {};
@@ -3231,6 +3268,7 @@ function buildShellCapabilities(hooks) {
3231
3268
  if (hooks.serial?.isAvailable()) naps.push("serial");
3232
3269
  if (hooks.ble?.isAvailable()) naps.push("ble");
3233
3270
  if (hooks.webrtc?.isAvailable()) naps.push("webrtc");
3271
+ if (hooks.dm) naps.push("dm");
3234
3272
  return applyCapabilityOverrides(
3235
3273
  { domains, protocols, naps, sandbox },
3236
3274
  hooks.capabilities?.disabledDomains ?? []
@@ -3250,20 +3288,29 @@ function applyCapabilityOverrides(capabilities, disabledDomains) {
3250
3288
  sandbox: capabilities.sandbox
3251
3289
  };
3252
3290
  }
3253
- var initSent = /* @__PURE__ */ new Set();
3291
+ var initSent = /* @__PURE__ */ new WeakMap();
3254
3292
  function handleShellReady({
3255
3293
  hooks,
3256
3294
  origin,
3257
3295
  runtime,
3296
+ sourceRegistrationId,
3297
+ sourceWindow,
3258
3298
  windowId
3259
3299
  }) {
3260
- registerNip5dSessionIfNeeded({ hooks, origin, runtime, windowId });
3261
- if (initSent.has(windowId)) {
3300
+ registerNip5dSessionIfNeeded({
3301
+ hooks,
3302
+ origin,
3303
+ runtime,
3304
+ sourceRegistrationId,
3305
+ sourceWindow,
3306
+ windowId
3307
+ });
3308
+ if (initSent.get(sourceWindow) === sourceRegistrationId) {
3262
3309
  return;
3263
3310
  }
3264
3311
  const capabilities = buildShellCapabilities(hooks);
3265
- postShellInit(windowId, capabilities, Object.keys(hooks.services ?? {}));
3266
- initSent.add(windowId);
3312
+ postShellInit(sourceWindow, capabilities, Object.keys(hooks.services ?? {}));
3313
+ initSent.set(sourceWindow, sourceRegistrationId);
3267
3314
  }
3268
3315
  function registerNip5dSessionIfNeeded({
3269
3316
  hooks,
@@ -3312,14 +3359,13 @@ function resolveNip5dIdentity(hooks, windowId) {
3312
3359
  aggregateHash: originIdentity.aggregateHash
3313
3360
  };
3314
3361
  }
3315
- function postShellInit(windowId, capabilities, services) {
3362
+ function postShellInit(win, capabilities, services) {
3316
3363
  const initMsg = {
3317
3364
  type: "shell.init",
3318
3365
  capabilities,
3319
3366
  services
3320
3367
  };
3321
- const win = originRegistry.getIframeWindow(windowId);
3322
- if (win) win.postMessage(initMsg, "*");
3368
+ win.postMessage(initMsg, "*");
3323
3369
  }
3324
3370
  function reportUnrouted(hooks, event, reason) {
3325
3371
  if (!hooks.onUnroutedMessage) return;
@@ -3379,7 +3425,14 @@ function createShellBridge(hooks) {
3379
3425
  const msg = event.data;
3380
3426
  if (typeof msg !== "object" || msg === null || typeof msg.type !== "string") return;
3381
3427
  if (msg.type === "shell.ready") {
3382
- handleShellReady({ hooks, origin: event.origin, runtime, windowId });
3428
+ handleShellReady({
3429
+ hooks,
3430
+ origin: event.origin,
3431
+ runtime,
3432
+ sourceRegistrationId: originRegistry.getRegistrationId(sourceWindow) ?? 0,
3433
+ sourceWindow,
3434
+ windowId
3435
+ });
3383
3436
  return;
3384
3437
  }
3385
3438
  runtime.handleMessage(windowId, msg);
@@ -4061,10 +4114,10 @@ function createNotificationService(options) {
4061
4114
  };
4062
4115
  }
4063
4116
  var IDENTITY_SERVICE_VERSION = "1.0.0";
4064
- function sendProviderError(send, result, fallback, err) {
4117
+ function sendProviderError(send, result, fallback, err2) {
4065
4118
  send({
4066
4119
  ...result,
4067
- error: err?.message ?? fallback
4120
+ error: err2?.message ?? fallback
4068
4121
  });
4069
4122
  }
4070
4123
  async function getCurrentPubkey(options) {
@@ -4081,13 +4134,13 @@ function sendOptionalProviderResult(options, send, fallbackResult, errorFallback
4081
4134
  send(fallbackResult);
4082
4135
  return;
4083
4136
  }
4084
- Promise.resolve(getCurrentPubkey(options)).then((pubkey) => buildResult(pubkey)).then((result) => send(result)).catch((err) => sendProviderError(send, fallbackResult, errorFallback, err));
4137
+ Promise.resolve(getCurrentPubkey(options)).then((pubkey) => buildResult(pubkey)).then((result) => send(result)).catch((err2) => sendProviderError(send, fallbackResult, errorFallback, err2));
4085
4138
  }
4086
4139
  function sendIdentityError(send, id, typeBase, error) {
4087
4140
  send({ type: `${typeBase}.error`, id, error });
4088
4141
  }
4089
- function sendSignerError(send, id, typeBase, fallback, err) {
4090
- sendIdentityError(send, id, typeBase, err?.message ?? fallback);
4142
+ function sendSignerError(send, id, typeBase, fallback, err2) {
4143
+ sendIdentityError(send, id, typeBase, err2?.message ?? fallback);
4091
4144
  }
4092
4145
  function handleGetPublicKey(options, id, send) {
4093
4146
  const signer = options.getSigner();
@@ -4107,7 +4160,7 @@ function handleGetPublicKey(options, id, send) {
4107
4160
  pubkey: pubkey ?? ""
4108
4161
  };
4109
4162
  send(result);
4110
- }).catch((err) => sendSignerError(send, id, "identity.getPublicKey", "getPublicKey failed", err));
4163
+ }).catch((err2) => sendSignerError(send, id, "identity.getPublicKey", "getPublicKey failed", err2));
4111
4164
  }
4112
4165
  function handleGetRelays(options, id, send) {
4113
4166
  const signer = options.getSigner();
@@ -4122,7 +4175,7 @@ function handleGetRelays(options, id, send) {
4122
4175
  relays
4123
4176
  };
4124
4177
  send(result);
4125
- }).catch((err) => sendSignerError(send, id, "identity.getRelays", "getRelays failed", err));
4178
+ }).catch((err2) => sendSignerError(send, id, "identity.getRelays", "getRelays failed", err2));
4126
4179
  }
4127
4180
  function handleReadProvider(options, id, message, send) {
4128
4181
  switch (message.type) {
@@ -4281,7 +4334,7 @@ function createRelayPoolService(options) {
4281
4334
  return;
4282
4335
  }
4283
4336
  const relayHint = typeof relayMessage.relay === "string" && relayMessage.relay.length > 0 ? relayMessage.relay : void 0;
4284
- const relayUrls = relayHint ? [relayHint] : options.selectRelayTier(filters);
4337
+ const relayUrls2 = relayHint ? [relayHint] : options.selectRelayTier(filters);
4285
4338
  let eoseSent = false;
4286
4339
  const eoseTimer = setTimeout(() => {
4287
4340
  if (!eoseSent) {
@@ -4299,7 +4352,7 @@ function createRelayPoolService(options) {
4299
4352
  return;
4300
4353
  }
4301
4354
  send({ type: "relay.event", subId, event: item });
4302
- }, relayUrls);
4355
+ }, relayUrls2);
4303
4356
  tracked.set(subKey, { handle, eoseTimer });
4304
4357
  return;
4305
4358
  }
@@ -4445,12 +4498,12 @@ function createKeysService(options = {}) {
4445
4498
  unsubscribeHandles.set(m.action.id, unsubscribe);
4446
4499
  if (!bridgeWindowActions.has(windowId)) bridgeWindowActions.set(windowId, /* @__PURE__ */ new Set());
4447
4500
  bridgeWindowActions.get(windowId).add(m.action.id);
4448
- } catch (err) {
4501
+ } catch (err2) {
4449
4502
  const id = m.id ?? "";
4450
4503
  send({
4451
4504
  type: "keys.registerAction.error",
4452
4505
  id,
4453
- error: `bridge subscribe failed: ${err.message}`
4506
+ error: `bridge subscribe failed: ${err2.message}`
4454
4507
  });
4455
4508
  return;
4456
4509
  }
@@ -4592,12 +4645,12 @@ function createKeysService(options = {}) {
4592
4645
  });
4593
4646
  if (!windowActions.has(windowId)) windowActions.set(windowId, /* @__PURE__ */ new Set());
4594
4647
  windowActions.get(windowId).add(m.action.id);
4595
- } catch (err) {
4648
+ } catch (err2) {
4596
4649
  const id = m.id ?? "";
4597
4650
  send({
4598
4651
  type: "keys.registerAction.error",
4599
4652
  id,
4600
- error: `invalid chord: ${err.message}`
4653
+ error: `invalid chord: ${err2.message}`
4601
4654
  });
4602
4655
  return;
4603
4656
  }
@@ -5265,6 +5318,9 @@ function arrayBufferToBase64(buf) {
5265
5318
  }
5266
5319
  return btoa(binary);
5267
5320
  }
5321
+ var DEFAULT_RESOURCE_INFO = {
5322
+ schemes: [{ scheme: "https", enabled: true }]
5323
+ };
5268
5324
  function assertResourceOptions(options) {
5269
5325
  if (typeof options?.fetch !== "function" || typeof options?.isOriginGranted !== "function" || typeof options?.getConnectGrants !== "function" || typeof options?.resolveIdentity !== "function") {
5270
5326
  throw new Error(
@@ -5336,6 +5392,35 @@ function requestIdFromMessage(message) {
5336
5392
  if (typeof message.requestId === "string" && message.requestId.length > 0) return message.requestId;
5337
5393
  return null;
5338
5394
  }
5395
+ function normalizeResourceInfo(info) {
5396
+ return {
5397
+ schemes: Array.isArray(info.schemes) ? info.schemes.filter((scheme) => typeof scheme?.scheme === "string").map((scheme) => ({ scheme: scheme.scheme, enabled: scheme.enabled !== false })) : [],
5398
+ ...typeof info.maxBytes === "number" ? { maxBytes: info.maxBytes } : {},
5399
+ ...typeof info.maxUrls === "number" ? { maxUrls: info.maxUrls } : {}
5400
+ };
5401
+ }
5402
+ async function resolveResourceInfo(options, windowId) {
5403
+ const configured = options.resourceInfo ?? DEFAULT_RESOURCE_INFO;
5404
+ const info = typeof configured === "function" ? await configured({ windowId, identity: options.resolveIdentity(windowId) }) : configured;
5405
+ return normalizeResourceInfo(info);
5406
+ }
5407
+ async function handleInfo(options, windowId, requestId, send) {
5408
+ try {
5409
+ const info = await resolveResourceInfo(options, windowId);
5410
+ send({
5411
+ type: "resource.info.result",
5412
+ id: requestId,
5413
+ info
5414
+ });
5415
+ } catch (err2) {
5416
+ send({
5417
+ type: "resource.info.error",
5418
+ id: requestId,
5419
+ error: "unavailable",
5420
+ message: err2 instanceof Error ? err2.message : String(err2)
5421
+ });
5422
+ }
5423
+ }
5339
5424
  function resourceInvalidRequest(url, message) {
5340
5425
  return {
5341
5426
  ok: false,
@@ -5377,14 +5462,14 @@ async function fetchResourceItem(options, identity, url, init, signal) {
5377
5462
  headers,
5378
5463
  bodyBase64: arrayBufferToBase64(buffer)
5379
5464
  };
5380
- } catch (err) {
5381
- const isAbort = signal.aborted || err instanceof Error && (err.name === "AbortError" || err.name === "DOMException");
5465
+ } catch (err2) {
5466
+ const isAbort = signal.aborted || err2 instanceof Error && (err2.name === "AbortError" || err2.name === "DOMException");
5382
5467
  return {
5383
5468
  ok: false,
5384
5469
  url,
5385
5470
  error: isAbort ? "timeout" : "network-error",
5386
5471
  code: isAbort ? "canceled" : "network-error",
5387
- message: err instanceof Error ? err.message : String(err)
5472
+ message: err2 instanceof Error ? err2.message : String(err2)
5388
5473
  };
5389
5474
  }
5390
5475
  }
@@ -5502,6 +5587,14 @@ function createResourceService(options) {
5502
5587
  });
5503
5588
  return;
5504
5589
  }
5590
+ case "resource.info": {
5591
+ const m = message;
5592
+ const requestId = requestIdFromMessage(m);
5593
+ if (!requestId) return;
5594
+ handleInfo(options, windowId, requestId, send).catch(() => {
5595
+ });
5596
+ return;
5597
+ }
5505
5598
  case "resource.bytesMany": {
5506
5599
  const m = message;
5507
5600
  const requestId = requestIdFromMessage(m);
@@ -5530,7 +5623,7 @@ var OUTBOX_SERVICE_VERSION = "1.0.0";
5530
5623
  var OUTBOX_DESCRIPTOR = {
5531
5624
  name: "outbox",
5532
5625
  version: OUTBOX_SERVICE_VERSION,
5533
- description: "NAP-OUTBOX outbox-aware relay routing \u2014 query/subscribe/publish/resolveRelays"
5626
+ description: "NAP-OUTBOX outbox-aware relay routing \u2014 getEvent/query/subscribe/publish/resolveRelays"
5534
5627
  };
5535
5628
  function normalizeFilters(raw) {
5536
5629
  if (Array.isArray(raw)) {
@@ -5540,6 +5633,59 @@ function normalizeFilters(raw) {
5540
5633
  if (typeof raw === "object" && raw !== null) return [raw];
5541
5634
  return null;
5542
5635
  }
5636
+ function buildEventQuery(eventId, eventOptions) {
5637
+ const filter = { ids: [eventId] };
5638
+ const queryOptions = { limit: 1 };
5639
+ if (typeof eventOptions?.author === "string" && eventOptions.author.length > 0) {
5640
+ filter.authors = [eventOptions.author];
5641
+ queryOptions.authors = [eventOptions.author];
5642
+ }
5643
+ if (Array.isArray(eventOptions?.relays)) queryOptions.relays = eventOptions.relays;
5644
+ if (eventOptions?.strategy !== void 0) queryOptions.strategy = eventOptions.strategy;
5645
+ if (eventOptions?.timeoutMs !== void 0) queryOptions.timeoutMs = eventOptions.timeoutMs;
5646
+ return { filter, queryOptions };
5647
+ }
5648
+ function eventResultFromQuery(eventId, result) {
5649
+ const event = result.events.find((candidate) => candidate.id === eventId);
5650
+ const eventResult = {
5651
+ relays: event ? result.relays[eventId] ?? [] : []
5652
+ };
5653
+ if (event) eventResult.event = event;
5654
+ if (!event) eventResult.error = result.error ?? "not found";
5655
+ else if (result.error !== void 0) eventResult.error = result.error;
5656
+ if (result.incomplete !== void 0) eventResult.incomplete = result.incomplete;
5657
+ return eventResult;
5658
+ }
5659
+ function fallbackGetEvent(router, eventId, eventOptions) {
5660
+ const { filter, queryOptions } = buildEventQuery(eventId, eventOptions);
5661
+ return router.query([filter], queryOptions).then((result) => eventResultFromQuery(eventId, result));
5662
+ }
5663
+ function sendEventResult(id, eventId, result, send) {
5664
+ if (result.event && result.event.id !== eventId) {
5665
+ send({ type: "outbox.getEvent.result", id, relays: [], error: "not found" });
5666
+ return;
5667
+ }
5668
+ send({
5669
+ type: "outbox.getEvent.result",
5670
+ id,
5671
+ ...result.event === void 0 ? {} : { event: result.event },
5672
+ relays: result.relays,
5673
+ ...result.incomplete === void 0 ? {} : { incomplete: result.incomplete },
5674
+ ...result.error === void 0 ? {} : { error: result.error }
5675
+ });
5676
+ }
5677
+ function handleGetEvent(router, msg, send) {
5678
+ const m = msg;
5679
+ const id = m.id ?? "";
5680
+ if (typeof m.eventId !== "string" || m.eventId.length === 0) {
5681
+ send({ type: "outbox.getEvent.result", id, relays: [], error: "invalid filter" });
5682
+ return;
5683
+ }
5684
+ const getEvent = router.getEvent ?? ((eventId, eventOptions) => fallbackGetEvent(router, eventId, eventOptions));
5685
+ void getEvent(m.eventId, m.options).then((result) => sendEventResult(id, m.eventId, result, send)).catch(
5686
+ (err2) => send({ type: "outbox.getEvent.result", id, relays: [], error: toErrorMessage(err2) })
5687
+ );
5688
+ }
5543
5689
  function createOutboxService(options) {
5544
5690
  if (!options || typeof options.router !== "object" || options.router === null) {
5545
5691
  throw new Error("createOutboxService: options.router is required");
@@ -5564,7 +5710,7 @@ function createOutboxService(options) {
5564
5710
  ...result.error === void 0 ? {} : { error: result.error }
5565
5711
  })
5566
5712
  ).catch(
5567
- (err) => send({ type: "outbox.query.result", id, events: [], relays: {}, error: toErrorMessage(err) })
5713
+ (err2) => send({ type: "outbox.query.result", id, events: [], relays: {}, error: toErrorMessage(err2) })
5568
5714
  );
5569
5715
  }
5570
5716
  function handleSubscribe2(windowId, msg, send) {
@@ -5616,7 +5762,7 @@ function createOutboxService(options) {
5616
5762
  ...result.error === void 0 ? {} : { error: result.error }
5617
5763
  })
5618
5764
  ).catch(
5619
- (err) => send({ type: "outbox.publish.result", id, ok: false, error: toErrorMessage(err) })
5765
+ (err2) => send({ type: "outbox.publish.result", id, ok: false, error: toErrorMessage(err2) })
5620
5766
  );
5621
5767
  }
5622
5768
  function handleResolveRelays(msg, send) {
@@ -5627,13 +5773,16 @@ function createOutboxService(options) {
5627
5773
  return;
5628
5774
  }
5629
5775
  void router.resolveRelays(m.target).then((plan) => send({ type: "outbox.resolveRelays.result", id, plan })).catch(
5630
- (err) => send({ type: "outbox.resolveRelays.result", id, error: toErrorMessage(err) })
5776
+ (err2) => send({ type: "outbox.resolveRelays.result", id, error: toErrorMessage(err2) })
5631
5777
  );
5632
5778
  }
5633
5779
  return {
5634
5780
  descriptor: OUTBOX_DESCRIPTOR,
5635
5781
  handleMessage(windowId, message, send) {
5636
5782
  switch (message.type) {
5783
+ case "outbox.getEvent":
5784
+ handleGetEvent(router, message, send);
5785
+ return;
5637
5786
  case "outbox.query":
5638
5787
  handleQuery(message, send);
5639
5788
  return;
@@ -5664,9 +5813,9 @@ function createOutboxService(options) {
5664
5813
  }
5665
5814
  };
5666
5815
  }
5667
- function toErrorMessage(err) {
5668
- if (err instanceof Error) return err.message;
5669
- if (typeof err === "string") return err;
5816
+ function toErrorMessage(err2) {
5817
+ if (err2 instanceof Error) return err2.message;
5818
+ if (typeof err2 === "string") return err2;
5670
5819
  return "outbox request failed";
5671
5820
  }
5672
5821
  var UPLOAD_SERVICE_VERSION = "1.0.0";
@@ -5675,14 +5824,38 @@ var UPLOAD_DESCRIPTOR = {
5675
5824
  version: UPLOAD_SERVICE_VERSION,
5676
5825
  description: "NAP-UPLOAD shell-mediated file/blob upload \u2014 upload/status with progress pushes"
5677
5826
  };
5827
+ var DEFAULT_UPLOAD_INFO = {
5828
+ rails: []
5829
+ };
5678
5830
  function createUploadService(options) {
5679
5831
  if (!options || typeof options.uploader !== "object" || options.uploader === null) {
5680
5832
  throw new Error("createUploadService: options.uploader is required");
5681
5833
  }
5682
5834
  const { uploader } = options;
5835
+ const uploadInfo = options.uploadInfo ?? DEFAULT_UPLOAD_INFO;
5683
5836
  const generateId2 = options.generateId ?? (() => crypto.randomUUID());
5684
5837
  const now = options.now ?? (() => Date.now());
5685
5838
  const entries = /* @__PURE__ */ new Map();
5839
+ function normalizeUploadInfo(info) {
5840
+ return {
5841
+ rails: Array.isArray(info.rails) ? info.rails.filter((rail) => typeof rail?.rail === "string").map((rail) => ({
5842
+ rail: rail.rail,
5843
+ enabled: rail.enabled !== false,
5844
+ ...Array.isArray(rail.returns) ? { returns: rail.returns.filter((value) => typeof value === "string") } : {}
5845
+ })) : [],
5846
+ ...typeof info.maxBytes === "number" ? { maxBytes: info.maxBytes } : {},
5847
+ ...Array.isArray(info.mimeTypes) ? { mimeTypes: info.mimeTypes.filter((value) => typeof value === "string") } : {}
5848
+ };
5849
+ }
5850
+ function handleInfo2(windowId, msg, send) {
5851
+ const m = msg;
5852
+ const id = m.id ?? "";
5853
+ void Promise.resolve().then(() => typeof uploadInfo === "function" ? uploadInfo({ windowId }) : uploadInfo).then((info) => {
5854
+ send({ type: "upload.info.result", id, info: normalizeUploadInfo(info) });
5855
+ }).catch((err2) => {
5856
+ send({ type: "upload.info.result", id, error: toErrorMessage2(err2) });
5857
+ });
5858
+ }
5686
5859
  function handleUpload(windowId, msg, send) {
5687
5860
  const m = msg;
5688
5861
  const id = m.id ?? "";
@@ -5709,9 +5882,9 @@ function createUploadService(options) {
5709
5882
  const entry = entries.get(key);
5710
5883
  if (entry) entry.status = { ...stamped, updatedAt: now() };
5711
5884
  send({ type: "upload.upload.result", id, result: stamped });
5712
- }).catch((err) => {
5885
+ }).catch((err2) => {
5713
5886
  entries.delete(key);
5714
- send({ type: "upload.upload.result", id, error: toErrorMessage2(err) });
5887
+ send({ type: "upload.upload.result", id, error: toErrorMessage2(err2) });
5715
5888
  });
5716
5889
  }
5717
5890
  function handleStatus(windowId, msg, send) {
@@ -5733,7 +5906,7 @@ function createUploadService(options) {
5733
5906
  status ? { type: "upload.status.result", id, status } : { type: "upload.status.result", id, error: "unknown upload" }
5734
5907
  )
5735
5908
  ).catch(
5736
- (err) => send({ type: "upload.status.result", id, error: toErrorMessage2(err) })
5909
+ (err2) => send({ type: "upload.status.result", id, error: toErrorMessage2(err2) })
5737
5910
  );
5738
5911
  return;
5739
5912
  }
@@ -5743,6 +5916,9 @@ function createUploadService(options) {
5743
5916
  descriptor: UPLOAD_DESCRIPTOR,
5744
5917
  handleMessage(windowId, message, send) {
5745
5918
  switch (message.type) {
5919
+ case "upload.info":
5920
+ handleInfo2(windowId, message, send);
5921
+ return;
5746
5922
  case "upload.upload":
5747
5923
  handleUpload(windowId, message, send);
5748
5924
  return;
@@ -5764,9 +5940,9 @@ function createUploadService(options) {
5764
5940
  }
5765
5941
  };
5766
5942
  }
5767
- function toErrorMessage2(err) {
5768
- if (err instanceof Error) return err.message;
5769
- if (typeof err === "string") return err;
5943
+ function toErrorMessage2(err2) {
5944
+ if (err2 instanceof Error) return err2.message;
5945
+ if (typeof err2 === "string") return err2;
5770
5946
  return "upload request failed";
5771
5947
  }
5772
5948
  var INTENT_SERVICE_VERSION = "1.0.0";
@@ -5775,9 +5951,9 @@ var INTENT_DESCRIPTOR = {
5775
5951
  version: INTENT_SERVICE_VERSION,
5776
5952
  description: "NAP-INTENT archetype intent dispatch \u2014 invoke/available/handlers"
5777
5953
  };
5778
- function toErrorMessage4(err) {
5779
- if (err instanceof Error) return err.message;
5780
- if (typeof err === "string") return err;
5954
+ function toErrorMessage4(err2) {
5955
+ if (err2 instanceof Error) return err2.message;
5956
+ if (typeof err2 === "string") return err2;
5781
5957
  return "intent request failed";
5782
5958
  }
5783
5959
  function createIntentService(options) {
@@ -5795,11 +5971,11 @@ function createIntentService(options) {
5795
5971
  let pending;
5796
5972
  try {
5797
5973
  pending = Promise.resolve(call());
5798
- } catch (err) {
5799
- send({ type: resultType, id, error: toErrorMessage4(err) });
5974
+ } catch (err2) {
5975
+ send({ type: resultType, id, error: toErrorMessage4(err2) });
5800
5976
  return;
5801
5977
  }
5802
- pending.then((value) => send(onValue(value))).catch((err) => send({ type: resultType, id, error: toErrorMessage4(err) }));
5978
+ pending.then((value) => send(onValue(value))).catch((err2) => send({ type: resultType, id, error: toErrorMessage4(err2) }));
5803
5979
  }
5804
5980
  function handleInvoke(windowId, msg, send) {
5805
5981
  const m = msg;
@@ -5908,7 +6084,7 @@ function createCvmService(options) {
5908
6084
  const m = msg;
5909
6085
  const id = m.id ?? "";
5910
6086
  void transport.discover(m.query).then((servers) => send({ type: "cvm.discover.result", id, servers })).catch(
5911
- (err) => send({ type: "cvm.discover.result", id, servers: [], error: toErrorMessage5(err) })
6087
+ (err2) => send({ type: "cvm.discover.result", id, servers: [], error: toErrorMessage5(err2) })
5912
6088
  );
5913
6089
  }
5914
6090
  function handleRequest(windowId, msg, send) {
@@ -5924,7 +6100,7 @@ function createCvmService(options) {
5924
6100
  }
5925
6101
  openSession(windowId, m.server, send);
5926
6102
  void transport.request(m.server, m.message, m.options).then((message) => send({ type: "cvm.request.result", id, message })).catch(
5927
- (err) => send({ type: "cvm.request.result", id, error: toErrorMessage5(err) })
6103
+ (err2) => send({ type: "cvm.request.result", id, error: toErrorMessage5(err2) })
5928
6104
  );
5929
6105
  }
5930
6106
  function handleClose(windowId, msg, send) {
@@ -5935,7 +6111,7 @@ function createCvmService(options) {
5935
6111
  return;
5936
6112
  }
5937
6113
  closeSession(windowId, m.server.pubkey);
5938
- void transport.close(m.server).then(() => send({ type: "cvm.close.result", id })).catch((err) => send({ type: "cvm.close.result", id, error: toErrorMessage5(err) }));
6114
+ void transport.close(m.server).then(() => send({ type: "cvm.close.result", id })).catch((err2) => send({ type: "cvm.close.result", id, error: toErrorMessage5(err2) }));
5939
6115
  }
5940
6116
  return {
5941
6117
  descriptor: CVM_DESCRIPTOR,
@@ -5966,9 +6142,9 @@ function createCvmService(options) {
5966
6142
  }
5967
6143
  };
5968
6144
  }
5969
- function toErrorMessage5(err) {
5970
- if (err instanceof Error) return err.message;
5971
- if (typeof err === "string") return err;
6145
+ function toErrorMessage5(err2) {
6146
+ if (err2 instanceof Error) return err2.message;
6147
+ if (typeof err2 === "string") return err2;
5972
6148
  return "cvm request failed";
5973
6149
  }
5974
6150
  var LINK_SERVICE_VERSION = "1.0.0";
@@ -6043,20 +6219,20 @@ var LISTS_DESCRIPTOR = {
6043
6219
  version: LISTS_SERVICE_VERSION,
6044
6220
  description: "NAP-LISTS reference handler for shell-mediated NIP-51 list mutations"
6045
6221
  };
6046
- function errorMessage(err, fallback) {
6047
- if (err instanceof Error) return err.message;
6048
- if (typeof err === "string") return err;
6222
+ function errorMessage(err2, fallback) {
6223
+ if (err2 instanceof Error) return err2.message;
6224
+ if (typeof err2 === "string") return err2;
6049
6225
  return fallback;
6050
6226
  }
6051
6227
  function settle(call, send, okFalse, onValue) {
6052
6228
  let pending;
6053
6229
  try {
6054
6230
  pending = Promise.resolve(call());
6055
- } catch (err) {
6056
- send(okFalse(errorMessage(err, "lists request failed")));
6231
+ } catch (err2) {
6232
+ send(okFalse(errorMessage(err2, "lists request failed")));
6057
6233
  return;
6058
6234
  }
6059
- pending.then((value) => send(onValue(value))).catch((err) => send(okFalse(errorMessage(err, "lists request failed"))));
6235
+ pending.then((value) => send(onValue(value))).catch((err2) => send(okFalse(errorMessage(err2, "lists request failed"))));
6060
6236
  }
6061
6237
  function unsupportedMutation(resultType, id) {
6062
6238
  return {
@@ -6123,20 +6299,20 @@ var SERIAL_DESCRIPTOR = {
6123
6299
  version: SERIAL_SERVICE_VERSION,
6124
6300
  description: "NAP-SERIAL reference handler for shell-mediated serial sessions"
6125
6301
  };
6126
- function errorMessage2(err, fallback) {
6127
- if (err instanceof Error) return err.message;
6128
- if (typeof err === "string") return err;
6302
+ function errorMessage2(err2, fallback) {
6303
+ if (err2 instanceof Error) return err2.message;
6304
+ if (typeof err2 === "string") return err2;
6129
6305
  return fallback;
6130
6306
  }
6131
6307
  function settle2(call, send, okFalse, onValue) {
6132
6308
  let pending;
6133
6309
  try {
6134
6310
  pending = Promise.resolve(call());
6135
- } catch (err) {
6136
- send(okFalse(errorMessage2(err, "serial request failed")));
6311
+ } catch (err2) {
6312
+ send(okFalse(errorMessage2(err2, "serial request failed")));
6137
6313
  return;
6138
6314
  }
6139
- pending.then((value) => send(onValue(value))).catch((err) => send(okFalse(errorMessage2(err, "serial request failed"))));
6315
+ pending.then((value) => send(onValue(value))).catch((err2) => send(okFalse(errorMessage2(err2, "serial request failed"))));
6140
6316
  }
6141
6317
  function unsupported(resultType, id) {
6142
6318
  return {
@@ -6210,20 +6386,20 @@ var BLE_DESCRIPTOR = {
6210
6386
  version: BLE_SERVICE_VERSION,
6211
6387
  description: "NAP-BLE reference handler for shell-mediated BLE/GATT sessions"
6212
6388
  };
6213
- function errorMessage3(err, fallback) {
6214
- if (err instanceof Error) return err.message;
6215
- if (typeof err === "string") return err;
6389
+ function errorMessage3(err2, fallback) {
6390
+ if (err2 instanceof Error) return err2.message;
6391
+ if (typeof err2 === "string") return err2;
6216
6392
  return fallback;
6217
6393
  }
6218
6394
  function settle3(call, send, okFalse, onValue) {
6219
6395
  let pending;
6220
6396
  try {
6221
6397
  pending = Promise.resolve(call());
6222
- } catch (err) {
6223
- send(okFalse(errorMessage3(err, "ble request failed")));
6398
+ } catch (err2) {
6399
+ send(okFalse(errorMessage3(err2, "ble request failed")));
6224
6400
  return;
6225
6401
  }
6226
- pending.then((value) => send(onValue(value))).catch((err) => send(okFalse(errorMessage3(err, "ble request failed"))));
6402
+ pending.then((value) => send(onValue(value))).catch((err2) => send(okFalse(errorMessage3(err2, "ble request failed"))));
6227
6403
  }
6228
6404
  function unsupported2(resultType, id) {
6229
6405
  return {
@@ -6361,20 +6537,20 @@ var WEBRTC_DESCRIPTOR = {
6361
6537
  version: WEBRTC_SERVICE_VERSION,
6362
6538
  description: "NAP-WEBRTC reference handler for shell-mediated WebRTC sessions"
6363
6539
  };
6364
- function errorMessage4(err, fallback) {
6365
- if (err instanceof Error) return err.message;
6366
- if (typeof err === "string") return err;
6540
+ function errorMessage4(err2, fallback) {
6541
+ if (err2 instanceof Error) return err2.message;
6542
+ if (typeof err2 === "string") return err2;
6367
6543
  return fallback;
6368
6544
  }
6369
6545
  function settle4(call, send, okFalse, onValue) {
6370
6546
  let pending;
6371
6547
  try {
6372
6548
  pending = Promise.resolve(call());
6373
- } catch (err) {
6374
- send(okFalse(errorMessage4(err, "webrtc request failed")));
6549
+ } catch (err2) {
6550
+ send(okFalse(errorMessage4(err2, "webrtc request failed")));
6375
6551
  return;
6376
6552
  }
6377
- pending.then((value) => send(onValue(value))).catch((err) => send(okFalse(errorMessage4(err, "webrtc request failed"))));
6553
+ pending.then((value) => send(onValue(value))).catch((err2) => send(okFalse(errorMessage4(err2, "webrtc request failed"))));
6378
6554
  }
6379
6555
  function unsupported3(resultType, id) {
6380
6556
  return {
@@ -6457,9 +6633,9 @@ var COMMON_DESCRIPTOR = {
6457
6633
  version: COMMON_SERVICE_VERSION,
6458
6634
  description: "NAP-COMMON reference handler for shell-mediated social helpers"
6459
6635
  };
6460
- function errorMessage5(err, fallback) {
6461
- if (err instanceof Error) return err.message;
6462
- if (typeof err === "string") return err;
6636
+ function errorMessage5(err2, fallback) {
6637
+ if (err2 instanceof Error) return err2.message;
6638
+ if (typeof err2 === "string") return err2;
6463
6639
  return fallback;
6464
6640
  }
6465
6641
  function encodeNip19(input) {
@@ -6488,8 +6664,8 @@ function encodeNip19(input) {
6488
6664
  default:
6489
6665
  return { ok: false, error: "unsupported NIP-19 type" };
6490
6666
  }
6491
- } catch (err) {
6492
- return { ok: false, error: errorMessage5(err, "NIP-19 encode failed") };
6667
+ } catch (err2) {
6668
+ return { ok: false, error: errorMessage5(err2, "NIP-19 encode failed") };
6493
6669
  }
6494
6670
  }
6495
6671
  function decodeNip19Value(value) {
@@ -6522,9 +6698,9 @@ function decodeNip19Value(value) {
6522
6698
  default:
6523
6699
  return { ok: false, error: "unsupported NIP-19 type" };
6524
6700
  }
6525
- } catch (err) {
6701
+ } catch (err2) {
6526
6702
  if (value.startsWith("nrelay1")) return decodeNrelay(value);
6527
- return { ok: false, error: errorMessage5(err, "NIP-19 decode failed") };
6703
+ return { ok: false, error: errorMessage5(err2, "NIP-19 decode failed") };
6528
6704
  }
6529
6705
  }
6530
6706
  function decodeNrelay(value) {
@@ -6540,8 +6716,8 @@ function decodeNrelay(value) {
6540
6716
  const payloadWords = words.slice(0, -6);
6541
6717
  const bytes = convertBits(payloadWords, 5, 8, false);
6542
6718
  return { ok: true, nip19Type: "nrelay", relay: new TextDecoder().decode(Uint8Array.from(bytes)) };
6543
- } catch (err) {
6544
- return { ok: false, error: errorMessage5(err, "invalid nrelay value") };
6719
+ } catch (err2) {
6720
+ return { ok: false, error: errorMessage5(err2, "invalid nrelay value") };
6545
6721
  }
6546
6722
  }
6547
6723
  function convertBits(data, fromBits, toBits, pad) {
@@ -6570,11 +6746,11 @@ function settle5(call, send, okFalse, onValue) {
6570
6746
  let pending;
6571
6747
  try {
6572
6748
  pending = Promise.resolve(call());
6573
- } catch (err) {
6574
- send(okFalse(errorMessage5(err, "common request failed")));
6749
+ } catch (err2) {
6750
+ send(okFalse(errorMessage5(err2, "common request failed")));
6575
6751
  return;
6576
6752
  }
6577
- pending.then((value) => send(onValue(value))).catch((err) => send(okFalse(errorMessage5(err, "common request failed"))));
6753
+ pending.then((value) => send(onValue(value))).catch((err2) => send(okFalse(errorMessage5(err2, "common request failed"))));
6578
6754
  }
6579
6755
  function createCommonService(options = {}) {
6580
6756
  return {