@tinycloud/node-sdk 3.4.0 → 3.5.0-beta.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/core.d.cts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { ReplicationOptions } from '@tinycloud/sdk-core';
2
2
  export { ACCOUNT_REGISTRY_PATH, ACCOUNT_REGISTRY_SPACE, AccountApplication, AccountApplicationListOptions, AccountApplicationRegisterOptions, AccountDelegation, AccountDelegationListOptions, AccountDelegationRevokeOptions, AccountIndexEnsureResult, AccountIndexRebuildResult, AccountIndexStatus, AccountIndexedReadOptions, AccountService, AccountServiceConfig, AccountSpace, AccountSpaceListOptions, AccountStatus, AuthorityRefusal, AutoApproveSpaceCreationHandler, AutoRejectStrategy, AutoSignStrategy, BatchOptions, BatchResponse, CallbackStrategy, CanonicalAddress, CanonicalParsedNetworkId, CapabilityEntry, CapabilityKeyRegistry, CapabilityKeyRegistryErrorCode, CapabilityKeyRegistryErrorCodes, CaveatedDelegationUnsupportedError, ClientSession, ColumnInfo, ComposeManifestOptions, ComposedManifestRequest, CreateDelegationParams, DEFAULT_MANIFEST_SPACE, DEFAULT_MANIFEST_VERSION, DEFAULT_SIGNED_READ_URL_EXPIRY_MS, DataVaultConfig, DataVaultService, DatabaseHandle, DelegateReceivedShareParams, DelegatedShareAccess, Delegation, DelegationChain, DelegationChainV2, DelegationDirection, DelegationError, DelegationErrorCode, DelegationErrorCodes, DelegationFilters, DelegationManager, DelegationManagerConfig, DelegationRecord, DelegationResult, DidCacheKeyOptions, DidEqualsOptions, DuckDbAction, DuckDbActionType, DuckDbBatchOptions, DuckDbBatchResponse, DuckDbDatabaseHandle, DuckDbExecuteOptions, DuckDbExecuteResponse, DuckDbOptions, DuckDbQueryOptions, DuckDbQueryResponse, DuckDbService, DuckDbServiceConfig, DuckDbStatement, DuckDbValue, EncodedShareData, ExecuteOptions, ExecuteResponse, Extension, FetchFunction, GenerateShareParams, ICapabilityKeyRegistry, IDataVaultService, IDatabaseHandle, IDuckDbDatabaseHandle, IDuckDbService, IENSResolver, IKVService, INotificationHandler, IPrefixedKVService, ISQLService, ISecretsService, ISessionManager, ISessionStorage, ISharingService, ISigner, ISpace, ISpaceCreationHandler, ISpaceScopedDelegations, ISpaceScopedSharing, ISpaceService, IUserAuthorization, IWasmBindings, IdentityParseError, IngestOptions, InvokeFunction, JWK, KVBatchReadResponse, KVCreateSignedReadUrlOptions, KVListPage, KVReadThrough, KVReplicaHandle, KVReplicaSpec, KVReplicaStorage, KVReplicationController, KVReplicationDeps, KVResponse, KVService, KVServiceConfig, KVSignedReadUrlResponse, KeyInfo, KeyProvider, KeyType, LocalGetResult, LocalListResult, LocalReadMeta, LocalReplicaStatus, LocalSyncResult, Manifest, ManifestDefaults, ManifestRegistryRecord, ManifestSecretActions, ManifestValidationError, OpenKeyCallbackStrategy, OpenKeySigningRequestBody, OpenKeySigningResponseBody, OpenKeySigningStrategyOptions, ParsedSecretCatalogKey, PendingWriteRecord, PendingWriteState, PendingWriteStore, PermissionEntry, PermissionNotInManifestError, PersistedSessionData, PinnedKey, PkhDidParts, PrefixedKVService, ProtocolMismatchError, PurgeTarget, QueryOptions, QueryResponse, ReceiveOptions, RegisterBatchSuccess, RegisterPolicyV3Input, RegisterPolicyV3Receipt, ReplicaAuthorityState, ReplicaCoverage, ReplicaDevice, ReplicaGatedHandle, ReplicaGrantInfo, ReplicaInspectedStatus, ReplicaState, ReplicaStatusEntry, ReplicationAuthority, ReplicationControl, ReplicationEvent, ReplicationIdentity, ReplicationOptions, ReplicationPurgeReport, ReplicationReason, ReplicationScheduler, ResolvedCapabilities, ResolvedDelegate, ResolvedReplicationOptions, ResolvedSecretPath, ResourceCapability, SECRET_NAME_RE, SQLAction, SQLActionType, SQLService, SQLServiceConfig, SchemaInfo, SecretCatalogEntry, SecretPayload, SecretScopeOptions, SecretsError, SecretsService, ServiceContext, ServiceContextConfig, ServiceSession, SessionExpiredError, ShareAccess, ShareLink, ShareLinkData, ShareSchema, SharingService, SharingServiceConfig, SignCallback, SignInOptions, SignRequest, SignResponse, SilentNotificationHandler, Space, SpaceAbilitiesMap, SpaceConfig, SpaceCreationContext, SpaceErrorCode, SpaceErrorCodes, SpaceInfo, SpaceOwnership, SpaceService, SpaceServiceConfig, SqlStatement, SqlValue, StoredDelegationChain, TableInfo, TelemetryConfig, TelemetryEventHandler, TinyCloud, TinyCloudConfig, TinyCloudDebugEnableOptions, TinyCloudDebugEvent, TinyCloudDebugLevel, TinyCloudDebugLogger, TinyCloudDebugTimer, TinyCloudSession, UnsupportedFeatureError, VAULT_PERMISSION_SERVICE, VaultCrypto, VaultEntry, VaultError, VaultGetOptions, VaultGrantOptions, VaultHeaders, VaultListOptions, VaultNetworkReadResult, VaultPublicSpaceKVActions, VaultPutOptions, VersionCheckError, ViewInfo, WasmVaultFunctions, addressStorageKey, buildSpaceUri, canonicalizeAddress, canonicalizeDid, canonicalizeDidUrl, canonicalizeNetworkId, canonicalizeSecretScope, checkNodeInfo, clearTinyCloudDebugLogs, composeManifestRequest, createCapabilityKeyRegistry, createOpenKeyCallbackSigningStrategy, createSharingService, createSpaceService, createVaultCrypto, defaultSpaceCreationHandler, didCacheKey, didEquals, disableTinyCloudDebug, enableTinyCloudDebug, expandActionShortNames, expandPermissionEntries, expandPermissionEntry, getTinyCloudDebugLogs, installTinyCloudDebugGlobals, isCapabilitySubset, isEvmAddress, loadManifest, makePkhSpaceId, makePublicSpaceId, parseCanonicalNetworkId, parseExpiry, parsePkhDid, parseSecretCatalogKey, parseSpaceUri, pkhDid, principalDid, principalDidEquals, resolveManifest, resolveSecretListPrefix, resolveSecretPath, resourceCapabilitiesToSpaceAbilitiesMap, tinyCloudDebugLogger, validateManifest } from '@tinycloud/sdk-core';
3
3
  import { _ as __gated_network } from './gated-network-BEF2XSTC.cjs';
4
- import { _ as __authority } from './authority-BO2VqGnD.cjs';
4
+ import { _ as __authority } from './authority-BgZpUFss.cjs';
5
5
  import { _ as __runtime } from './runtime-D1o9Eybt.cjs';
6
6
  import { ReplicaDenyInput } from '@tinycloud/sdk-services/kv/replication';
7
7
  export { F as FileSessionStorage, M as MemorySessionStorage, W as WasmKeyProvider, a as WasmKeyProviderConfig, c as createWasmKeyProvider } from './WasmKeyProvider-5Ee7fcAw.cjs';
8
- export { e as BootstrapWarning, C as CompactRuntimeDelegationInput, f as CreateOwnerDelegationParams, D as DelegateToOptions, g as DelegateToResult, h as DelegatedAccess, E as EnsureEncryptionNetworkOptions, I as InvalidRestoredSessionError, N as NodeEventEmitterStrategy, j as NodeUserAuthorization, l as NodeUserAuthorizationConfig, p as OwnerDelegationReceipt, P as PortableDelegation, u as RuntimePermissionGrantOptions, S as SecretPermissionHint, v as SecretReadInput, w as SecretReadResult, y as SignStrategy, T as TinyCloudNode, z as TinyCloudNodeConfig, U as UnifiedOwnerRootInput, F as UnifiedOwnerRootReceipt, G as UnsupportedSessionRestoreError, V as ValidatedRuntimeDelegation, J as activateCompactRuntimeDelegation, L as defaultSignStrategy, M as deserializeDelegation, W as serializeDelegation } from './TinyCloudNode-DeV-L_14.cjs';
8
+ export { e as BootstrapWarning, C as CompactRuntimeDelegationInput, f as CreateOwnerDelegationParams, D as DelegateToOptions, g as DelegateToResult, h as DelegatedAccess, E as EnsureEncryptionNetworkOptions, I as InvalidRestoredSessionError, N as NodeEventEmitterStrategy, j as NodeUserAuthorization, l as NodeUserAuthorizationConfig, p as OwnerDelegationReceipt, P as PortableDelegation, u as RuntimePermissionGrantOptions, S as SecretPermissionHint, v as SecretReadInput, w as SecretReadResult, y as SignStrategy, T as TinyCloudNode, z as TinyCloudNodeConfig, U as UnifiedOwnerRootInput, F as UnifiedOwnerRootReceipt, G as UnsupportedSessionRestoreError, V as ValidatedRuntimeDelegation, J as activateCompactRuntimeDelegation, L as defaultSignStrategy, M as deserializeDelegation, W as serializeDelegation } from './TinyCloudNode-N4mfZI_k.cjs';
9
9
  import '@tinycloud/sdk-services';
10
10
  import 'events';
11
11
 
package/dist/core.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { ReplicationOptions } from '@tinycloud/sdk-core';
2
2
  export { ACCOUNT_REGISTRY_PATH, ACCOUNT_REGISTRY_SPACE, AccountApplication, AccountApplicationListOptions, AccountApplicationRegisterOptions, AccountDelegation, AccountDelegationListOptions, AccountDelegationRevokeOptions, AccountIndexEnsureResult, AccountIndexRebuildResult, AccountIndexStatus, AccountIndexedReadOptions, AccountService, AccountServiceConfig, AccountSpace, AccountSpaceListOptions, AccountStatus, AuthorityRefusal, AutoApproveSpaceCreationHandler, AutoRejectStrategy, AutoSignStrategy, BatchOptions, BatchResponse, CallbackStrategy, CanonicalAddress, CanonicalParsedNetworkId, CapabilityEntry, CapabilityKeyRegistry, CapabilityKeyRegistryErrorCode, CapabilityKeyRegistryErrorCodes, CaveatedDelegationUnsupportedError, ClientSession, ColumnInfo, ComposeManifestOptions, ComposedManifestRequest, CreateDelegationParams, DEFAULT_MANIFEST_SPACE, DEFAULT_MANIFEST_VERSION, DEFAULT_SIGNED_READ_URL_EXPIRY_MS, DataVaultConfig, DataVaultService, DatabaseHandle, DelegateReceivedShareParams, DelegatedShareAccess, Delegation, DelegationChain, DelegationChainV2, DelegationDirection, DelegationError, DelegationErrorCode, DelegationErrorCodes, DelegationFilters, DelegationManager, DelegationManagerConfig, DelegationRecord, DelegationResult, DidCacheKeyOptions, DidEqualsOptions, DuckDbAction, DuckDbActionType, DuckDbBatchOptions, DuckDbBatchResponse, DuckDbDatabaseHandle, DuckDbExecuteOptions, DuckDbExecuteResponse, DuckDbOptions, DuckDbQueryOptions, DuckDbQueryResponse, DuckDbService, DuckDbServiceConfig, DuckDbStatement, DuckDbValue, EncodedShareData, ExecuteOptions, ExecuteResponse, Extension, FetchFunction, GenerateShareParams, ICapabilityKeyRegistry, IDataVaultService, IDatabaseHandle, IDuckDbDatabaseHandle, IDuckDbService, IENSResolver, IKVService, INotificationHandler, IPrefixedKVService, ISQLService, ISecretsService, ISessionManager, ISessionStorage, ISharingService, ISigner, ISpace, ISpaceCreationHandler, ISpaceScopedDelegations, ISpaceScopedSharing, ISpaceService, IUserAuthorization, IWasmBindings, IdentityParseError, IngestOptions, InvokeFunction, JWK, KVBatchReadResponse, KVCreateSignedReadUrlOptions, KVListPage, KVReadThrough, KVReplicaHandle, KVReplicaSpec, KVReplicaStorage, KVReplicationController, KVReplicationDeps, KVResponse, KVService, KVServiceConfig, KVSignedReadUrlResponse, KeyInfo, KeyProvider, KeyType, LocalGetResult, LocalListResult, LocalReadMeta, LocalReplicaStatus, LocalSyncResult, Manifest, ManifestDefaults, ManifestRegistryRecord, ManifestSecretActions, ManifestValidationError, OpenKeyCallbackStrategy, OpenKeySigningRequestBody, OpenKeySigningResponseBody, OpenKeySigningStrategyOptions, ParsedSecretCatalogKey, PendingWriteRecord, PendingWriteState, PendingWriteStore, PermissionEntry, PermissionNotInManifestError, PersistedSessionData, PinnedKey, PkhDidParts, PrefixedKVService, ProtocolMismatchError, PurgeTarget, QueryOptions, QueryResponse, ReceiveOptions, RegisterBatchSuccess, RegisterPolicyV3Input, RegisterPolicyV3Receipt, ReplicaAuthorityState, ReplicaCoverage, ReplicaDevice, ReplicaGatedHandle, ReplicaGrantInfo, ReplicaInspectedStatus, ReplicaState, ReplicaStatusEntry, ReplicationAuthority, ReplicationControl, ReplicationEvent, ReplicationIdentity, ReplicationOptions, ReplicationPurgeReport, ReplicationReason, ReplicationScheduler, ResolvedCapabilities, ResolvedDelegate, ResolvedReplicationOptions, ResolvedSecretPath, ResourceCapability, SECRET_NAME_RE, SQLAction, SQLActionType, SQLService, SQLServiceConfig, SchemaInfo, SecretCatalogEntry, SecretPayload, SecretScopeOptions, SecretsError, SecretsService, ServiceContext, ServiceContextConfig, ServiceSession, SessionExpiredError, ShareAccess, ShareLink, ShareLinkData, ShareSchema, SharingService, SharingServiceConfig, SignCallback, SignInOptions, SignRequest, SignResponse, SilentNotificationHandler, Space, SpaceAbilitiesMap, SpaceConfig, SpaceCreationContext, SpaceErrorCode, SpaceErrorCodes, SpaceInfo, SpaceOwnership, SpaceService, SpaceServiceConfig, SqlStatement, SqlValue, StoredDelegationChain, TableInfo, TelemetryConfig, TelemetryEventHandler, TinyCloud, TinyCloudConfig, TinyCloudDebugEnableOptions, TinyCloudDebugEvent, TinyCloudDebugLevel, TinyCloudDebugLogger, TinyCloudDebugTimer, TinyCloudSession, UnsupportedFeatureError, VAULT_PERMISSION_SERVICE, VaultCrypto, VaultEntry, VaultError, VaultGetOptions, VaultGrantOptions, VaultHeaders, VaultListOptions, VaultNetworkReadResult, VaultPublicSpaceKVActions, VaultPutOptions, VersionCheckError, ViewInfo, WasmVaultFunctions, addressStorageKey, buildSpaceUri, canonicalizeAddress, canonicalizeDid, canonicalizeDidUrl, canonicalizeNetworkId, canonicalizeSecretScope, checkNodeInfo, clearTinyCloudDebugLogs, composeManifestRequest, createCapabilityKeyRegistry, createOpenKeyCallbackSigningStrategy, createSharingService, createSpaceService, createVaultCrypto, defaultSpaceCreationHandler, didCacheKey, didEquals, disableTinyCloudDebug, enableTinyCloudDebug, expandActionShortNames, expandPermissionEntries, expandPermissionEntry, getTinyCloudDebugLogs, installTinyCloudDebugGlobals, isCapabilitySubset, isEvmAddress, loadManifest, makePkhSpaceId, makePublicSpaceId, parseCanonicalNetworkId, parseExpiry, parsePkhDid, parseSecretCatalogKey, parseSpaceUri, pkhDid, principalDid, principalDidEquals, resolveManifest, resolveSecretListPrefix, resolveSecretPath, resourceCapabilitiesToSpaceAbilitiesMap, tinyCloudDebugLogger, validateManifest } from '@tinycloud/sdk-core';
3
3
  import { _ as __gated_network } from './gated-network-BEF2XSTC.js';
4
- import { _ as __authority } from './authority-CtsxSAoP.js';
4
+ import { _ as __authority } from './authority-C670-9su.js';
5
5
  import { _ as __runtime } from './runtime-v62FzQHz.js';
6
6
  import { ReplicaDenyInput } from '@tinycloud/sdk-services/kv/replication';
7
7
  export { F as FileSessionStorage, M as MemorySessionStorage, W as WasmKeyProvider, a as WasmKeyProviderConfig, c as createWasmKeyProvider } from './WasmKeyProvider-5Ee7fcAw.js';
8
- export { e as BootstrapWarning, C as CompactRuntimeDelegationInput, f as CreateOwnerDelegationParams, D as DelegateToOptions, g as DelegateToResult, h as DelegatedAccess, E as EnsureEncryptionNetworkOptions, I as InvalidRestoredSessionError, N as NodeEventEmitterStrategy, j as NodeUserAuthorization, l as NodeUserAuthorizationConfig, p as OwnerDelegationReceipt, P as PortableDelegation, u as RuntimePermissionGrantOptions, S as SecretPermissionHint, v as SecretReadInput, w as SecretReadResult, y as SignStrategy, T as TinyCloudNode, z as TinyCloudNodeConfig, U as UnifiedOwnerRootInput, F as UnifiedOwnerRootReceipt, G as UnsupportedSessionRestoreError, V as ValidatedRuntimeDelegation, J as activateCompactRuntimeDelegation, L as defaultSignStrategy, M as deserializeDelegation, W as serializeDelegation } from './TinyCloudNode-DeV-L_14.js';
8
+ export { e as BootstrapWarning, C as CompactRuntimeDelegationInput, f as CreateOwnerDelegationParams, D as DelegateToOptions, g as DelegateToResult, h as DelegatedAccess, E as EnsureEncryptionNetworkOptions, I as InvalidRestoredSessionError, N as NodeEventEmitterStrategy, j as NodeUserAuthorization, l as NodeUserAuthorizationConfig, p as OwnerDelegationReceipt, P as PortableDelegation, u as RuntimePermissionGrantOptions, S as SecretPermissionHint, v as SecretReadInput, w as SecretReadResult, y as SignStrategy, T as TinyCloudNode, z as TinyCloudNodeConfig, U as UnifiedOwnerRootInput, F as UnifiedOwnerRootReceipt, G as UnsupportedSessionRestoreError, V as ValidatedRuntimeDelegation, J as activateCompactRuntimeDelegation, L as defaultSignStrategy, M as deserializeDelegation, W as serializeDelegation } from './TinyCloudNode-N4mfZI_k.js';
9
9
  import '@tinycloud/sdk-services';
10
10
  import 'events';
11
11
 
package/dist/core.js CHANGED
@@ -2053,6 +2053,173 @@ var NodeUserAuthorization = class {
2053
2053
  }
2054
2054
  };
2055
2055
 
2056
+ // src/recordingServiceContext.ts
2057
+ import {
2058
+ ServiceContext
2059
+ } from "@tinycloud/sdk-services";
2060
+ import {
2061
+ buildRequestEvent,
2062
+ invocationMetaOf,
2063
+ requestBytesOf
2064
+ } from "@tinycloud/sdk-services/telemetry/requestLog";
2065
+
2066
+ // src/recordingRegistry.ts
2067
+ var unrecordedFetches = /* @__PURE__ */ new WeakMap();
2068
+ function registerRecording(context, unrecordedFetch) {
2069
+ unrecordedFetches.set(context, unrecordedFetch);
2070
+ }
2071
+ function unrecordedFetchOf(context) {
2072
+ const unrecordedFetch = unrecordedFetches.get(context);
2073
+ return unrecordedFetch ? unrecordedFetch() : context.fetch;
2074
+ }
2075
+
2076
+ // src/recordingServiceContext.ts
2077
+ var SYNC_ABILITY = "tinycloud.kv/sync";
2078
+ var INFO_PATH = "/info";
2079
+ function outcomeCodeOf(response) {
2080
+ return response === void 0 ? "ERROR" : response.ok ? "ok" : `HTTP_${response.status}`;
2081
+ }
2082
+ function replicationOp(url, meta) {
2083
+ if (meta !== void 0) return meta.action === SYNC_ABILITY ? `${meta.service}/sync` : void 0;
2084
+ return isInfoUrl(url) ? "sync/info" : void 0;
2085
+ }
2086
+ function isInfoUrl(url) {
2087
+ try {
2088
+ return new URL(url).pathname.replace(/\/+$/, "") === INFO_PATH;
2089
+ } catch {
2090
+ return false;
2091
+ }
2092
+ }
2093
+ function replicationEvent(sample, op) {
2094
+ return buildRequestEvent({
2095
+ service: "sync",
2096
+ op,
2097
+ url: sample.url,
2098
+ bytes: requestBytesOf(sample.init?.body, sample.response?.headers.get("content-length")),
2099
+ durationMs: performance.now() - sample.clock,
2100
+ attempts: sample.attempts ?? 1,
2101
+ ok: sample.response?.ok === true,
2102
+ code: outcomeCodeOf(sample.response),
2103
+ at: sample.at
2104
+ });
2105
+ }
2106
+ function createServiceContext(config) {
2107
+ const { requestSink, ...base } = config;
2108
+ return requestSink === void 0 ? new ServiceContext(base) : new RecordingServiceContext(base, requestSink);
2109
+ }
2110
+ var RecordingServiceContext = class extends ServiceContext {
2111
+ constructor(config, sink) {
2112
+ const pending = {};
2113
+ super({
2114
+ ...config,
2115
+ invoke: rememberInvoke(config.invoke, sink, pending),
2116
+ invokeAny: config.invokeAny ? rememberInvokeAny(config.invokeAny, sink, pending) : void 0
2117
+ });
2118
+ this.requestSink = sink;
2119
+ this.pending = pending;
2120
+ registerRecording(this, () => this.unrecordedFetch);
2121
+ }
2122
+ /** Per-call recording; `_fetch` is read at access time, so overrides apply. */
2123
+ get fetch() {
2124
+ const raw = super.fetch;
2125
+ return (url, init) => this.recordCall(raw, url, init);
2126
+ }
2127
+ /** Transport without per-call recording. */
2128
+ get unrecordedFetch() {
2129
+ return super.fetch;
2130
+ }
2131
+ /**
2132
+ * One event per logical request. The first resolved attempt's init is the logged request and
2133
+ * `attempts` counts resolved builds. A retired context throws before the first build and records
2134
+ * nothing, as master does.
2135
+ */
2136
+ async invokeWithRetry(url, build) {
2137
+ const at = Date.now();
2138
+ const clock = performance.now();
2139
+ let reached = false;
2140
+ let attempts = 0;
2141
+ let first;
2142
+ let firstMeta;
2143
+ let response;
2144
+ const attempt = async () => {
2145
+ reached = true;
2146
+ this.pending.meta = void 0;
2147
+ const built = build();
2148
+ const meta = this.pending.meta;
2149
+ const init = await built;
2150
+ attempts += 1;
2151
+ if (first === void 0) {
2152
+ first = init;
2153
+ firstMeta = meta;
2154
+ }
2155
+ return init;
2156
+ };
2157
+ try {
2158
+ response = await super.invokeWithRetry(url, attempt);
2159
+ return response;
2160
+ } finally {
2161
+ if (reached) {
2162
+ this.observeAttempt({ url, init: first, response, meta: firstMeta, at, clock, attempts });
2163
+ }
2164
+ }
2165
+ }
2166
+ async recordCall(fetchFn, url, init) {
2167
+ const at = Date.now();
2168
+ const clock = performance.now();
2169
+ let response;
2170
+ try {
2171
+ response = await fetchFn(url, init);
2172
+ return response;
2173
+ } finally {
2174
+ this.observeAttempt({ url, init, response, at, clock });
2175
+ }
2176
+ }
2177
+ observeAttempt(sample) {
2178
+ try {
2179
+ const replication = replicationOp(sample.url, sample.meta ?? invocationMetaOf(sample.init?.headers));
2180
+ if (replication !== void 0) {
2181
+ this.requestSink.record(replicationEvent(sample, replication));
2182
+ return;
2183
+ }
2184
+ const headers = sample.init?.headers;
2185
+ if (sample.meta !== void 0 && typeof headers === "object" && headers !== null) {
2186
+ this.requestSink.remember(headers, sample.meta);
2187
+ }
2188
+ this.requestSink.observe({
2189
+ url: sample.url,
2190
+ requestHeaders: headers,
2191
+ requestBody: sample.init?.body,
2192
+ responseContentLength: sample.response?.headers.get("content-length"),
2193
+ ok: sample.response?.ok === true,
2194
+ code: outcomeCodeOf(sample.response),
2195
+ durationMs: performance.now() - sample.clock,
2196
+ attempts: sample.attempts ?? 1,
2197
+ at: sample.at
2198
+ });
2199
+ } catch {
2200
+ }
2201
+ }
2202
+ };
2203
+ function rememberInvoke(invoke, sink, pending) {
2204
+ return (session, service, path, action, facts) => {
2205
+ const headers = invoke(session, service, path, action, facts);
2206
+ const meta = { service, path, action, spaceId: session.spaceId };
2207
+ pending.meta = meta;
2208
+ sink.remember(headers, meta);
2209
+ return headers;
2210
+ };
2211
+ }
2212
+ function rememberInvokeAny(invokeAny, sink, pending) {
2213
+ return (session, entries, facts) => {
2214
+ const headers = invokeAny(session, entries, facts);
2215
+ const first = entries[0];
2216
+ const meta = first === void 0 ? void 0 : { service: first.service, path: first.path, action: first.action, spaceId: first.spaceId ?? session.spaceId };
2217
+ pending.meta = meta;
2218
+ if (meta !== void 0) sink.remember(headers, meta);
2219
+ return headers;
2220
+ };
2221
+ }
2222
+
2056
2223
  // src/delegation.ts
2057
2224
  import {
2058
2225
  canonicalizeRecapCaveats,
@@ -2553,7 +2720,6 @@ import {
2553
2720
  DecryptTransportResponseError,
2554
2721
  SecretsService,
2555
2722
  createVaultCrypto,
2556
- ServiceContext as ServiceContext2,
2557
2723
  SilentNotificationHandler,
2558
2724
  DelegationManager,
2559
2725
  SpaceService,
@@ -2584,7 +2750,7 @@ import {
2584
2750
  KV as KV3,
2585
2751
  SQL as SQL2,
2586
2752
  DUCKDB as DUCKDB2,
2587
- ENCRYPTION as ENCRYPTION2,
2753
+ ENCRYPTION as ENCRYPTION3,
2588
2754
  EXPIRY as EXPIRY3,
2589
2755
  canonicalHashHex,
2590
2756
  canonicalizeEncryptionJson,
@@ -2596,7 +2762,7 @@ import {
2596
2762
  createInMemoryRegistrySequenceStore as createInMemoryRegistrySequenceStore2,
2597
2763
  publishLocationRecord,
2598
2764
  principalDidEquals as principalDidEquals3,
2599
- parseNetworkId as parseNetworkId2,
2765
+ parseNetworkId as parseNetworkId3,
2600
2766
  resolveSecretPath as resolveSecretPath2,
2601
2767
  registerPolicyV3,
2602
2768
  CREDENTIAL_INVITATION_REQUEST_DOMAIN,
@@ -2617,6 +2783,7 @@ import {
2617
2783
  parsePermissionHint,
2618
2784
  tinyCloudDebugLogger
2619
2785
  } from "@tinycloud/sdk-services";
2786
+ import { RequestLog, observeReplicaReads, readOnlyRequestLog } from "@tinycloud/sdk-services/telemetry/requestLog";
2620
2787
 
2621
2788
  // src/account/AccountService.ts
2622
2789
  import { AccountService } from "@tinycloud/sdk-core";
@@ -2626,8 +2793,7 @@ import {
2626
2793
  KVService,
2627
2794
  HooksService,
2628
2795
  SQLService,
2629
- DuckDbService,
2630
- ServiceContext
2796
+ DuckDbService
2631
2797
  } from "@tinycloud/sdk-core";
2632
2798
  var DelegatedAccess = class {
2633
2799
  /**
@@ -2640,12 +2806,13 @@ var DelegatedAccess = class {
2640
2806
  this.session = session;
2641
2807
  this._delegation = delegation;
2642
2808
  this.host = host;
2643
- const context = new ServiceContext({
2809
+ const context = createServiceContext({
2644
2810
  invoke,
2645
2811
  invokeAny,
2646
2812
  fetch: lifetime?.fetch ?? globalThis.fetch.bind(globalThis),
2647
2813
  hosts: [host],
2648
- telemetry
2814
+ telemetry,
2815
+ requestSink: lifetime?.requestSink
2649
2816
  });
2650
2817
  this._serviceContext = lifetime ? lifetime.track(context) : context;
2651
2818
  const prefix = this._delegation.path.replace(/\/$/, "");
@@ -2809,7 +2976,11 @@ function createWasmKeyProvider(sessionManager) {
2809
2976
 
2810
2977
  // src/delegateToHelpers.ts
2811
2978
  import {
2979
+ actionContains,
2980
+ ENCRYPTION as ENCRYPTION2,
2812
2981
  parseExpiry,
2982
+ isNetworkId,
2983
+ parseNetworkId as parseNetworkId2,
2813
2984
  SiweMessage as SiweMessage2,
2814
2985
  EXPIRY as EXPIRY2
2815
2986
  } from "@tinycloud/sdk-core";
@@ -2844,6 +3015,16 @@ function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
2844
3015
  return entries;
2845
3016
  }
2846
3017
  var DEFAULT_DELEGATION_EXPIRY_MS = EXPIRY2.SESSION_MS;
3018
+ var SHARE_NETWORK_NAME_RE = /^share-[a-z0-9][a-z0-9-]{15,35}$/;
3019
+ function grantsCappedDecrypt(path, actions) {
3020
+ if (!actions.some((action) => actionContains(action, ENCRYPTION2.DECRYPT))) {
3021
+ return false;
3022
+ }
3023
+ return !(isNetworkId(path) && SHARE_NETWORK_NAME_RE.test(parseNetworkId2(path).name));
3024
+ }
3025
+ function includesDecrypt(entries) {
3026
+ return entries.some((entry) => grantsCappedDecrypt(entry.path, entry.actions));
3027
+ }
2847
3028
  function resolveExpiryMs(expiry) {
2848
3029
  if (expiry === void 0) {
2849
3030
  return DEFAULT_DELEGATION_EXPIRY_MS;
@@ -3017,6 +3198,15 @@ var NodeSecretsService = class {
3017
3198
  if (this.hasPermission(permissionEntries)) {
3018
3199
  return ok();
3019
3200
  }
3201
+ let escalation;
3202
+ try {
3203
+ escalation = this.config.uncoveredEntries?.(permissionEntries) ?? permissionEntries;
3204
+ } catch (error) {
3205
+ return this.escalationError(action, target, error);
3206
+ }
3207
+ if (this.config.uncoveredEntries !== void 0 && escalation.length === 0) {
3208
+ return ok();
3209
+ }
3020
3210
  if (!this.config.canEscalate()) {
3021
3211
  return secretsError(
3022
3212
  ErrorCodes.PERMISSION_DENIED,
@@ -3024,16 +3214,20 @@ var NodeSecretsService = class {
3024
3214
  );
3025
3215
  }
3026
3216
  try {
3027
- await this.config.grantPermissions(permissionEntries);
3217
+ const grant = action === "get" && this.config.grantGetPermissions !== void 0 ? this.config.grantGetPermissions : this.config.grantPermissions;
3218
+ await grant(escalation);
3028
3219
  return this.restoreUnlockAfterEscalation();
3029
3220
  } catch (error) {
3030
- return secretsError(
3031
- ErrorCodes.PERMISSION_DENIED,
3032
- error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${target} failed.`,
3033
- error instanceof Error ? error : void 0
3034
- );
3221
+ return this.escalationError(action, target, error);
3035
3222
  }
3036
3223
  }
3224
+ escalationError(action, target, error) {
3225
+ return secretsError(
3226
+ ErrorCodes.PERMISSION_DENIED,
3227
+ error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${target} failed.`,
3228
+ error instanceof Error ? error : void 0
3229
+ );
3230
+ }
3037
3231
  async restoreUnlockAfterEscalation() {
3038
3232
  if (!this.shouldRestoreUnlock) {
3039
3233
  return ok();
@@ -3068,8 +3262,8 @@ var NodeSecretsService = class {
3068
3262
  // src/TinyCloudNode.ts
3069
3263
  var DEFAULT_HOST = "https://node.tinycloud.xyz";
3070
3264
  var DEFAULT_ENCRYPTION_NETWORK_NAME = "default";
3071
- var NETWORK_CREATE_ACTION2 = ENCRYPTION2.NETWORK_CREATE;
3072
- var DECRYPT_ACTION2 = ENCRYPTION2.DECRYPT;
3265
+ var NETWORK_CREATE_ACTION2 = ENCRYPTION3.NETWORK_CREATE;
3266
+ var DECRYPT_ACTION2 = ENCRYPTION3.DECRYPT;
3073
3267
  var BOOTSTRAP_COMPLETION_MARKER_KEY = "system/bootstrap/complete";
3074
3268
  var BOOTSTRAP_COMPLETION_MARKER_VERSION = 1;
3075
3269
  var ACCEPTED_MARKER_VERSIONS = [BOOTSTRAP_COMPLETION_MARKER_VERSION];
@@ -3245,11 +3439,12 @@ function createDefaultSessionKey(wasm) {
3245
3439
  return { manager, keyId, jwk: JSON.parse(jwkStr) };
3246
3440
  }
3247
3441
  var ServiceGraphLifetime = class {
3248
- constructor(invokeFn, invokeAnyFn, fetchFn, observeContext) {
3442
+ constructor(invokeFn, invokeAnyFn, fetchFn, observeContext, requestSink) {
3249
3443
  this.invokeFn = invokeFn;
3250
3444
  this.invokeAnyFn = invokeAnyFn;
3251
3445
  this.fetchFn = fetchFn;
3252
3446
  this.observeContext = observeContext;
3447
+ this.requestSink = requestSink;
3253
3448
  this.abortController = new AbortController();
3254
3449
  this.contexts = /* @__PURE__ */ new Set();
3255
3450
  this.retired = false;
@@ -3415,7 +3610,7 @@ function ownerDelegationPermissions(params) {
3415
3610
  }
3416
3611
  if (permission.service === ENCRYPTION_PERMISSION_SERVICE2) {
3417
3612
  try {
3418
- parseNetworkId2(permission.path);
3613
+ parseNetworkId3(permission.path);
3419
3614
  } catch {
3420
3615
  throw new Error("Owner delegation encryption permission requires a canonical network URN");
3421
3616
  }
@@ -3438,6 +3633,8 @@ function ownerPermissionsToAbilities(permissions) {
3438
3633
  return { abilities, rawAbilities };
3439
3634
  }
3440
3635
  var TERMINAL_DELEGATION_REQUIRES_SESSION_KEY = "disableSubDelegation requires a session-key delegation to a did:key (not did:pkh); use the session-key DID or drop the flag";
3636
+ var DECRYPT_GRANT_MAX_EXPIRY_MS = 60 * 60 * 1e3;
3637
+ var SECRET_GET_GRANT_EXPIRY_MS = 59 * 60 * 1e3;
3441
3638
  function base64UrlEncode(bytes) {
3442
3639
  const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
3443
3640
  let output = "";
@@ -3820,6 +4017,7 @@ var _TinyCloudNode = class _TinyCloudNode {
3820
4017
  this.sessionManager = sessionKey.manager;
3821
4018
  this.sessionKeyId = sessionKey.keyId;
3822
4019
  this.sessionKeyJwk = sessionKey.jwk;
4020
+ this._requestLog = config.requestLog === true ? new RequestLog() : void 0;
3823
4021
  this._serviceGraph = this.createServiceGraphLifetime();
3824
4022
  this._capabilityRegistry = new CapabilityKeyRegistry();
3825
4023
  this._keyProvider = new WasmKeyProvider({
@@ -3991,7 +4189,8 @@ var _TinyCloudNode = class _TinyCloudNode {
3991
4189
  createKVService: (config) => {
3992
4190
  const prefix = config.pathPrefix?.replace(/\/$/, "");
3993
4191
  const kvService = new KVService2({ prefix });
3994
- const kvContext = receiveOnlyGraph.track(new ServiceContext2({
4192
+ const kvContext = receiveOnlyGraph.track(createServiceContext({
4193
+ requestSink: receiveOnlyGraph.requestSink,
3995
4194
  invoke: config.invoke,
3996
4195
  fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
3997
4196
  hosts: config.hosts,
@@ -4054,6 +4253,10 @@ var _TinyCloudNode = class _TinyCloudNode {
4054
4253
  shouldUseBootstrapSignInRequest(config) {
4055
4254
  return config.autoBootstrapAccount !== false && config.manifest === void 0 && config.capabilityRequest === void 0 && (config.prefix ?? "default") === "default" && isOpenKeyAutoSignStrategy(config.signStrategy);
4056
4255
  }
4256
+ /** Sanitized developer request events; undefined unless the node was built with `requestLog: true`. */
4257
+ get requests() {
4258
+ return this._requestLog === void 0 ? void 0 : readOnlyRequestLog(this._requestLog);
4259
+ }
4057
4260
  createServiceGraphLifetime() {
4058
4261
  return new ServiceGraphLifetime(
4059
4262
  this.invokeWithRuntimePermissions,
@@ -4064,7 +4267,9 @@ var _TinyCloudNode = class _TinyCloudNode {
4064
4267
  (url, init) => globalThis.fetch(url, init),
4065
4268
  (context) => {
4066
4269
  this.storageFull.observe(context);
4067
- }
4270
+ if (this._requestLog) observeReplicaReads(context, this._requestLog);
4271
+ },
4272
+ this._requestLog
4068
4273
  );
4069
4274
  }
4070
4275
  syncResolvedHostFromAuth() {
@@ -4387,6 +4592,7 @@ var _TinyCloudNode = class _TinyCloudNode {
4387
4592
  this.hostedOwnedSpaceIds.clear();
4388
4593
  this.cancelOwnedSpaceHosts();
4389
4594
  this.storageFull.clear();
4595
+ this._requestLog?.clear();
4390
4596
  this._bootstrapSkipped = false;
4391
4597
  this._bootstrapStatus = { skipped: false };
4392
4598
  this.replicationDelegateSession = void 0;
@@ -4478,7 +4684,10 @@ var _TinyCloudNode = class _TinyCloudNode {
4478
4684
  const denial = await this.denyReplicaGate({ reason: "account_switch", principal: priorPrincipal, next: nextPrincipal });
4479
4685
  this.replicaRestoreGate = denial?.status === "unguarded" ? "gate_unavailable" : "stamp_stale";
4480
4686
  }
4481
- if (address !== this._address || chainId !== this._chainId) this.storageFull.clear();
4687
+ if (address !== this._address || chainId !== this._chainId) {
4688
+ this.storageFull.clear();
4689
+ this._requestLog?.clear();
4690
+ }
4482
4691
  this._address = address;
4483
4692
  this._chainId = chainId;
4484
4693
  this._kv = void 0;
@@ -5057,10 +5266,11 @@ var _TinyCloudNode = class _TinyCloudNode {
5057
5266
  const contexts = [context];
5058
5267
  const accountSpaceId = this.ownedSpaceId(ACCOUNT_REGISTRY_SPACE2);
5059
5268
  const createScopedContext = (spaceId) => {
5060
- const scoped = this._serviceGraph.track(new ServiceContext2({
5269
+ const scoped = this._serviceGraph.track(createServiceContext({
5270
+ requestSink: this._serviceGraph.requestSink,
5061
5271
  invoke: context.invoke,
5062
5272
  invokeAny: context.invokeAny,
5063
- fetch: context.fetch,
5273
+ fetch: unrecordedFetchOf(context),
5064
5274
  hosts: context.hosts,
5065
5275
  telemetry: this.config.telemetry,
5066
5276
  retryPolicy: this.config.retryPolicy
@@ -5124,10 +5334,11 @@ var _TinyCloudNode = class _TinyCloudNode {
5124
5334
  const promise = this.enqueueAccountRegistryOperation(session, async () => {
5125
5335
  const sharedContext = this._serviceContext;
5126
5336
  if (!sharedContext) return;
5127
- const context = this._serviceGraph.track(new ServiceContext2({
5337
+ const context = this._serviceGraph.track(createServiceContext({
5338
+ requestSink: this._serviceGraph.requestSink,
5128
5339
  invoke: sharedContext.invoke,
5129
5340
  invokeAny: sharedContext.invokeAny,
5130
- fetch: sharedContext.fetch,
5341
+ fetch: unrecordedFetchOf(sharedContext),
5131
5342
  hosts: sharedContext.hosts,
5132
5343
  telemetry: this.config.telemetry,
5133
5344
  retryPolicy: this.config.retryPolicy
@@ -5332,7 +5543,7 @@ var _TinyCloudNode = class _TinyCloudNode {
5332
5543
  return;
5333
5544
  }
5334
5545
  for (const networkId of this.requestedEncryptionNetworkIds()) {
5335
- const parsed = parseNetworkId2(networkId);
5546
+ const parsed = parseNetworkId3(networkId);
5336
5547
  if (!didPrincipalMatches2(parsed.ownerDid, this.did)) {
5337
5548
  continue;
5338
5549
  }
@@ -5861,6 +6072,7 @@ var _TinyCloudNode = class _TinyCloudNode {
5861
6072
  if (resolvedHost) this.config.host = resolvedHost;
5862
6073
  if (spaceOwnerKey(serviceSession.spaceId) !== this.currentStorageOwner()) {
5863
6074
  this.storageFull.clear();
6075
+ this._requestLog?.clear();
5864
6076
  }
5865
6077
  this._address = stagedAddress;
5866
6078
  this._chainId = stagedChainId;
@@ -5980,7 +6192,8 @@ var _TinyCloudNode = class _TinyCloudNode {
5980
6192
  const coreContext = graph.track(core.serviceContext);
5981
6193
  coreContext.setSession(input.serviceSession);
5982
6194
  }
5983
- const serviceContext = graph.track(new ServiceContext2({
6195
+ const serviceContext = graph.track(createServiceContext({
6196
+ requestSink: graph.requestSink,
5984
6197
  invoke: graph.invoke,
5985
6198
  invokeAny: graph.invokeAny,
5986
6199
  fetch: graph.fetch,
@@ -6068,7 +6281,8 @@ var _TinyCloudNode = class _TinyCloudNode {
6068
6281
  },
6069
6282
  createKVService: (config) => {
6070
6283
  const service = new KVService2({ prefix: config.pathPrefix?.replace(/\/$/, "") });
6071
- const context = graph.track(new ServiceContext2({
6284
+ const context = graph.track(createServiceContext({
6285
+ requestSink: graph.requestSink,
6072
6286
  invoke: config.invoke,
6073
6287
  fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
6074
6288
  hosts: config.hosts,
@@ -6108,7 +6322,8 @@ var _TinyCloudNode = class _TinyCloudNode {
6108
6322
  createKVService: (spaceId) => {
6109
6323
  graph.assertActive();
6110
6324
  const scopedKv = new KVService2({});
6111
- const context = graph.track(new ServiceContext2({
6325
+ const context = graph.track(createServiceContext({
6326
+ requestSink: graph.requestSink,
6112
6327
  invoke: graph.invoke,
6113
6328
  invokeAny: graph.invokeAny,
6114
6329
  fetch: graph.fetch,
@@ -6124,7 +6339,8 @@ var _TinyCloudNode = class _TinyCloudNode {
6124
6339
  createVaultService: (spaceId) => {
6125
6340
  graph.assertActive();
6126
6341
  const scopedKv = new KVService2({});
6127
- const context = graph.track(new ServiceContext2({
6342
+ const context = graph.track(createServiceContext({
6343
+ requestSink: graph.requestSink,
6128
6344
  invoke: graph.invoke,
6129
6345
  invokeAny: graph.invokeAny,
6130
6346
  fetch: graph.fetch,
@@ -6523,7 +6739,8 @@ var _TinyCloudNode = class _TinyCloudNode {
6523
6739
  this._serviceGraph.fetch
6524
6740
  );
6525
6741
  this._serviceGraph.track(this.tc.serviceContext);
6526
- this._serviceContext = this._serviceGraph.track(new ServiceContext2({
6742
+ this._serviceContext = this._serviceGraph.track(createServiceContext({
6743
+ requestSink: this._serviceGraph.requestSink,
6527
6744
  invoke: this._serviceGraph.invoke,
6528
6745
  invokeAny: this._serviceGraph.invokeAny,
6529
6746
  fetch: this._serviceGraph.fetch,
@@ -6571,10 +6788,11 @@ var _TinyCloudNode = class _TinyCloudNode {
6571
6788
  createSpaceScopedKVService(spaceId) {
6572
6789
  const kvService = new KVService2({});
6573
6790
  if (this._serviceContext) {
6574
- const spaceScopedContext = this._serviceGraph.track(new ServiceContext2({
6791
+ const spaceScopedContext = this._serviceGraph.track(createServiceContext({
6792
+ requestSink: this._serviceGraph.requestSink,
6575
6793
  invoke: this._serviceContext.invoke,
6576
6794
  invokeAny: this._serviceContext.invokeAny,
6577
- fetch: this._serviceContext.fetch,
6795
+ fetch: unrecordedFetchOf(this._serviceContext),
6578
6796
  hosts: this._serviceContext.hosts,
6579
6797
  telemetry: this.config.telemetry,
6580
6798
  retryPolicy: this.config.retryPolicy
@@ -7040,7 +7258,8 @@ var _TinyCloudNode = class _TinyCloudNode {
7040
7258
  createKVService: (config) => {
7041
7259
  graph.assertActive();
7042
7260
  const service = new KVService2({ prefix: config.pathPrefix?.replace(/\/$/, "") });
7043
- const context = graph.track(new ServiceContext2({
7261
+ const context = graph.track(createServiceContext({
7262
+ requestSink: graph.requestSink,
7044
7263
  invoke: config.invoke,
7045
7264
  fetch: config.fetch ?? graph.fetch,
7046
7265
  hosts: config.hosts,
@@ -7143,7 +7362,7 @@ var _TinyCloudNode = class _TinyCloudNode {
7143
7362
  if (!session) throw new Error("Owner session is required");
7144
7363
  const ownerDid = pkhDid2(session.address, session.chainId);
7145
7364
  for (const permission of permissions) {
7146
- if (permission.service === ENCRYPTION_PERMISSION_SERVICE2 && !principalDidEquals3(parseNetworkId2(permission.path).ownerDid, ownerDid)) {
7365
+ if (permission.service === ENCRYPTION_PERMISSION_SERVICE2 && !principalDidEquals3(parseNetworkId3(permission.path).ownerDid, ownerDid)) {
7147
7366
  throw new Error("Owner delegation cannot grant a foreign encryption network");
7148
7367
  }
7149
7368
  }
@@ -7361,10 +7580,11 @@ var _TinyCloudNode = class _TinyCloudNode {
7361
7580
  throw new Error("Not signed in. Call signIn() first.");
7362
7581
  }
7363
7582
  const sql = new SQLService2({});
7364
- const spaceScopedContext = this._serviceGraph.track(new ServiceContext2({
7583
+ const spaceScopedContext = this._serviceGraph.track(createServiceContext({
7584
+ requestSink: this._serviceGraph.requestSink,
7365
7585
  invoke: this._serviceContext.invoke,
7366
7586
  invokeAny: this._serviceContext.invokeAny,
7367
- fetch: this._serviceContext.fetch,
7587
+ fetch: unrecordedFetchOf(this._serviceContext),
7368
7588
  hosts: this._serviceContext.hosts,
7369
7589
  telemetry: this.config.telemetry,
7370
7590
  retryPolicy: this.config.retryPolicy
@@ -7392,10 +7612,11 @@ var _TinyCloudNode = class _TinyCloudNode {
7392
7612
  throw new Error("Not signed in. Call signIn() first.");
7393
7613
  }
7394
7614
  const kv = new KVService2({});
7395
- const spaceScopedContext = this._serviceGraph.track(new ServiceContext2({
7615
+ const spaceScopedContext = this._serviceGraph.track(createServiceContext({
7616
+ requestSink: this._serviceGraph.requestSink,
7396
7617
  invoke: this._serviceContext.invoke,
7397
7618
  invokeAny: this._serviceContext.invokeAny,
7398
- fetch: this._serviceContext.fetch,
7619
+ fetch: unrecordedFetchOf(this._serviceContext),
7399
7620
  hosts: this._serviceContext.hosts
7400
7621
  }));
7401
7622
  spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
@@ -7503,7 +7724,7 @@ var _TinyCloudNode = class _TinyCloudNode {
7503
7724
  return existing;
7504
7725
  }
7505
7726
  }
7506
- const parsed = parseNetworkId2(networkId);
7727
+ const parsed = parseNetworkId3(networkId);
7507
7728
  if (!didPrincipalMatches2(parsed.ownerDid, this.did)) {
7508
7729
  throw new Error(
7509
7730
  `Cannot create encryption network ${networkId}: owner ${parsed.ownerDid} does not match signed-in DID ${this.did}`
@@ -7536,6 +7757,8 @@ var _TinyCloudNode = class _TinyCloudNode {
7536
7757
  getManifest: () => this.manifest,
7537
7758
  hasPermissions: (permissions) => this.hasRuntimePermissions(permissions),
7538
7759
  grantPermissions: (additional) => this.grantRuntimePermissions(additional),
7760
+ grantGetPermissions: (additional) => this.grantRuntimePermissions(additional, { expiry: SECRET_GET_GRANT_EXPIRY_MS }),
7761
+ uncoveredEntries: (permissions) => permissions.filter((entry) => !this.hasRuntimePermissions([entry])),
7539
7762
  canEscalate: () => this.signer !== void 0 && this.tc !== void 0,
7540
7763
  getEncryptionNetworkId: () => this.getEncryptionNetworkIdForSpace(resolvedSpace),
7541
7764
  resolveSpace: (space) => space.startsWith("tinycloud:") ? space : this.ownedSpaceId(space),
@@ -7883,6 +8106,13 @@ var _TinyCloudNode = class _TinyCloudNode {
7883
8106
  }
7884
8107
  }
7885
8108
  const expanded = this.expandPermissionEntries(permissions);
8109
+ const requestsDecrypt = includesDecrypt(expanded);
8110
+ const requestedExpiryMs = requestsDecrypt && options?.expiry === void 0 ? DECRYPT_GRANT_MAX_EXPIRY_MS : resolveExpiryMs(options?.expiry);
8111
+ if (requestsDecrypt && requestedExpiryMs > DECRYPT_GRANT_MAX_EXPIRY_MS) {
8112
+ throw Object.assign(new Error("decrypt grants last at most one hour"), {
8113
+ code: "DECRYPT_EXPIRY_TOO_LONG"
8114
+ });
8115
+ }
7886
8116
  if (this.sessionCoversPermissionEntries(session, expanded)) {
7887
8117
  return [];
7888
8118
  }
@@ -7913,7 +8143,6 @@ var _TinyCloudNode = class _TinyCloudNode {
7913
8143
  bySpace.set(session.spaceId, []);
7914
8144
  }
7915
8145
  const now = /* @__PURE__ */ new Date();
7916
- const requestedExpiryMs = resolveExpiryMs(options?.expiry);
7917
8146
  let expiresAt = new Date(now.getTime() + requestedExpiryMs);
7918
8147
  if (sessionExpiry !== void 0 && sessionExpiry < expiresAt) {
7919
8148
  expiresAt = sessionExpiry;
@@ -8181,7 +8410,8 @@ var _TinyCloudNode = class _TinyCloudNode {
8181
8410
  }
8182
8411
  if (this._serviceContext) {
8183
8412
  const publicKV = new KVService2({ prefix: "" });
8184
- const publicContext = this._serviceGraph.track(new ServiceContext2({
8413
+ const publicContext = this._serviceGraph.track(createServiceContext({
8414
+ requestSink: this._serviceGraph.requestSink,
8185
8415
  invoke: this._serviceGraph.invoke,
8186
8416
  fetch: this._serviceGraph.fetch,
8187
8417
  hosts: this._serviceContext.hosts,
@@ -9764,7 +9994,7 @@ import {
9764
9994
  UnsupportedFeatureError as UnsupportedFeatureError2,
9765
9995
  checkNodeInfo as checkNodeInfo3
9766
9996
  } from "@tinycloud/sdk-core";
9767
- import { ServiceContext as ServiceContext3 } from "@tinycloud/sdk-core";
9997
+ import { ServiceContext as ServiceContext4 } from "@tinycloud/sdk-core";
9768
9998
  export {
9769
9999
  ACCOUNT_REGISTRY_PATH,
9770
10000
  ACCOUNT_REGISTRY_SPACE3 as ACCOUNT_REGISTRY_SPACE,
@@ -9798,7 +10028,7 @@ export {
9798
10028
  SQLAction,
9799
10029
  SQLService3 as SQLService,
9800
10030
  SecretsService2 as SecretsService,
9801
- ServiceContext3 as ServiceContext,
10031
+ ServiceContext4 as ServiceContext,
9802
10032
  SessionExpiredError2 as SessionExpiredError,
9803
10033
  SharingService2 as SharingService,
9804
10034
  SilentNotificationHandler2 as SilentNotificationHandler,