@kehto/services 0.18.0 → 0.19.0

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
@@ -1,4 +1,4 @@
1
- import { ServiceHandler, Signer, RelayEventResult } from '@kehto/runtime';
1
+ import { ServiceHandler, Signer, RelayEventResult, ServiceRuntimeContext } from '@kehto/runtime';
2
2
  import { IdentityGetProfileMessage, IdentityGetProfileResultMessage, IdentityGetFollowsMessage, IdentityGetFollowsResultMessage, IdentityGetListMessage, IdentityGetListResultMessage, IdentityGetZapsMessage, IdentityGetZapsResultMessage, IdentityGetMutesMessage, IdentityGetMutesResultMessage, IdentityGetBlockedMessage, IdentityGetBlockedResultMessage, IdentityGetBadgesMessage, IdentityGetBadgesResultMessage } from '@napplet/nap/identity/types';
3
3
  import { NostrFilter, NostrEvent, EventTemplate, IntentRequest, IntentResult, IntentAvailability, IntentBehavior, IntentCandidate, LinkOpenOptions, LinkOpenResult, ListSupport, ListRef, ListItem, ListOptions, ListMutationResult, SerialOpenRequest, SerialOpenResult, BleEvent, BleOpenRequest, BleOpenResult, BleService, BleAttribute, BleWriteOptions, WebrtcEvent, WebrtcOpenRequest, WebrtcOpenResult, CommonProfileTarget, CommonProfileResult, CommonFollowsResult, CommonActionResult, CommonReaction, CommonReportTarget, CommonReportReason } from '@napplet/core';
4
4
  export { IntentAvailability, IntentBehavior, IntentCandidate, IntentHandlerPreference, IntentOpenOptions, IntentRequest, IntentResult } from '@napplet/core';
@@ -1707,6 +1707,14 @@ interface StreamingOutboxRouter extends OutboxRouter {
1707
1707
  interface OutboxServiceOptions {
1708
1708
  /** The outbox router the shell uses to reach relays. Required. */
1709
1709
  router: OutboxRouter;
1710
+ /**
1711
+ * Optionally selects a request-scoped router for a live napplet source.
1712
+ *
1713
+ * @param windowId - The authenticated source window for the request.
1714
+ * @param context - Narrow runtime context for source-bound policy checks.
1715
+ * @returns Router used only for that source's one-shot outbox queries.
1716
+ */
1717
+ getQueryRouter?(windowId: string, context: ServiceRuntimeContext | undefined): OutboxRouter;
1710
1718
  }
1711
1719
  /**
1712
1720
  * Create the NAP-OUTBOX service handler.
package/dist/index.js CHANGED
@@ -2182,9 +2182,10 @@ function createOutboxService(options) {
2182
2182
  if (!options || typeof options.router !== "object" || options.router === null) {
2183
2183
  throw new Error("createOutboxService: options.router is required");
2184
2184
  }
2185
- const { router } = options;
2185
+ const { router, getQueryRouter } = options;
2186
+ let runtimeContext;
2186
2187
  const subscriptions = /* @__PURE__ */ new Map();
2187
- function handleQuery(msg, send) {
2188
+ function handleQuery(windowId, msg, send) {
2188
2189
  const m = msg;
2189
2190
  const id = m.id ?? "";
2190
2191
  const filters = normalizeFilters(m.filters);
@@ -2192,7 +2193,8 @@ function createOutboxService(options) {
2192
2193
  send({ type: "outbox.query.result", id, events: [], error: "invalid filter" });
2193
2194
  return;
2194
2195
  }
2195
- void router.query(filters, sanitizeQueryOptions(m.options)).then(
2196
+ const queryRouter = getQueryRouter?.(windowId, runtimeContext) ?? router;
2197
+ void queryRouter.query(filters, sanitizeQueryOptions(m.options)).then(
2196
2198
  (result2) => send({
2197
2199
  type: "outbox.query.result",
2198
2200
  id,
@@ -2269,13 +2271,19 @@ function createOutboxService(options) {
2269
2271
  }
2270
2272
  return {
2271
2273
  descriptor: OUTBOX_DESCRIPTOR,
2274
+ onRegistered(context) {
2275
+ runtimeContext = context;
2276
+ },
2277
+ onUnregistered() {
2278
+ runtimeContext = void 0;
2279
+ },
2272
2280
  handleMessage(windowId, message, send) {
2273
2281
  switch (message.type) {
2274
2282
  case "outbox.getEvent":
2275
2283
  handleGetEvent(router, message, send);
2276
2284
  return;
2277
2285
  case "outbox.query":
2278
- handleQuery(message, send);
2286
+ handleQuery(windowId, message, send);
2279
2287
  return;
2280
2288
  case "outbox.subscribe":
2281
2289
  handleSubscribe(windowId, message, send);
@@ -3527,20 +3535,20 @@ function createCatalogIntentResolver(options) {
3527
3535
  }
3528
3536
 
3529
3537
  // src/manifest-intent-catalog.ts
3530
- function actionFromConvention(slug, convention) {
3531
- if (!/^[a-z0-9][a-z0-9-]*$/.test(slug)) {
3532
- throw new TypeError("manifest archetype slug is invalid");
3533
- }
3538
+ function actionFromConvention(convention) {
3534
3539
  const match = /^napplet:([^/?#\s]+)\/([^/?#\s]+)$/.exec(convention);
3535
- if (!match || match[1] !== slug) {
3536
- throw new TypeError("manifest archetype convention is invalid or mismatched");
3540
+ if (!match) {
3541
+ throw new TypeError("manifest archetype convention is invalid");
3537
3542
  }
3538
3543
  return match[2];
3539
3544
  }
3540
3545
  function manifestToIntentCatalogEntry(manifest) {
3541
3546
  const archetypes = {};
3542
3547
  for (const { slug, convention } of manifest.archetypes) {
3543
- const action = actionFromConvention(slug, convention);
3548
+ if (!/^[a-z0-9][a-z0-9-]*$/.test(slug)) {
3549
+ throw new TypeError("manifest archetype slug is invalid");
3550
+ }
3551
+ const action = actionFromConvention(convention);
3544
3552
  const support = archetypes[slug] ??= {
3545
3553
  actions: [],
3546
3554
  conventions: []