@kehto/services 0.15.0 → 0.16.1

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/dist/index.d.ts CHANGED
@@ -1653,21 +1653,12 @@ declare function createResourceService(options: ResourceServiceOptions): Resourc
1653
1653
  * @packageDocumentation
1654
1654
  */
1655
1655
 
1656
- /**
1657
- * Relay-selection strategy:
1658
- * - `outbox` — query/publish via author write relays (the outbox model)
1659
- * - `inbox` — query/publish via recipient read relays (the inbox model)
1660
- * - `auto` — let the shell choose per its policy and relay intelligence
1661
- */
1662
- type OutboxStrategy = 'outbox' | 'inbox' | 'auto';
1663
1656
  /** Options for a single-event outbox lookup. */
1664
1657
  interface OutboxEventOptions {
1665
1658
  /** Author hint for routing through the author's outbox relays. */
1666
1659
  author?: string;
1667
1660
  /** Relay hints; treated as a hint subject to shell validation, not a bypass. */
1668
1661
  relays?: string[];
1669
- /** Relay-selection strategy. */
1670
- strategy?: OutboxStrategy;
1671
1662
  /** Wall-clock budget for the lookup, in milliseconds. */
1672
1663
  timeoutMs?: number;
1673
1664
  }
@@ -1677,8 +1668,6 @@ interface OutboxQueryOptions {
1677
1668
  authors?: string[];
1678
1669
  /** Relay hints; treated as a hint subject to shell validation, not a bypass. */
1679
1670
  relays?: string[];
1680
- /** Relay-selection strategy. */
1681
- strategy?: OutboxStrategy;
1682
1671
  /** Maximum events to collect. */
1683
1672
  limit?: number;
1684
1673
  /** Wall-clock budget for the query, in milliseconds. */
@@ -1686,8 +1675,6 @@ interface OutboxQueryOptions {
1686
1675
  }
1687
1676
  /** Options for a live outbox subscription. */
1688
1677
  interface OutboxSubscribeOptions extends OutboxQueryOptions {
1689
- /** Keep the subscription open for real-time events after EOSE. */
1690
- live?: boolean;
1691
1678
  }
1692
1679
  /** Options for an outbox publish. */
1693
1680
  interface OutboxPublishOptions {
@@ -1695,8 +1682,6 @@ interface OutboxPublishOptions {
1695
1682
  relays?: string[];
1696
1683
  /** Recipient authors whose inbox relays should be included for directed events. */
1697
1684
  targetAuthors?: string[];
1698
- /** Relay-selection strategy. */
1699
- strategy?: OutboxStrategy;
1700
1685
  }
1701
1686
  /** A read/write target for relay-plan resolution. */
1702
1687
  interface OutboxTarget {
@@ -1706,8 +1691,6 @@ interface OutboxTarget {
1706
1691
  pubkey?: string;
1707
1692
  /** Whether the plan is for reading (their write relays) or writing (their read relays). */
1708
1693
  direction?: 'read' | 'write';
1709
- /** Relay-selection strategy. */
1710
- strategy?: OutboxStrategy;
1711
1694
  }
1712
1695
  /** The relay plan the shell would use for a target. */
1713
1696
  interface OutboxRelayPlan {
@@ -1812,9 +1795,6 @@ declare function createOutboxService(options: OutboxServiceOptions): ServiceHand
1812
1795
  * - reading an author's events → their **write** relays (where they publish)
1813
1796
  * - writing to reach an author → their **read** relays (their inbox)
1814
1797
  *
1815
- * `strategy` overrides the direction default: `outbox` forces write relays,
1816
- * `inbox` forces read relays, `auto` (default) follows the read/write direction.
1817
- *
1818
1798
  * @example
1819
1799
  * ```ts
1820
1800
  * import { createOutboxService, createRelayPoolOutboxRouter } from '@kehto/services';
@@ -3021,4 +3001,4 @@ declare function createCordnRelayCoordinatorClient(options: CordnRelayCoordinato
3021
3001
  /** Create a Cordn/ContextVM-backed NAP-DM adapter. */
3022
3002
  declare function createCordnDmAdapter(options: CordnDmAdapterOptions): DmAdapter;
3023
3003
 
3024
- export { type AudioServiceOptions, type AudioSource, type BleServiceContext, type BleServiceOptions, type CacheServiceOptions, type CatalogIntentResolver, type CatalogIntentResolverOptions, type CommonServiceContext, type CommonServiceOptions, type ConfigSchemaValidation, type ConfigService, type ConfigServiceOptions, type CoordinatedRelayOptions, type CordnCodecResult, type CordnCoordinatorClient, type CordnCoordinatorSubscription, type CordnDmAdapterOptions, type CordnDmClient, type CordnGroupMessage, type CordnRelayCoordinatorOptions, type CountRequest, type CountResult, type CountServiceOptions, type DmAdapter, type DmConversation, type DmConversationPage, type DmConversationQuery, type DmHexPubkey, DmMemoryStore, type DmMessage, type DmMessagePage, type DmMessageQuery, type DmMessageStatus, type DmOk, type DmPeer, type DmRelayPool, type DmSendRequest, type DmSendResult, type DmService, type DmServiceOptions, type DmStatus, type DmSubscribeRequest, type DmSubscription, type DmTimestamp, type HostCacheBridge, type HostKeyEvent, type HostKeysBridge, type HostMediaBridge, type HttpUploaderOptions, type HttpUploaderRails, type IdentityServiceOptions, type IntentArchetypeSupport, type IntentAvailability, type IntentBehavior, type IntentCandidate, type IntentCatalogEntry, type IntentHandlerPreference, type IntentOpenParams, type IntentRequest, type IntentResolver, type IntentResolverContext, type IntentResult, type IntentServiceOptions, type IntentWindowController, type KeysServiceOptions, type LinkOpenContext, type LinkServiceOptions, type ListsServiceContext, type ListsServiceOptions, type ManifestArchetypeInput, type MaybePromise, type MediaMetadataLike, type MediaPlaybackOwner, type MediaServiceOptions, type MediaSessionCreateOptions, type MediaSessionTarget, type MediaSourceRef, type NdrDmAdapterOptions, type NdrRelayTransport, type NdrRelayTransportOptions, type NdrRumorLike, type NdrRuntimeLike, type Nip17DmAdapterOptions, type NostrTag, type Notification, type NotificationServiceOptions, type NotifyServiceOptions, type OutboxEventOptions, type OutboxEventResult, type OutboxPublishOptions, type OutboxPublishResult, type OutboxQueryOptions, type OutboxRelayPlan, type OutboxRelayPool, type OutboxResult, type OutboxRouter, type OutboxRouterSubscription, type OutboxServiceOptions, type OutboxStrategy, type OutboxSubscribeOptions, type OutboxSubscriptionSink, type OutboxTarget, type RailServerConfig, type RelayListEntry, type RelayPoolOutboxRouterOptions, type RelayPoolServiceOptions, type ResourceInfo, type ResourceInfoContext, type ResourceInfoProvider, type ResourceSchemeInfo, type ResourceService, type ResourceServiceOptions, type SerialServiceContext, type SerialServiceOptions, type SignEvent, type ThemeService, type ThemeServiceOptions, type UploadDimensions, type UploadInfo, type UploadInfoContext, type UploadInfoProvider, type UploadRail, type UploadRailInfo, type UploadRequest, type UploadResult, type UploadServiceOptions, type UploadState, type UploadStatus, type Uploader, type UploaderContext, type WebrtcServiceContext, type WebrtcServiceOptions, createAudioService, createBleService, createBrowserMediaBridge, createCacheService, createCatalogIntentResolver, createCommonService, createConfigService, createCoordinatedRelay, createCordnDmAdapter, createCordnRelayCoordinatorClient, createCountService, createDmService, createHttpUploader, createIdentityService, createIntentService, createKeysService, createLinkService, createListsService, createMediaService, createNdrDmAdapter, createNdrRelayTransport, createNip17DmAdapter, createNotificationService, createNotifyService, createOutboxService, createRelayPoolOutboxRouter, createRelayPoolService, createResourceService, createSerialService, createThemeService, createUploadService, createWebrtcService, manifestToIntentCatalogEntry };
3004
+ export { type AudioServiceOptions, type AudioSource, type BleServiceContext, type BleServiceOptions, type CacheServiceOptions, type CatalogIntentResolver, type CatalogIntentResolverOptions, type CommonServiceContext, type CommonServiceOptions, type ConfigSchemaValidation, type ConfigService, type ConfigServiceOptions, type CoordinatedRelayOptions, type CordnCodecResult, type CordnCoordinatorClient, type CordnCoordinatorSubscription, type CordnDmAdapterOptions, type CordnDmClient, type CordnGroupMessage, type CordnRelayCoordinatorOptions, type CountRequest, type CountResult, type CountServiceOptions, type DmAdapter, type DmConversation, type DmConversationPage, type DmConversationQuery, type DmHexPubkey, DmMemoryStore, type DmMessage, type DmMessagePage, type DmMessageQuery, type DmMessageStatus, type DmOk, type DmPeer, type DmRelayPool, type DmSendRequest, type DmSendResult, type DmService, type DmServiceOptions, type DmStatus, type DmSubscribeRequest, type DmSubscription, type DmTimestamp, type HostCacheBridge, type HostKeyEvent, type HostKeysBridge, type HostMediaBridge, type HttpUploaderOptions, type HttpUploaderRails, type IdentityServiceOptions, type IntentArchetypeSupport, type IntentAvailability, type IntentBehavior, type IntentCandidate, type IntentCatalogEntry, type IntentHandlerPreference, type IntentOpenParams, type IntentRequest, type IntentResolver, type IntentResolverContext, type IntentResult, type IntentServiceOptions, type IntentWindowController, type KeysServiceOptions, type LinkOpenContext, type LinkServiceOptions, type ListsServiceContext, type ListsServiceOptions, type ManifestArchetypeInput, type MaybePromise, type MediaMetadataLike, type MediaPlaybackOwner, type MediaServiceOptions, type MediaSessionCreateOptions, type MediaSessionTarget, type MediaSourceRef, type NdrDmAdapterOptions, type NdrRelayTransport, type NdrRelayTransportOptions, type NdrRumorLike, type NdrRuntimeLike, type Nip17DmAdapterOptions, type NostrTag, type Notification, type NotificationServiceOptions, type NotifyServiceOptions, type OutboxEventOptions, type OutboxEventResult, type OutboxPublishOptions, type OutboxPublishResult, type OutboxQueryOptions, type OutboxRelayPlan, type OutboxRelayPool, type OutboxResult, type OutboxRouter, type OutboxRouterSubscription, type OutboxServiceOptions, type OutboxSubscribeOptions, type OutboxSubscriptionSink, type OutboxTarget, type RailServerConfig, type RelayListEntry, type RelayPoolOutboxRouterOptions, type RelayPoolServiceOptions, type ResourceInfo, type ResourceInfoContext, type ResourceInfoProvider, type ResourceSchemeInfo, type ResourceService, type ResourceServiceOptions, type SerialServiceContext, type SerialServiceOptions, type SignEvent, type ThemeService, type ThemeServiceOptions, type UploadDimensions, type UploadInfo, type UploadInfoContext, type UploadInfoProvider, type UploadRail, type UploadRailInfo, type UploadRequest, type UploadResult, type UploadServiceOptions, type UploadState, type UploadStatus, type Uploader, type UploaderContext, type WebrtcServiceContext, type WebrtcServiceOptions, createAudioService, createBleService, createBrowserMediaBridge, createCacheService, createCatalogIntentResolver, createCommonService, createConfigService, createCoordinatedRelay, createCordnDmAdapter, createCordnRelayCoordinatorClient, createCountService, createDmService, createHttpUploader, createIdentityService, createIntentService, createKeysService, createLinkService, createListsService, createMediaService, createNdrDmAdapter, createNdrRelayTransport, createNip17DmAdapter, createNotificationService, createNotifyService, createOutboxService, createRelayPoolOutboxRouter, createRelayPoolService, createResourceService, createSerialService, createThemeService, createUploadService, createWebrtcService, manifestToIntentCatalogEntry };
package/dist/index.js CHANGED
@@ -2030,6 +2030,59 @@ var OUTBOX_DESCRIPTOR = {
2030
2030
  version: OUTBOX_SERVICE_VERSION,
2031
2031
  description: "NAP-OUTBOX outbox-aware relay routing \u2014 getEvent/query/subscribe/publish/resolveRelays"
2032
2032
  };
2033
+ function isRecord(value) {
2034
+ return typeof value === "object" && value !== null;
2035
+ }
2036
+ function stringArray(value) {
2037
+ if (!Array.isArray(value)) return void 0;
2038
+ const strings = value.filter((item) => typeof item === "string");
2039
+ return strings.length > 0 ? strings : void 0;
2040
+ }
2041
+ function uint(value) {
2042
+ return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
2043
+ }
2044
+ function sanitizeEventOptions(raw) {
2045
+ if (!isRecord(raw)) return void 0;
2046
+ const out = {};
2047
+ if (typeof raw.author === "string") out.author = raw.author;
2048
+ const relays = stringArray(raw.relays);
2049
+ if (relays) out.relays = relays;
2050
+ const timeoutMs = uint(raw.timeoutMs);
2051
+ if (timeoutMs !== void 0) out.timeoutMs = timeoutMs;
2052
+ return Object.keys(out).length > 0 ? out : void 0;
2053
+ }
2054
+ function sanitizeQueryOptions(raw) {
2055
+ if (!isRecord(raw)) return void 0;
2056
+ const out = {};
2057
+ const authors = stringArray(raw.authors);
2058
+ if (authors) out.authors = authors;
2059
+ const relays = stringArray(raw.relays);
2060
+ if (relays) out.relays = relays;
2061
+ const limit = uint(raw.limit);
2062
+ if (limit !== void 0) out.limit = limit;
2063
+ const timeoutMs = uint(raw.timeoutMs);
2064
+ if (timeoutMs !== void 0) out.timeoutMs = timeoutMs;
2065
+ return Object.keys(out).length > 0 ? out : void 0;
2066
+ }
2067
+ var sanitizeSubscribeOptions = sanitizeQueryOptions;
2068
+ function sanitizePublishOptions(raw) {
2069
+ if (!isRecord(raw)) return void 0;
2070
+ const out = {};
2071
+ const relays = stringArray(raw.relays);
2072
+ if (relays) out.relays = relays;
2073
+ const targetAuthors = stringArray(raw.targetAuthors);
2074
+ if (targetAuthors) out.targetAuthors = targetAuthors;
2075
+ return Object.keys(out).length > 0 ? out : void 0;
2076
+ }
2077
+ function sanitizeTarget(raw) {
2078
+ if (!isRecord(raw)) return void 0;
2079
+ const out = {};
2080
+ const authors = stringArray(raw.authors);
2081
+ if (authors) out.authors = authors;
2082
+ if (typeof raw.pubkey === "string") out.pubkey = raw.pubkey;
2083
+ if (raw.direction === "read" || raw.direction === "write") out.direction = raw.direction;
2084
+ return out;
2085
+ }
2033
2086
  function normalizeFilters(raw) {
2034
2087
  if (Array.isArray(raw)) {
2035
2088
  const filters = raw.filter((f) => typeof f === "object" && f !== null);
@@ -2046,7 +2099,6 @@ function buildEventQuery(eventId, eventOptions) {
2046
2099
  queryOptions.authors = [eventOptions.author];
2047
2100
  }
2048
2101
  if (Array.isArray(eventOptions?.relays)) queryOptions.relays = eventOptions.relays;
2049
- if (eventOptions?.strategy !== void 0) queryOptions.strategy = eventOptions.strategy;
2050
2102
  if (eventOptions?.timeoutMs !== void 0) queryOptions.timeoutMs = eventOptions.timeoutMs;
2051
2103
  return { filter, queryOptions };
2052
2104
  }
@@ -2084,7 +2136,7 @@ function handleGetEvent(router, msg, send) {
2084
2136
  return;
2085
2137
  }
2086
2138
  const getEvent = router.getEvent ?? ((eventId, eventOptions) => fallbackGetEvent(router, eventId, eventOptions));
2087
- void getEvent(m.eventId, m.options).then((result2) => sendEventResult(id, m.eventId, result2, send)).catch(
2139
+ void getEvent(m.eventId, sanitizeEventOptions(m.options)).then((result2) => sendEventResult(id, m.eventId, result2, send)).catch(
2088
2140
  (err2) => send({ type: "outbox.getEvent.result", id, error: toErrorMessage(err2) })
2089
2141
  );
2090
2142
  }
@@ -2102,7 +2154,7 @@ function createOutboxService(options) {
2102
2154
  send({ type: "outbox.query.result", id, events: [], error: "invalid filter" });
2103
2155
  return;
2104
2156
  }
2105
- void router.query(filters, m.options).then(
2157
+ void router.query(filters, sanitizeQueryOptions(m.options)).then(
2106
2158
  (result2) => send({
2107
2159
  type: "outbox.query.result",
2108
2160
  id,
@@ -2133,7 +2185,7 @@ function createOutboxService(options) {
2133
2185
  send({ type: "outbox.closed", subId, ...reason === void 0 ? {} : { reason } });
2134
2186
  }
2135
2187
  };
2136
- subscriptions.set(subKey, router.subscribe(filters, m.options, sink));
2188
+ subscriptions.set(subKey, router.subscribe(filters, sanitizeSubscribeOptions(m.options), sink));
2137
2189
  }
2138
2190
  function handleClose(windowId, msg, send) {
2139
2191
  const m = msg;
@@ -2151,7 +2203,7 @@ function createOutboxService(options) {
2151
2203
  send({ type: "outbox.publish.result", id, ok: false, error: "invalid filter" });
2152
2204
  return;
2153
2205
  }
2154
- void router.publish(m.event, m.options).then(
2206
+ void router.publish(m.event, sanitizePublishOptions(m.options)).then(
2155
2207
  (result2) => send({
2156
2208
  type: "outbox.publish.result",
2157
2209
  id,
@@ -2168,11 +2220,12 @@ function createOutboxService(options) {
2168
2220
  function handleResolveRelays(msg, send) {
2169
2221
  const m = msg;
2170
2222
  const id = m.id ?? "";
2171
- if (!m.target || typeof m.target !== "object") {
2223
+ const target = sanitizeTarget(m.target);
2224
+ if (!target) {
2172
2225
  send({ type: "outbox.resolveRelays.result", id, error: "invalid filter" });
2173
2226
  return;
2174
2227
  }
2175
- void router.resolveRelays(m.target).then((plan) => send({ type: "outbox.resolveRelays.result", id, plan })).catch(
2228
+ void router.resolveRelays(target).then((plan) => send({ type: "outbox.resolveRelays.result", id, plan })).catch(
2176
2229
  (err2) => send({ type: "outbox.resolveRelays.result", id, error: toErrorMessage(err2) })
2177
2230
  );
2178
2231
  }
@@ -2233,11 +2286,6 @@ function deriveAuthors(filters, optionAuthors) {
2233
2286
  for (const author of optionAuthors ?? []) authors.add(author);
2234
2287
  return [...authors];
2235
2288
  }
2236
- function wantsWriteRelays(direction, strategy) {
2237
- if (strategy === "outbox") return true;
2238
- if (strategy === "inbox") return false;
2239
- return direction === "read";
2240
- }
2241
2289
  function allowed(ctx, urls) {
2242
2290
  const out = /* @__PURE__ */ new Set();
2243
2291
  for (const url of urls) {
@@ -2245,8 +2293,8 @@ function allowed(ctx, urls) {
2245
2293
  }
2246
2294
  return [...out];
2247
2295
  }
2248
- async function resolvePlan(ctx, pubkeys, direction, strategy, relayHints) {
2249
- const useWrite = wantsWriteRelays(direction, strategy);
2296
+ async function resolvePlan(ctx, pubkeys, direction, relayHints) {
2297
+ const useWrite = direction === "read";
2250
2298
  const collected = /* @__PURE__ */ new Set();
2251
2299
  const missingAuthors = [];
2252
2300
  let sawNip65 = false;
@@ -2344,9 +2392,8 @@ async function queryImpl(ctx, filters, options) {
2344
2392
  if (!ctx.relayPool.isAvailable()) {
2345
2393
  return { events: [], incomplete: true, error: "relay list unavailable" };
2346
2394
  }
2347
- const strategy = options?.strategy ?? "auto";
2348
2395
  const authors = deriveAuthors(filters, options?.authors);
2349
- const plan = await resolvePlan(ctx, authors, "read", strategy, options?.relays);
2396
+ const plan = await resolvePlan(ctx, authors, "read", options?.relays);
2350
2397
  if (plan.relays.length === 0) {
2351
2398
  return { events: [], incomplete: true, error: "relay list unavailable" };
2352
2399
  }
@@ -2372,7 +2419,6 @@ async function getEventImpl(ctx, eventId, options) {
2372
2419
  queryOptions.authors = [options.author];
2373
2420
  }
2374
2421
  if (Array.isArray(options?.relays)) queryOptions.relays = options.relays;
2375
- if (options?.strategy !== void 0) queryOptions.strategy = options.strategy;
2376
2422
  if (options?.timeoutMs !== void 0) queryOptions.timeoutMs = options.timeoutMs;
2377
2423
  const queryResult = await queryImpl(ctx, [filter], queryOptions);
2378
2424
  const eventResult = queryResult.events.find((candidate) => candidate.event.id === eventId);
@@ -2392,21 +2438,10 @@ function closeLiveSub(sub) {
2392
2438
  }
2393
2439
  sub.handles.length = 0;
2394
2440
  }
2395
- function attachLiveRelay(ctx, sub, filters, relayUrl, live, sink) {
2441
+ function attachLiveRelay(ctx, sub, filters, relayUrl, sink) {
2396
2442
  sub.handles.push(relayPoolSubscribe(ctx, filters, relayUrl, (item) => {
2397
2443
  if (sub.closed) return;
2398
- if (item === "EOSE") {
2399
- sub.eoseCount += 1;
2400
- if (!sub.eoseSent && sub.eoseCount >= sub.relayCount) {
2401
- sub.eoseSent = true;
2402
- if (!live) {
2403
- sub.closed = true;
2404
- closeLiveSub(sub);
2405
- sink.closed();
2406
- }
2407
- }
2408
- return;
2409
- }
2444
+ if (item === "EOSE") return;
2410
2445
  if (sub.seen.has(item.id)) return;
2411
2446
  void ctx.verify(item).then((ok) => {
2412
2447
  if (!ok || sub.closed || sub.seen.has(item.id)) return;
@@ -2416,18 +2451,15 @@ function attachLiveRelay(ctx, sub, filters, relayUrl, live, sink) {
2416
2451
  }));
2417
2452
  }
2418
2453
  function startSubscription(ctx, filters, options, sink) {
2419
- const live = options?.live ?? true;
2420
- const strategy = options?.strategy ?? "auto";
2421
2454
  const authors = deriveAuthors(filters, options?.authors);
2422
- const sub = { handles: [], seen: /* @__PURE__ */ new Set(), closed: false, eoseCount: 0, relayCount: 0, eoseSent: false };
2423
- void resolvePlan(ctx, authors, "read", strategy, options?.relays).then((plan) => {
2455
+ const sub = { handles: [], seen: /* @__PURE__ */ new Set(), closed: false };
2456
+ void resolvePlan(ctx, authors, "read", options?.relays).then((plan) => {
2424
2457
  if (sub.closed) return;
2425
2458
  if (plan.relays.length === 0) {
2426
2459
  sink.closed("relay list unavailable");
2427
2460
  return;
2428
2461
  }
2429
- sub.relayCount = plan.relays.length;
2430
- for (const relayUrl of plan.relays) attachLiveRelay(ctx, sub, filters, relayUrl, live, sink);
2462
+ for (const relayUrl of plan.relays) attachLiveRelay(ctx, sub, filters, relayUrl, sink);
2431
2463
  }).catch((err2) => {
2432
2464
  if (!sub.closed) sink.closed(err2 instanceof Error ? err2.message : "subscribe failed");
2433
2465
  });
@@ -2440,12 +2472,11 @@ function startSubscription(ctx, filters, options, sink) {
2440
2472
  };
2441
2473
  }
2442
2474
  async function resolvePublishTargets(ctx, signed, options) {
2443
- const strategy = options?.strategy ?? "auto";
2444
2475
  const targets = /* @__PURE__ */ new Set();
2445
- const authorPlan = await resolvePlan(ctx, [signed.pubkey], "read", strategy === "inbox" ? "auto" : "outbox");
2476
+ const authorPlan = await resolvePlan(ctx, [signed.pubkey], "read");
2446
2477
  for (const url of authorPlan.relays) targets.add(url);
2447
2478
  if (options?.targetAuthors && options.targetAuthors.length > 0) {
2448
- const inboxPlan = await resolvePlan(ctx, options.targetAuthors, "write", "inbox");
2479
+ const inboxPlan = await resolvePlan(ctx, options.targetAuthors, "write");
2449
2480
  for (const url of inboxPlan.relays) targets.add(url);
2450
2481
  }
2451
2482
  for (const url of options?.relays ?? []) targets.add(url);
@@ -2507,7 +2538,7 @@ function createRelayPoolOutboxRouter(options) {
2507
2538
  publish: (template, publishOptions) => publishImpl(ctx, template, publishOptions),
2508
2539
  resolveRelays: (target) => {
2509
2540
  const pubkeys = target.authors ?? (target.pubkey ? [target.pubkey] : []);
2510
- return resolvePlan(ctx, pubkeys, target.direction ?? "read", target.strategy ?? "auto");
2541
+ return resolvePlan(ctx, pubkeys, target.direction ?? "read");
2511
2542
  }
2512
2543
  };
2513
2544
  }