@kehto/services 0.21.0 → 0.21.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/README.md +1 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ Current draft posture:
|
|
|
43
43
|
- `createKeysService` and `createMediaService` ship real reference backends as of v1.4 (see the dedicated sections below). `createKeysService` attaches a document-level `keydown` listener by default and delivers `keys.action` push envelopes to registered napplets; `createMediaService` mirrors session metadata and playback state to `navigator.mediaSession` and emits `media.command` push envelopes on OS transport events. Both accept a host-bridge option (`HostKeysBridge` / `HostMediaBridge`) so Electron / Tauri / native shells can swap in OS-level backends without re-implementing the wire-protocol bookkeeping.
|
|
44
44
|
- `createNotifyService` handles direct `notify.*` envelopes. It is not an INC
|
|
45
45
|
topic handler.
|
|
46
|
-
- `createOutboxService` supports `outbox.getEvent` from draft NAP-OUTBOX. Single-event lookups run through shell-owned relay routing and only return events whose ID matches the request. The draft wire contract keeps `outbox.query` one-shot and `outbox.subscribe` streaming; Kehto's concrete `createRelayPoolOutboxRouter` additionally exposes host-side `queryStream()` so verified query events can arrive before asynchronous NIP-65 discovery completes.
|
|
46
|
+
- `createOutboxService` supports `outbox.getEvent` from draft NAP-OUTBOX. Single-event lookups run through shell-owned relay routing and only return events whose ID matches the request. Hosts can provide `getReadRouter` to scope all event-returning reads (`getEvent`, query, and subscription) to the authenticated source window, plus `getQueryRouter` when one-shot queries need an additional decorator. The draft wire contract keeps `outbox.query` one-shot and `outbox.subscribe` streaming; Kehto's concrete `createRelayPoolOutboxRouter` additionally exposes host-side `queryStream()` so verified query events can arrive before asynchronous NIP-65 discovery completes.
|
|
47
47
|
- `createResourceService` implements NAP-RESOURCE at exact draft head `9511232f69313aa7953d110e35d32cc28d506f66` without choosing a runtime's network policy. Single requests carry optional advisory Blossom `servers`; bulk requests use canonical per-resource `requests: [{ url, servers? }]` entries. The service forwards hints to the injected resolver only for `blossom:`, preserves order and per-entry failures, and exposes optional `resource.info.maxServers`. By default it delegates every syntactically valid URL to the resolver; `resource.info.schemes` remains advisory. Runtimes that want hierarchical-origin grants can supply `isOriginGranted`, `getConnectGrants`, and `resolveIdentity` together, while scheme resolvers retain responsibility for hint validation, SSRF protection, redirects, and fallback policy. The service enforces supplied size/bulk caps, scopes cancellation to the requesting window, drops cancelled terminal envelopes, never forwards response headers, and preserves explicit `ResourceServiceError` codes.
|
|
48
48
|
- `createUploadService` supports `upload.info` from draft NAP-UPLOAD. Hosts may expose configured rails, return URL forms, maximum bytes, and MIME type policy without requiring napplets to start an upload.
|
|
49
49
|
- `createConfigService` implements draft NAP-CONFIG's shell-writer boundary: recursive bounded-subset schema validation, per-window schema/subscription state, deterministic defaults, invalid/orphan removal, version rollback rejection, scoped host persistence hooks, and settings-UI commits. Reads before schema registration fail closed with `no-schema`.
|
package/dist/index.d.ts
CHANGED
|
@@ -1416,6 +1416,8 @@ interface ResourceFetchInit {
|
|
|
1416
1416
|
headers?: Record<string, string>;
|
|
1417
1417
|
/** Request-scoped cancellation signal. */
|
|
1418
1418
|
signal: AbortSignal;
|
|
1419
|
+
/** Authenticated source window, for runtime-private scoped policy state. */
|
|
1420
|
+
windowId?: string;
|
|
1419
1421
|
/** Advisory Blossom server origins for this resource only. */
|
|
1420
1422
|
servers?: readonly string[];
|
|
1421
1423
|
}
|
|
@@ -1715,7 +1717,19 @@ interface OutboxServiceOptions {
|
|
|
1715
1717
|
/** The outbox router the shell uses to reach relays. Required. */
|
|
1716
1718
|
router: OutboxRouter;
|
|
1717
1719
|
/**
|
|
1718
|
-
* Optionally selects a
|
|
1720
|
+
* Optionally selects a source-scoped router for event-returning reads.
|
|
1721
|
+
*
|
|
1722
|
+
* The selected router is used for `outbox.getEvent`, `outbox.query`, and
|
|
1723
|
+
* `outbox.subscribe`. A query-specific router takes precedence when both
|
|
1724
|
+
* hooks are supplied.
|
|
1725
|
+
*
|
|
1726
|
+
* @param windowId - The authenticated source window for the request.
|
|
1727
|
+
* @param context - Narrow runtime context for source-bound policy checks.
|
|
1728
|
+
* @returns Router used for that source's event-returning reads.
|
|
1729
|
+
*/
|
|
1730
|
+
getReadRouter?(windowId: string, context: ServiceRuntimeContext | undefined): OutboxRouter;
|
|
1731
|
+
/**
|
|
1732
|
+
* Optionally selects a query-specific router for a live napplet source.
|
|
1719
1733
|
*
|
|
1720
1734
|
* @param windowId - The authenticated source window for the request.
|
|
1721
1735
|
* @param context - Narrow runtime context for source-bound policy checks.
|
package/dist/index.js
CHANGED
|
@@ -2405,6 +2405,7 @@ async function fetchResourceItem(options, windowId, info, request, signal) {
|
|
|
2405
2405
|
const response = await options.fetch(url, {
|
|
2406
2406
|
method: "GET",
|
|
2407
2407
|
signal,
|
|
2408
|
+
windowId,
|
|
2408
2409
|
...parsedUrl.protocol === "blossom:" && request.servers !== void 0 ? { servers: [...request.servers] } : {}
|
|
2409
2410
|
});
|
|
2410
2411
|
const buffer = await response.arrayBuffer();
|
|
@@ -2720,7 +2721,7 @@ function createOutboxService(options) {
|
|
|
2720
2721
|
if (!options || typeof options.router !== "object" || options.router === null) {
|
|
2721
2722
|
throw new Error("createOutboxService: options.router is required");
|
|
2722
2723
|
}
|
|
2723
|
-
const { router, getQueryRouter } = options;
|
|
2724
|
+
const { router, getReadRouter, getQueryRouter } = options;
|
|
2724
2725
|
let runtimeContext;
|
|
2725
2726
|
const subscriptions = /* @__PURE__ */ new Map();
|
|
2726
2727
|
function handleQuery(windowId, msg, send) {
|
|
@@ -2731,7 +2732,7 @@ function createOutboxService(options) {
|
|
|
2731
2732
|
send({ type: "outbox.query.result", id, events: [], error: "invalid filter" });
|
|
2732
2733
|
return;
|
|
2733
2734
|
}
|
|
2734
|
-
const queryRouter = getQueryRouter?.(windowId, runtimeContext) ?? router;
|
|
2735
|
+
const queryRouter = getQueryRouter?.(windowId, runtimeContext) ?? getReadRouter?.(windowId, runtimeContext) ?? router;
|
|
2735
2736
|
void queryRouter.query(filters, sanitizeQueryOptions(m.options)).then(
|
|
2736
2737
|
(result2) => send({
|
|
2737
2738
|
type: "outbox.query.result",
|
|
@@ -2763,7 +2764,8 @@ function createOutboxService(options) {
|
|
|
2763
2764
|
send({ type: "outbox.closed", subId, ...reason === void 0 ? {} : { reason } });
|
|
2764
2765
|
}
|
|
2765
2766
|
};
|
|
2766
|
-
|
|
2767
|
+
const readRouter = getReadRouter?.(windowId, runtimeContext) ?? router;
|
|
2768
|
+
subscriptions.set(subKey, readRouter.subscribe(filters, sanitizeSubscribeOptions(m.options), sink));
|
|
2767
2769
|
}
|
|
2768
2770
|
function handleClose(windowId, msg, send) {
|
|
2769
2771
|
const m = msg;
|
|
@@ -2818,7 +2820,7 @@ function createOutboxService(options) {
|
|
|
2818
2820
|
handleMessage(windowId, message, send) {
|
|
2819
2821
|
switch (message.type) {
|
|
2820
2822
|
case "outbox.getEvent":
|
|
2821
|
-
handleGetEvent(router, message, send);
|
|
2823
|
+
handleGetEvent(getReadRouter?.(windowId, runtimeContext) ?? router, message, send);
|
|
2822
2824
|
return;
|
|
2823
2825
|
case "outbox.query":
|
|
2824
2826
|
handleQuery(windowId, message, send);
|