@kehto/services 0.20.1 → 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 +3 -3
- package/dist/index.d.ts +30 -18
- package/dist/index.js +35 -20
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ pnpm add @kehto/services
|
|
|
17
17
|
## Published Napplet Compatibility
|
|
18
18
|
|
|
19
19
|
`@kehto/services` publishes against `@napplet/core` and `@napplet/nap`
|
|
20
|
-
`>=0.
|
|
20
|
+
`>=0.32.0 <0.33.0`. The exact installed contracts are core 0.32.0 / nap 0.32.0
|
|
21
21
|
from NAP-INTENT authority `5ac0490461ca6fec2f0d2e45b4835cf9bc08de24`,
|
|
22
22
|
napplet/web#199 source `3037200c932488f14f7f369b8583c39c9c16510a` / merge
|
|
23
23
|
`b3f0007867eac109fa4917fac9c285d3b7cc6155`, and Version Packages #198 release
|
|
@@ -43,8 +43,8 @@ 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.
|
|
47
|
-
- `createResourceService` implements
|
|
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
|
+
- `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`.
|
|
50
50
|
- `createDmService` keeps NAP-DM request correlation, per-window subscriptions, and packaged message shapes in runtime-owned code. Adapters cover concrete transports: verified NIP-17 gift wraps and relay history via `nostr-tools`, structural NDR runtimes with relay hooks, and Cordn/ContextVM coordinator clients.
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export { MediaAction } from '@napplet/nap/media/types';
|
|
|
7
7
|
import { NotifyActionMessage, NotifyClickedMessage, NotifyDismissedMessage, NotifySendMessage, NotifyChannelRegisterMessage, NotifyControl } from '@napplet/nap/notify/types';
|
|
8
8
|
import { Theme, ThemeChangedMessage } from '@napplet/nap/theme/types';
|
|
9
9
|
import { ConfigSchemaErrorCode, NappletConfigSchema, ConfigValues } from '@napplet/nap/config/types';
|
|
10
|
+
import { ResourceInfo } from '@napplet/nap/resource/types';
|
|
11
|
+
export { ResourceBytesRequest, ResourceInfo, ResourceSchemeInfo } from '@napplet/nap/resource/types';
|
|
10
12
|
export { a as CvmCloseMessage, b as CvmCloseResultMessage, c as CvmDiscoverMessage, d as CvmDiscoverQuery, e as CvmDiscoverResultMessage, f as CvmEventMessage, g as CvmInboundMessage, h as CvmOutboundMessage, i as CvmRequestMessage, j as CvmRequestOptions, k as CvmRequestResultMessage, l as CvmServer, m as CvmServerRef, n as CvmService, o as CvmServiceOptions, C as CvmTransport, p as CvmTransportError, M as McpContentBlock, q as McpMessage, r as McpTool, s as McpToolResult, t as createCvmService } from './cvm-service-t5syG4tU.js';
|
|
11
13
|
|
|
12
14
|
/**
|
|
@@ -1406,16 +1408,18 @@ declare function createConfigService(options: ConfigServiceOptions): ConfigServi
|
|
|
1406
1408
|
* ```
|
|
1407
1409
|
*/
|
|
1408
1410
|
|
|
1409
|
-
/**
|
|
1410
|
-
interface
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1411
|
+
/** Read-only metadata passed from the resource service to a runtime resolver. */
|
|
1412
|
+
interface ResourceFetchInit {
|
|
1413
|
+
/** Read-only HTTP method selected by the service. */
|
|
1414
|
+
method?: string;
|
|
1415
|
+
/** Optional runtime-owned request headers. */
|
|
1416
|
+
headers?: Record<string, string>;
|
|
1417
|
+
/** Request-scoped cancellation signal. */
|
|
1418
|
+
signal: AbortSignal;
|
|
1419
|
+
/** Authenticated source window, for runtime-private scoped policy state. */
|
|
1420
|
+
windowId?: string;
|
|
1421
|
+
/** Advisory Blossom server origins for this resource only. */
|
|
1422
|
+
servers?: readonly string[];
|
|
1419
1423
|
}
|
|
1420
1424
|
/** Context passed to a host-provided resource info resolver. */
|
|
1421
1425
|
interface ResourceInfoContext {
|
|
@@ -1445,13 +1449,9 @@ interface ResourceServiceOptions {
|
|
|
1445
1449
|
* canonical protocol error classification.
|
|
1446
1450
|
*
|
|
1447
1451
|
* @param url - The URL from the resource.bytes request
|
|
1448
|
-
* @param init - Read-only method
|
|
1452
|
+
* @param init - Read-only method, request-scoped AbortSignal, and optional advisory Blossom servers
|
|
1449
1453
|
*/
|
|
1450
|
-
fetch(url: string, init:
|
|
1451
|
-
method?: string;
|
|
1452
|
-
headers?: Record<string, string>;
|
|
1453
|
-
signal: AbortSignal;
|
|
1454
|
-
}): Promise<Response>;
|
|
1454
|
+
fetch(url: string, init: ResourceFetchInit): Promise<Response>;
|
|
1455
1455
|
/**
|
|
1456
1456
|
* Returns true if `origin` is present in `grants` (the list returned by
|
|
1457
1457
|
* `getConnectGrants` for the napplet's dTag + aggregateHash).
|
|
@@ -1717,7 +1717,19 @@ interface OutboxServiceOptions {
|
|
|
1717
1717
|
/** The outbox router the shell uses to reach relays. Required. */
|
|
1718
1718
|
router: OutboxRouter;
|
|
1719
1719
|
/**
|
|
1720
|
-
* 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.
|
|
1721
1733
|
*
|
|
1722
1734
|
* @param windowId - The authenticated source window for the request.
|
|
1723
1735
|
* @param context - Narrow runtime context for source-bound policy checks.
|
|
@@ -2849,4 +2861,4 @@ interface FsService extends ServiceHandler {
|
|
|
2849
2861
|
*/
|
|
2850
2862
|
declare function createFsService(options: FsServiceOptions): FsService;
|
|
2851
2863
|
|
|
2852
|
-
export { type BleServiceContext, type BleServiceOptions, type CacheServiceOptions, type CatalogIntentResolver, type CatalogIntentResolverOptions, type CommonServiceContext, type CommonServiceOptions, type ConfigSchemaValidation, type ConfigService, type ConfigServiceOptions, type ConfigSettingsContext, type CoordinatedRelayOptions, type CordnCodecResult, type CordnCoordinatorClient, type CordnCoordinatorSubscription, type CordnDmAdapterOptions, type CordnDmClient, type CordnGroupMessage, type CordnRelayCoordinatorOptions, type CountRequest, type CountResult, type CountServiceOptions, type DmAdapter, DmMemoryStore, type DmRelayPool, type DmService, type DmServiceOptions, type FsBackend, type FsBackendChange, type FsBackendWatch, type FsService, FsServiceError, type FsServiceOptions, type HostCacheBridge, type HostKeyEvent, type HostKeysBridge, type HostMediaBridge, type HttpUploaderOptions, type HttpUploaderRails, type IdentityServiceOptions, type IntentArchetypeSupport, type IntentCatalogEntry, type IntentDispatchParams, type IntentResolver, type IntentResolverContext, type IntentServiceOptions, type IntentTargetController, type IntentTargetDispatch, 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 NotifyInteractionMessage, type NotifyPresentation, type NotifyServiceOptions, type OutboxEventOptions, type OutboxEventResult, type OutboxPublishOptions, type OutboxPublishResult, type OutboxQueryOptions, type OutboxQueryStream, type OutboxQueryStreamSink, 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 ResourceErrorCode, type
|
|
2864
|
+
export { type BleServiceContext, type BleServiceOptions, type CacheServiceOptions, type CatalogIntentResolver, type CatalogIntentResolverOptions, type CommonServiceContext, type CommonServiceOptions, type ConfigSchemaValidation, type ConfigService, type ConfigServiceOptions, type ConfigSettingsContext, type CoordinatedRelayOptions, type CordnCodecResult, type CordnCoordinatorClient, type CordnCoordinatorSubscription, type CordnDmAdapterOptions, type CordnDmClient, type CordnGroupMessage, type CordnRelayCoordinatorOptions, type CountRequest, type CountResult, type CountServiceOptions, type DmAdapter, DmMemoryStore, type DmRelayPool, type DmService, type DmServiceOptions, type FsBackend, type FsBackendChange, type FsBackendWatch, type FsService, FsServiceError, type FsServiceOptions, type HostCacheBridge, type HostKeyEvent, type HostKeysBridge, type HostMediaBridge, type HttpUploaderOptions, type HttpUploaderRails, type IdentityServiceOptions, type IntentArchetypeSupport, type IntentCatalogEntry, type IntentDispatchParams, type IntentResolver, type IntentResolverContext, type IntentServiceOptions, type IntentTargetController, type IntentTargetDispatch, 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 NotifyInteractionMessage, type NotifyPresentation, type NotifyServiceOptions, type OutboxEventOptions, type OutboxEventResult, type OutboxPublishOptions, type OutboxPublishResult, type OutboxQueryOptions, type OutboxQueryStream, type OutboxQueryStreamSink, 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 ResourceErrorCode, type ResourceFetchInit, type ResourceInfoContext, type ResourceInfoProvider, type ResourceService, ResourceServiceError, type ResourceServiceOptions, type SerialServiceContext, type SerialServiceOptions, type SignEvent, type StreamingOutboxRouter, 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, createBleService, createBrowserMediaBridge, createCacheService, createCatalogIntentResolver, createCommonService, createConfigService, createCoordinatedRelay, createCordnDmAdapter, createCordnRelayCoordinatorClient, createCountService, createDmService, createFsService, createHttpUploader, createIdentityService, createIntentService, createKeysService, createLinkService, createListsService, createMediaService, createNdrDmAdapter, createNdrRelayTransport, createNip17DmAdapter, createNotificationService, createNotifyService, createOutboxService, createRelayPoolOutboxRouter, createRelayPoolService, createResourceService, createSerialService, createThemeService, createUploadService, createWebrtcService, manifestToIntentCatalogEntry, resolveConfigValues, validateConfigSchema };
|
package/dist/index.js
CHANGED
|
@@ -2336,7 +2336,8 @@ function normalizeResourceInfo(info) {
|
|
|
2336
2336
|
return {
|
|
2337
2337
|
schemes: Array.isArray(info.schemes) ? info.schemes.filter((scheme) => typeof scheme?.scheme === "string").map((scheme) => ({ scheme: scheme.scheme, enabled: scheme.enabled !== false })) : [],
|
|
2338
2338
|
...typeof info.maxBytes === "number" ? { maxBytes: info.maxBytes } : {},
|
|
2339
|
-
...typeof info.maxUrls === "number" ? { maxUrls: info.maxUrls } : {}
|
|
2339
|
+
...typeof info.maxUrls === "number" ? { maxUrls: info.maxUrls } : {},
|
|
2340
|
+
...typeof info.maxServers === "number" ? { maxServers: info.maxServers } : {}
|
|
2340
2341
|
};
|
|
2341
2342
|
}
|
|
2342
2343
|
async function resolveResourceInfo(options, windowId) {
|
|
@@ -2375,10 +2376,11 @@ function classifyResourceFailure(error) {
|
|
|
2375
2376
|
message: error instanceof Error ? error.message : String(error)
|
|
2376
2377
|
};
|
|
2377
2378
|
}
|
|
2378
|
-
async function fetchResourceItem(options, windowId, info,
|
|
2379
|
+
async function fetchResourceItem(options, windowId, info, request, signal) {
|
|
2380
|
+
const { url } = request;
|
|
2379
2381
|
const parsedUrl = parseResourceUrl(url);
|
|
2380
2382
|
if (!parsedUrl) return resourceInvalidRequest(url, `invalid URL: ${url}`);
|
|
2381
|
-
if (options.isOriginGranted && options.getConnectGrants) {
|
|
2383
|
+
if (parsedUrl.origin !== "null" && options.isOriginGranted && options.getConnectGrants) {
|
|
2382
2384
|
const identity = options.resolveIdentity?.(windowId) ?? null;
|
|
2383
2385
|
if (!identity) {
|
|
2384
2386
|
return {
|
|
@@ -2402,7 +2404,9 @@ async function fetchResourceItem(options, windowId, info, url, signal) {
|
|
|
2402
2404
|
try {
|
|
2403
2405
|
const response = await options.fetch(url, {
|
|
2404
2406
|
method: "GET",
|
|
2405
|
-
signal
|
|
2407
|
+
signal,
|
|
2408
|
+
windowId,
|
|
2409
|
+
...parsedUrl.protocol === "blossom:" && request.servers !== void 0 ? { servers: [...request.servers] } : {}
|
|
2406
2410
|
});
|
|
2407
2411
|
const buffer = await response.arrayBuffer();
|
|
2408
2412
|
if (info.maxBytes !== void 0 && buffer.byteLength > info.maxBytes) {
|
|
@@ -2426,12 +2430,12 @@ async function fetchResourceItem(options, windowId, info, url, signal) {
|
|
|
2426
2430
|
}
|
|
2427
2431
|
}
|
|
2428
2432
|
async function handleBytes(options, state, windowId, msg, send) {
|
|
2429
|
-
const { requestId,
|
|
2433
|
+
const { requestId, ...request } = msg;
|
|
2430
2434
|
const controller = new AbortController();
|
|
2431
2435
|
trackRequest(state, requestId, windowId, controller);
|
|
2432
2436
|
try {
|
|
2433
2437
|
const info = await resolveResourceInfo(options, windowId);
|
|
2434
|
-
const item = await fetchResourceItem(options, windowId, info,
|
|
2438
|
+
const item = await fetchResourceItem(options, windowId, info, request, controller.signal);
|
|
2435
2439
|
if (controller.signal.aborted) return;
|
|
2436
2440
|
if (!item.ok) {
|
|
2437
2441
|
sendResourceError(send, requestId, item.message, item.error);
|
|
@@ -2453,9 +2457,9 @@ async function handleBytes(options, state, windowId, msg, send) {
|
|
|
2453
2457
|
}
|
|
2454
2458
|
}
|
|
2455
2459
|
async function handleBytesMany(options, state, windowId, msg, send) {
|
|
2456
|
-
const { requestId,
|
|
2457
|
-
if (!
|
|
2458
|
-
sendBytesManyError(send, requestId, "resource.bytesMany requires a non-empty
|
|
2460
|
+
const { requestId, requests } = msg;
|
|
2461
|
+
if (!isResourceRequestList(requests)) {
|
|
2462
|
+
sendBytesManyError(send, requestId, "resource.bytesMany requires a non-empty requests array", "invalid-request");
|
|
2459
2463
|
return;
|
|
2460
2464
|
}
|
|
2461
2465
|
let info;
|
|
@@ -2466,7 +2470,7 @@ async function handleBytesMany(options, state, windowId, msg, send) {
|
|
|
2466
2470
|
sendBytesManyError(send, requestId, failure.message, failure.error);
|
|
2467
2471
|
return;
|
|
2468
2472
|
}
|
|
2469
|
-
if (info.maxUrls !== void 0 &&
|
|
2473
|
+
if (info.maxUrls !== void 0 && requests.length > info.maxUrls) {
|
|
2470
2474
|
sendBytesManyError(send, requestId, `resource.bytesMany exceeds ${info.maxUrls} URLs`, "too-large");
|
|
2471
2475
|
return;
|
|
2472
2476
|
}
|
|
@@ -2474,8 +2478,8 @@ async function handleBytesMany(options, state, windowId, msg, send) {
|
|
|
2474
2478
|
trackRequest(state, requestId, windowId, controller);
|
|
2475
2479
|
try {
|
|
2476
2480
|
const items = [];
|
|
2477
|
-
for (const
|
|
2478
|
-
const item = await fetchResourceItem(options, windowId, info,
|
|
2481
|
+
for (const request of requests) {
|
|
2482
|
+
const item = await fetchResourceItem(options, windowId, info, request, controller.signal);
|
|
2479
2483
|
if (controller.signal.aborted) return;
|
|
2480
2484
|
if (item.ok) {
|
|
2481
2485
|
items.push({
|
|
@@ -2507,6 +2511,12 @@ async function handleBytesMany(options, state, windowId, msg, send) {
|
|
|
2507
2511
|
untrackRequest(state, windowId, requestId);
|
|
2508
2512
|
}
|
|
2509
2513
|
}
|
|
2514
|
+
function hasValidServerHints(request) {
|
|
2515
|
+
return request.servers === void 0 || Array.isArray(request.servers) && request.servers.every((server) => typeof server === "string");
|
|
2516
|
+
}
|
|
2517
|
+
function isResourceRequestList(value) {
|
|
2518
|
+
return Array.isArray(value) && value.length > 0 && value.every((request) => typeof request === "object" && request !== null && typeof request.url === "string" && hasValidServerHints(request));
|
|
2519
|
+
}
|
|
2510
2520
|
function handleCancel(state, windowId, requestId) {
|
|
2511
2521
|
const entry = state.inFlight.get(requestKey(windowId, requestId));
|
|
2512
2522
|
if (entry) {
|
|
@@ -2544,11 +2554,15 @@ function createResourceService(options) {
|
|
|
2544
2554
|
const m = message;
|
|
2545
2555
|
const requestId = requestIdFromMessage(m);
|
|
2546
2556
|
if (!requestId) return;
|
|
2547
|
-
if (typeof m.url !== "string") {
|
|
2548
|
-
sendResourceError(send, requestId, "resource.bytes requires a URL", "invalid-request");
|
|
2557
|
+
if (typeof m.url !== "string" || !hasValidServerHints(m)) {
|
|
2558
|
+
sendResourceError(send, requestId, "resource.bytes requires a URL and optional string servers", "invalid-request");
|
|
2549
2559
|
return;
|
|
2550
2560
|
}
|
|
2551
|
-
handleBytes(options, state, windowId, {
|
|
2561
|
+
handleBytes(options, state, windowId, {
|
|
2562
|
+
requestId,
|
|
2563
|
+
url: m.url,
|
|
2564
|
+
...m.servers !== void 0 ? { servers: [...m.servers] } : {}
|
|
2565
|
+
}, send).catch(() => {
|
|
2552
2566
|
});
|
|
2553
2567
|
return;
|
|
2554
2568
|
}
|
|
@@ -2564,7 +2578,7 @@ function createResourceService(options) {
|
|
|
2564
2578
|
const m = message;
|
|
2565
2579
|
const requestId = requestIdFromMessage(m);
|
|
2566
2580
|
if (!requestId) return;
|
|
2567
|
-
handleBytesMany(options, state, windowId, { requestId,
|
|
2581
|
+
handleBytesMany(options, state, windowId, { requestId, requests: m.requests ?? [] }, send).catch(() => {
|
|
2568
2582
|
});
|
|
2569
2583
|
return;
|
|
2570
2584
|
}
|
|
@@ -2707,7 +2721,7 @@ function createOutboxService(options) {
|
|
|
2707
2721
|
if (!options || typeof options.router !== "object" || options.router === null) {
|
|
2708
2722
|
throw new Error("createOutboxService: options.router is required");
|
|
2709
2723
|
}
|
|
2710
|
-
const { router, getQueryRouter } = options;
|
|
2724
|
+
const { router, getReadRouter, getQueryRouter } = options;
|
|
2711
2725
|
let runtimeContext;
|
|
2712
2726
|
const subscriptions = /* @__PURE__ */ new Map();
|
|
2713
2727
|
function handleQuery(windowId, msg, send) {
|
|
@@ -2718,7 +2732,7 @@ function createOutboxService(options) {
|
|
|
2718
2732
|
send({ type: "outbox.query.result", id, events: [], error: "invalid filter" });
|
|
2719
2733
|
return;
|
|
2720
2734
|
}
|
|
2721
|
-
const queryRouter = getQueryRouter?.(windowId, runtimeContext) ?? router;
|
|
2735
|
+
const queryRouter = getQueryRouter?.(windowId, runtimeContext) ?? getReadRouter?.(windowId, runtimeContext) ?? router;
|
|
2722
2736
|
void queryRouter.query(filters, sanitizeQueryOptions(m.options)).then(
|
|
2723
2737
|
(result2) => send({
|
|
2724
2738
|
type: "outbox.query.result",
|
|
@@ -2750,7 +2764,8 @@ function createOutboxService(options) {
|
|
|
2750
2764
|
send({ type: "outbox.closed", subId, ...reason === void 0 ? {} : { reason } });
|
|
2751
2765
|
}
|
|
2752
2766
|
};
|
|
2753
|
-
|
|
2767
|
+
const readRouter = getReadRouter?.(windowId, runtimeContext) ?? router;
|
|
2768
|
+
subscriptions.set(subKey, readRouter.subscribe(filters, sanitizeSubscribeOptions(m.options), sink));
|
|
2754
2769
|
}
|
|
2755
2770
|
function handleClose(windowId, msg, send) {
|
|
2756
2771
|
const m = msg;
|
|
@@ -2805,7 +2820,7 @@ function createOutboxService(options) {
|
|
|
2805
2820
|
handleMessage(windowId, message, send) {
|
|
2806
2821
|
switch (message.type) {
|
|
2807
2822
|
case "outbox.getEvent":
|
|
2808
|
-
handleGetEvent(router, message, send);
|
|
2823
|
+
handleGetEvent(getReadRouter?.(windowId, runtimeContext) ?? router, message, send);
|
|
2809
2824
|
return;
|
|
2810
2825
|
case "outbox.query":
|
|
2811
2826
|
handleQuery(windowId, message, send);
|