@tinycloud/node-sdk 3.3.2-beta.1 → 3.5.0-beta.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/{TinyCloudNode-DeV-L_14.d.cts → TinyCloudNode-N4mfZI_k.d.cts} +7 -1
- package/dist/{TinyCloudNode-DeV-L_14.d.ts → TinyCloudNode-N4mfZI_k.d.ts} +7 -1
- package/dist/{authority-BO2VqGnD.d.cts → authority-BgZpUFss.d.cts} +1 -1
- package/dist/{authority-CtsxSAoP.d.ts → authority-C670-9su.d.ts} +1 -1
- package/dist/core.cjs +216 -27
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +221 -28
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +232 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +223 -30
- package/dist/index.js.map +1 -1
- package/dist/replication/authority.d.cts +2 -2
- package/dist/replication/authority.d.ts +2 -2
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -17045,7 +17045,7 @@ function augmentSignInEntriesWithReplication(input) {
|
|
|
17045
17045
|
for (const prefix of replication.prefixes) {
|
|
17046
17046
|
(0, import_prefix.assertFolderPrefix)(prefix);
|
|
17047
17047
|
const path = prefix === "/" ? "" : prefix;
|
|
17048
|
-
if ((0,
|
|
17048
|
+
if ((0, import_sdk_services2.requiresSecretsOptIn)(input.primarySpaceId, prefix) && replication.allowSecrets !== true) {
|
|
17049
17049
|
continue;
|
|
17050
17050
|
}
|
|
17051
17051
|
if (!hasUnrestrictedGetCoverage(input.entries, input.primarySpaceId, path)) {
|
|
@@ -17071,12 +17071,12 @@ function augmentSignInEntriesWithReplication(input) {
|
|
|
17071
17071
|
}
|
|
17072
17072
|
return out;
|
|
17073
17073
|
}
|
|
17074
|
-
var import_sdk_core2,
|
|
17074
|
+
var import_sdk_core2, import_sdk_services2, import_prefix, KV_GET, KV_SYNC, KV_SERVICE;
|
|
17075
17075
|
var init_authority_sign_in = __esm({
|
|
17076
17076
|
"src/replication/authority-sign-in.ts"() {
|
|
17077
17077
|
"use strict";
|
|
17078
17078
|
import_sdk_core2 = require("@tinycloud/sdk-core");
|
|
17079
|
-
|
|
17079
|
+
import_sdk_services2 = require("@tinycloud/sdk-services");
|
|
17080
17080
|
import_prefix = require("@tinycloud/sdk-services/kv/replication/prefix");
|
|
17081
17081
|
KV_GET = import_sdk_core2.KV.GET;
|
|
17082
17082
|
KV_SYNC = import_sdk_core2.KV.SYNC;
|
|
@@ -18069,6 +18069,167 @@ var PrivateKeySigner = class {
|
|
|
18069
18069
|
}
|
|
18070
18070
|
};
|
|
18071
18071
|
|
|
18072
|
+
// src/recordingServiceContext.ts
|
|
18073
|
+
var import_sdk_services = require("@tinycloud/sdk-services");
|
|
18074
|
+
var import_requestLog = require("@tinycloud/sdk-services/telemetry/requestLog");
|
|
18075
|
+
|
|
18076
|
+
// src/recordingRegistry.ts
|
|
18077
|
+
var unrecordedFetches = /* @__PURE__ */ new WeakMap();
|
|
18078
|
+
function registerRecording(context, unrecordedFetch) {
|
|
18079
|
+
unrecordedFetches.set(context, unrecordedFetch);
|
|
18080
|
+
}
|
|
18081
|
+
function unrecordedFetchOf(context) {
|
|
18082
|
+
const unrecordedFetch = unrecordedFetches.get(context);
|
|
18083
|
+
return unrecordedFetch ? unrecordedFetch() : context.fetch;
|
|
18084
|
+
}
|
|
18085
|
+
|
|
18086
|
+
// src/recordingServiceContext.ts
|
|
18087
|
+
var SYNC_ABILITY = "tinycloud.kv/sync";
|
|
18088
|
+
var INFO_PATH = "/info";
|
|
18089
|
+
function outcomeCodeOf(response) {
|
|
18090
|
+
return response === void 0 ? "ERROR" : response.ok ? "ok" : `HTTP_${response.status}`;
|
|
18091
|
+
}
|
|
18092
|
+
function replicationOp(url, meta) {
|
|
18093
|
+
if (meta !== void 0) return meta.action === SYNC_ABILITY ? `${meta.service}/sync` : void 0;
|
|
18094
|
+
return isInfoUrl(url) ? "sync/info" : void 0;
|
|
18095
|
+
}
|
|
18096
|
+
function isInfoUrl(url) {
|
|
18097
|
+
try {
|
|
18098
|
+
return new URL(url).pathname.replace(/\/+$/, "") === INFO_PATH;
|
|
18099
|
+
} catch {
|
|
18100
|
+
return false;
|
|
18101
|
+
}
|
|
18102
|
+
}
|
|
18103
|
+
function replicationEvent(sample, op) {
|
|
18104
|
+
return (0, import_requestLog.buildRequestEvent)({
|
|
18105
|
+
service: "sync",
|
|
18106
|
+
op,
|
|
18107
|
+
url: sample.url,
|
|
18108
|
+
bytes: (0, import_requestLog.requestBytesOf)(sample.init?.body, sample.response?.headers.get("content-length")),
|
|
18109
|
+
durationMs: performance.now() - sample.clock,
|
|
18110
|
+
attempts: sample.attempts ?? 1,
|
|
18111
|
+
ok: sample.response?.ok === true,
|
|
18112
|
+
code: outcomeCodeOf(sample.response),
|
|
18113
|
+
at: sample.at
|
|
18114
|
+
});
|
|
18115
|
+
}
|
|
18116
|
+
function createServiceContext(config) {
|
|
18117
|
+
const { requestSink, ...base2 } = config;
|
|
18118
|
+
return requestSink === void 0 ? new import_sdk_services.ServiceContext(base2) : new RecordingServiceContext(base2, requestSink);
|
|
18119
|
+
}
|
|
18120
|
+
var RecordingServiceContext = class extends import_sdk_services.ServiceContext {
|
|
18121
|
+
constructor(config, sink) {
|
|
18122
|
+
const pending = {};
|
|
18123
|
+
super({
|
|
18124
|
+
...config,
|
|
18125
|
+
invoke: rememberInvoke(config.invoke, sink, pending),
|
|
18126
|
+
invokeAny: config.invokeAny ? rememberInvokeAny(config.invokeAny, sink, pending) : void 0
|
|
18127
|
+
});
|
|
18128
|
+
this.requestSink = sink;
|
|
18129
|
+
this.pending = pending;
|
|
18130
|
+
registerRecording(this, () => this.unrecordedFetch);
|
|
18131
|
+
}
|
|
18132
|
+
/** Per-call recording; `_fetch` is read at access time, so overrides apply. */
|
|
18133
|
+
get fetch() {
|
|
18134
|
+
const raw = super.fetch;
|
|
18135
|
+
return (url, init2) => this.recordCall(raw, url, init2);
|
|
18136
|
+
}
|
|
18137
|
+
/** Transport without per-call recording. */
|
|
18138
|
+
get unrecordedFetch() {
|
|
18139
|
+
return super.fetch;
|
|
18140
|
+
}
|
|
18141
|
+
/**
|
|
18142
|
+
* One event per logical request. The first resolved attempt's init is the logged request and
|
|
18143
|
+
* `attempts` counts resolved builds. A retired context throws before the first build and records
|
|
18144
|
+
* nothing, as master does.
|
|
18145
|
+
*/
|
|
18146
|
+
async invokeWithRetry(url, build) {
|
|
18147
|
+
const at = Date.now();
|
|
18148
|
+
const clock = performance.now();
|
|
18149
|
+
let reached = false;
|
|
18150
|
+
let attempts = 0;
|
|
18151
|
+
let first;
|
|
18152
|
+
let firstMeta;
|
|
18153
|
+
let response;
|
|
18154
|
+
const attempt = async () => {
|
|
18155
|
+
reached = true;
|
|
18156
|
+
this.pending.meta = void 0;
|
|
18157
|
+
const built = build();
|
|
18158
|
+
const meta = this.pending.meta;
|
|
18159
|
+
const init2 = await built;
|
|
18160
|
+
attempts += 1;
|
|
18161
|
+
if (first === void 0) {
|
|
18162
|
+
first = init2;
|
|
18163
|
+
firstMeta = meta;
|
|
18164
|
+
}
|
|
18165
|
+
return init2;
|
|
18166
|
+
};
|
|
18167
|
+
try {
|
|
18168
|
+
response = await super.invokeWithRetry(url, attempt);
|
|
18169
|
+
return response;
|
|
18170
|
+
} finally {
|
|
18171
|
+
if (reached) {
|
|
18172
|
+
this.observeAttempt({ url, init: first, response, meta: firstMeta, at, clock, attempts });
|
|
18173
|
+
}
|
|
18174
|
+
}
|
|
18175
|
+
}
|
|
18176
|
+
async recordCall(fetchFn, url, init2) {
|
|
18177
|
+
const at = Date.now();
|
|
18178
|
+
const clock = performance.now();
|
|
18179
|
+
let response;
|
|
18180
|
+
try {
|
|
18181
|
+
response = await fetchFn(url, init2);
|
|
18182
|
+
return response;
|
|
18183
|
+
} finally {
|
|
18184
|
+
this.observeAttempt({ url, init: init2, response, at, clock });
|
|
18185
|
+
}
|
|
18186
|
+
}
|
|
18187
|
+
observeAttempt(sample) {
|
|
18188
|
+
try {
|
|
18189
|
+
const replication = replicationOp(sample.url, sample.meta ?? (0, import_requestLog.invocationMetaOf)(sample.init?.headers));
|
|
18190
|
+
if (replication !== void 0) {
|
|
18191
|
+
this.requestSink.record(replicationEvent(sample, replication));
|
|
18192
|
+
return;
|
|
18193
|
+
}
|
|
18194
|
+
const headers = sample.init?.headers;
|
|
18195
|
+
if (sample.meta !== void 0 && typeof headers === "object" && headers !== null) {
|
|
18196
|
+
this.requestSink.remember(headers, sample.meta);
|
|
18197
|
+
}
|
|
18198
|
+
this.requestSink.observe({
|
|
18199
|
+
url: sample.url,
|
|
18200
|
+
requestHeaders: headers,
|
|
18201
|
+
requestBody: sample.init?.body,
|
|
18202
|
+
responseContentLength: sample.response?.headers.get("content-length"),
|
|
18203
|
+
ok: sample.response?.ok === true,
|
|
18204
|
+
code: outcomeCodeOf(sample.response),
|
|
18205
|
+
durationMs: performance.now() - sample.clock,
|
|
18206
|
+
attempts: sample.attempts ?? 1,
|
|
18207
|
+
at: sample.at
|
|
18208
|
+
});
|
|
18209
|
+
} catch {
|
|
18210
|
+
}
|
|
18211
|
+
}
|
|
18212
|
+
};
|
|
18213
|
+
function rememberInvoke(invoke2, sink, pending) {
|
|
18214
|
+
return (session, service, path, action, facts) => {
|
|
18215
|
+
const headers = invoke2(session, service, path, action, facts);
|
|
18216
|
+
const meta = { service, path, action, spaceId: session.spaceId };
|
|
18217
|
+
pending.meta = meta;
|
|
18218
|
+
sink.remember(headers, meta);
|
|
18219
|
+
return headers;
|
|
18220
|
+
};
|
|
18221
|
+
}
|
|
18222
|
+
function rememberInvokeAny(invokeAny2, sink, pending) {
|
|
18223
|
+
return (session, entries, facts) => {
|
|
18224
|
+
const headers = invokeAny2(session, entries, facts);
|
|
18225
|
+
const first = entries[0];
|
|
18226
|
+
const meta = first === void 0 ? void 0 : { service: first.service, path: first.path, action: first.action, spaceId: first.spaceId ?? session.spaceId };
|
|
18227
|
+
pending.meta = meta;
|
|
18228
|
+
if (meta !== void 0) sink.remember(headers, meta);
|
|
18229
|
+
return headers;
|
|
18230
|
+
};
|
|
18231
|
+
}
|
|
18232
|
+
|
|
18072
18233
|
// src/delegation.ts
|
|
18073
18234
|
var import_sdk_core = require("@tinycloud/sdk-core");
|
|
18074
18235
|
var RUNTIME_DELEGATION_REJECTIONS = [
|
|
@@ -18625,7 +18786,8 @@ function getNodeReplicationLoaders() {
|
|
|
18625
18786
|
|
|
18626
18787
|
// src/TinyCloudNode.ts
|
|
18627
18788
|
var import_sdk_core9 = require("@tinycloud/sdk-core");
|
|
18628
|
-
var
|
|
18789
|
+
var import_sdk_services3 = require("@tinycloud/sdk-services");
|
|
18790
|
+
var import_requestLog2 = require("@tinycloud/sdk-services/telemetry/requestLog");
|
|
18629
18791
|
|
|
18630
18792
|
// src/authorization/NodeUserAuthorization.ts
|
|
18631
18793
|
var import_node_crypto = require("crypto");
|
|
@@ -20448,12 +20610,13 @@ var DelegatedAccess = class {
|
|
|
20448
20610
|
this.session = session;
|
|
20449
20611
|
this._delegation = delegation;
|
|
20450
20612
|
this.host = host;
|
|
20451
|
-
const context =
|
|
20613
|
+
const context = createServiceContext({
|
|
20452
20614
|
invoke: invoke2,
|
|
20453
20615
|
invokeAny: invokeAny2,
|
|
20454
20616
|
fetch: lifetime?.fetch ?? globalThis.fetch.bind(globalThis),
|
|
20455
20617
|
hosts: [host],
|
|
20456
|
-
telemetry
|
|
20618
|
+
telemetry,
|
|
20619
|
+
requestSink: lifetime?.requestSink
|
|
20457
20620
|
});
|
|
20458
20621
|
this._serviceContext = lifetime ? lifetime.track(context) : context;
|
|
20459
20622
|
const prefix = this._delegation.path.replace(/\/$/, "");
|
|
@@ -21043,11 +21206,12 @@ function createDefaultSessionKey(wasm) {
|
|
|
21043
21206
|
return { manager, keyId, jwk: JSON.parse(jwkStr) };
|
|
21044
21207
|
}
|
|
21045
21208
|
var ServiceGraphLifetime = class {
|
|
21046
|
-
constructor(invokeFn, invokeAnyFn, fetchFn, observeContext) {
|
|
21209
|
+
constructor(invokeFn, invokeAnyFn, fetchFn, observeContext, requestSink) {
|
|
21047
21210
|
this.invokeFn = invokeFn;
|
|
21048
21211
|
this.invokeAnyFn = invokeAnyFn;
|
|
21049
21212
|
this.fetchFn = fetchFn;
|
|
21050
21213
|
this.observeContext = observeContext;
|
|
21214
|
+
this.requestSink = requestSink;
|
|
21051
21215
|
this.abortController = new AbortController();
|
|
21052
21216
|
this.contexts = /* @__PURE__ */ new Set();
|
|
21053
21217
|
this.retired = false;
|
|
@@ -21618,6 +21782,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21618
21782
|
this.sessionManager = sessionKey.manager;
|
|
21619
21783
|
this.sessionKeyId = sessionKey.keyId;
|
|
21620
21784
|
this.sessionKeyJwk = sessionKey.jwk;
|
|
21785
|
+
this._requestLog = config.requestLog === true ? new import_requestLog2.RequestLog() : void 0;
|
|
21621
21786
|
this._serviceGraph = this.createServiceGraphLifetime();
|
|
21622
21787
|
this._capabilityRegistry = new import_sdk_core9.CapabilityKeyRegistry();
|
|
21623
21788
|
this._keyProvider = new WasmKeyProvider({
|
|
@@ -21789,7 +21954,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21789
21954
|
createKVService: (config) => {
|
|
21790
21955
|
const prefix = config.pathPrefix?.replace(/\/$/, "");
|
|
21791
21956
|
const kvService = new import_sdk_core9.KVService({ prefix });
|
|
21792
|
-
const kvContext = receiveOnlyGraph.track(
|
|
21957
|
+
const kvContext = receiveOnlyGraph.track(createServiceContext({
|
|
21958
|
+
requestSink: receiveOnlyGraph.requestSink,
|
|
21793
21959
|
invoke: config.invoke,
|
|
21794
21960
|
fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
|
|
21795
21961
|
hosts: config.hosts,
|
|
@@ -21852,6 +22018,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21852
22018
|
shouldUseBootstrapSignInRequest(config) {
|
|
21853
22019
|
return config.autoBootstrapAccount !== false && config.manifest === void 0 && config.capabilityRequest === void 0 && (config.prefix ?? "default") === "default" && isOpenKeyAutoSignStrategy(config.signStrategy);
|
|
21854
22020
|
}
|
|
22021
|
+
/** Sanitized developer request events; undefined unless the node was built with `requestLog: true`. */
|
|
22022
|
+
get requests() {
|
|
22023
|
+
return this._requestLog === void 0 ? void 0 : (0, import_requestLog2.readOnlyRequestLog)(this._requestLog);
|
|
22024
|
+
}
|
|
21855
22025
|
createServiceGraphLifetime() {
|
|
21856
22026
|
return new ServiceGraphLifetime(
|
|
21857
22027
|
this.invokeWithRuntimePermissions,
|
|
@@ -21862,7 +22032,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21862
22032
|
(url, init2) => globalThis.fetch(url, init2),
|
|
21863
22033
|
(context) => {
|
|
21864
22034
|
this.storageFull.observe(context);
|
|
21865
|
-
|
|
22035
|
+
if (this._requestLog) (0, import_requestLog2.observeReplicaReads)(context, this._requestLog);
|
|
22036
|
+
},
|
|
22037
|
+
this._requestLog
|
|
21866
22038
|
);
|
|
21867
22039
|
}
|
|
21868
22040
|
syncResolvedHostFromAuth() {
|
|
@@ -22185,6 +22357,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22185
22357
|
this.hostedOwnedSpaceIds.clear();
|
|
22186
22358
|
this.cancelOwnedSpaceHosts();
|
|
22187
22359
|
this.storageFull.clear();
|
|
22360
|
+
this._requestLog?.clear();
|
|
22188
22361
|
this._bootstrapSkipped = false;
|
|
22189
22362
|
this._bootstrapStatus = { skipped: false };
|
|
22190
22363
|
this.replicationDelegateSession = void 0;
|
|
@@ -22276,7 +22449,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22276
22449
|
const denial = await this.denyReplicaGate({ reason: "account_switch", principal: priorPrincipal, next: nextPrincipal });
|
|
22277
22450
|
this.replicaRestoreGate = denial?.status === "unguarded" ? "gate_unavailable" : "stamp_stale";
|
|
22278
22451
|
}
|
|
22279
|
-
if (address !== this._address || chainId !== this._chainId)
|
|
22452
|
+
if (address !== this._address || chainId !== this._chainId) {
|
|
22453
|
+
this.storageFull.clear();
|
|
22454
|
+
this._requestLog?.clear();
|
|
22455
|
+
}
|
|
22280
22456
|
this._address = address;
|
|
22281
22457
|
this._chainId = chainId;
|
|
22282
22458
|
this._kv = void 0;
|
|
@@ -22855,10 +23031,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22855
23031
|
const contexts = [context];
|
|
22856
23032
|
const accountSpaceId = this.ownedSpaceId(import_sdk_core9.ACCOUNT_REGISTRY_SPACE);
|
|
22857
23033
|
const createScopedContext = (spaceId) => {
|
|
22858
|
-
const scoped = this._serviceGraph.track(
|
|
23034
|
+
const scoped = this._serviceGraph.track(createServiceContext({
|
|
23035
|
+
requestSink: this._serviceGraph.requestSink,
|
|
22859
23036
|
invoke: context.invoke,
|
|
22860
23037
|
invokeAny: context.invokeAny,
|
|
22861
|
-
fetch: context
|
|
23038
|
+
fetch: unrecordedFetchOf(context),
|
|
22862
23039
|
hosts: context.hosts,
|
|
22863
23040
|
telemetry: this.config.telemetry,
|
|
22864
23041
|
retryPolicy: this.config.retryPolicy
|
|
@@ -22910,7 +23087,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22910
23087
|
if (!this.currentSessionCoversAccountRegistry()) {
|
|
22911
23088
|
if (!_TinyCloudNode.accountRegistrySkipLogged) {
|
|
22912
23089
|
_TinyCloudNode.accountRegistrySkipLogged = true;
|
|
22913
|
-
|
|
23090
|
+
import_sdk_services3.tinyCloudDebugLogger.log("registry.skip");
|
|
22914
23091
|
}
|
|
22915
23092
|
return;
|
|
22916
23093
|
}
|
|
@@ -22922,10 +23099,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22922
23099
|
const promise = this.enqueueAccountRegistryOperation(session, async () => {
|
|
22923
23100
|
const sharedContext = this._serviceContext;
|
|
22924
23101
|
if (!sharedContext) return;
|
|
22925
|
-
const context = this._serviceGraph.track(
|
|
23102
|
+
const context = this._serviceGraph.track(createServiceContext({
|
|
23103
|
+
requestSink: this._serviceGraph.requestSink,
|
|
22926
23104
|
invoke: sharedContext.invoke,
|
|
22927
23105
|
invokeAny: sharedContext.invokeAny,
|
|
22928
|
-
fetch: sharedContext
|
|
23106
|
+
fetch: unrecordedFetchOf(sharedContext),
|
|
22929
23107
|
hosts: sharedContext.hosts,
|
|
22930
23108
|
telemetry: this.config.telemetry,
|
|
22931
23109
|
retryPolicy: this.config.retryPolicy
|
|
@@ -23659,6 +23837,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23659
23837
|
if (resolvedHost) this.config.host = resolvedHost;
|
|
23660
23838
|
if (spaceOwnerKey(serviceSession.spaceId) !== this.currentStorageOwner()) {
|
|
23661
23839
|
this.storageFull.clear();
|
|
23840
|
+
this._requestLog?.clear();
|
|
23662
23841
|
}
|
|
23663
23842
|
this._address = stagedAddress;
|
|
23664
23843
|
this._chainId = stagedChainId;
|
|
@@ -23778,7 +23957,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23778
23957
|
const coreContext = graph.track(core.serviceContext);
|
|
23779
23958
|
coreContext.setSession(input.serviceSession);
|
|
23780
23959
|
}
|
|
23781
|
-
const serviceContext = graph.track(
|
|
23960
|
+
const serviceContext = graph.track(createServiceContext({
|
|
23961
|
+
requestSink: graph.requestSink,
|
|
23782
23962
|
invoke: graph.invoke,
|
|
23783
23963
|
invokeAny: graph.invokeAny,
|
|
23784
23964
|
fetch: graph.fetch,
|
|
@@ -23866,7 +24046,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23866
24046
|
},
|
|
23867
24047
|
createKVService: (config) => {
|
|
23868
24048
|
const service = new import_sdk_core9.KVService({ prefix: config.pathPrefix?.replace(/\/$/, "") });
|
|
23869
|
-
const context = graph.track(
|
|
24049
|
+
const context = graph.track(createServiceContext({
|
|
24050
|
+
requestSink: graph.requestSink,
|
|
23870
24051
|
invoke: config.invoke,
|
|
23871
24052
|
fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
|
|
23872
24053
|
hosts: config.hosts,
|
|
@@ -23906,7 +24087,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23906
24087
|
createKVService: (spaceId) => {
|
|
23907
24088
|
graph.assertActive();
|
|
23908
24089
|
const scopedKv = new import_sdk_core9.KVService({});
|
|
23909
|
-
const context = graph.track(
|
|
24090
|
+
const context = graph.track(createServiceContext({
|
|
24091
|
+
requestSink: graph.requestSink,
|
|
23910
24092
|
invoke: graph.invoke,
|
|
23911
24093
|
invokeAny: graph.invokeAny,
|
|
23912
24094
|
fetch: graph.fetch,
|
|
@@ -23922,7 +24104,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23922
24104
|
createVaultService: (spaceId) => {
|
|
23923
24105
|
graph.assertActive();
|
|
23924
24106
|
const scopedKv = new import_sdk_core9.KVService({});
|
|
23925
|
-
const context = graph.track(
|
|
24107
|
+
const context = graph.track(createServiceContext({
|
|
24108
|
+
requestSink: graph.requestSink,
|
|
23926
24109
|
invoke: graph.invoke,
|
|
23927
24110
|
invokeAny: graph.invokeAny,
|
|
23928
24111
|
fetch: graph.fetch,
|
|
@@ -24321,7 +24504,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24321
24504
|
this._serviceGraph.fetch
|
|
24322
24505
|
);
|
|
24323
24506
|
this._serviceGraph.track(this.tc.serviceContext);
|
|
24324
|
-
this._serviceContext = this._serviceGraph.track(
|
|
24507
|
+
this._serviceContext = this._serviceGraph.track(createServiceContext({
|
|
24508
|
+
requestSink: this._serviceGraph.requestSink,
|
|
24325
24509
|
invoke: this._serviceGraph.invoke,
|
|
24326
24510
|
invokeAny: this._serviceGraph.invokeAny,
|
|
24327
24511
|
fetch: this._serviceGraph.fetch,
|
|
@@ -24369,10 +24553,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24369
24553
|
createSpaceScopedKVService(spaceId) {
|
|
24370
24554
|
const kvService = new import_sdk_core9.KVService({});
|
|
24371
24555
|
if (this._serviceContext) {
|
|
24372
|
-
const spaceScopedContext = this._serviceGraph.track(
|
|
24556
|
+
const spaceScopedContext = this._serviceGraph.track(createServiceContext({
|
|
24557
|
+
requestSink: this._serviceGraph.requestSink,
|
|
24373
24558
|
invoke: this._serviceContext.invoke,
|
|
24374
24559
|
invokeAny: this._serviceContext.invokeAny,
|
|
24375
|
-
fetch: this._serviceContext
|
|
24560
|
+
fetch: unrecordedFetchOf(this._serviceContext),
|
|
24376
24561
|
hosts: this._serviceContext.hosts,
|
|
24377
24562
|
telemetry: this.config.telemetry,
|
|
24378
24563
|
retryPolicy: this.config.retryPolicy
|
|
@@ -24560,7 +24745,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24560
24745
|
);
|
|
24561
24746
|
graph.assertActive();
|
|
24562
24747
|
if (!response.ok) {
|
|
24563
|
-
const permissionHint = response.status === 401 || response.status === 403 ? (0,
|
|
24748
|
+
const permissionHint = response.status === 401 || response.status === 403 ? (0, import_sdk_services3.parsePermissionHint)({
|
|
24564
24749
|
service: "tinycloud.encryption",
|
|
24565
24750
|
path: networkId,
|
|
24566
24751
|
actions: ["tinycloud.encryption/decrypt"]
|
|
@@ -24838,7 +25023,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24838
25023
|
createKVService: (config) => {
|
|
24839
25024
|
graph.assertActive();
|
|
24840
25025
|
const service = new import_sdk_core9.KVService({ prefix: config.pathPrefix?.replace(/\/$/, "") });
|
|
24841
|
-
const context = graph.track(
|
|
25026
|
+
const context = graph.track(createServiceContext({
|
|
25027
|
+
requestSink: graph.requestSink,
|
|
24842
25028
|
invoke: config.invoke,
|
|
24843
25029
|
fetch: config.fetch ?? graph.fetch,
|
|
24844
25030
|
hosts: config.hosts,
|
|
@@ -25159,10 +25345,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25159
25345
|
throw new Error("Not signed in. Call signIn() first.");
|
|
25160
25346
|
}
|
|
25161
25347
|
const sql = new import_sdk_core9.SQLService({});
|
|
25162
|
-
const spaceScopedContext = this._serviceGraph.track(
|
|
25348
|
+
const spaceScopedContext = this._serviceGraph.track(createServiceContext({
|
|
25349
|
+
requestSink: this._serviceGraph.requestSink,
|
|
25163
25350
|
invoke: this._serviceContext.invoke,
|
|
25164
25351
|
invokeAny: this._serviceContext.invokeAny,
|
|
25165
|
-
fetch: this._serviceContext
|
|
25352
|
+
fetch: unrecordedFetchOf(this._serviceContext),
|
|
25166
25353
|
hosts: this._serviceContext.hosts,
|
|
25167
25354
|
telemetry: this.config.telemetry,
|
|
25168
25355
|
retryPolicy: this.config.retryPolicy
|
|
@@ -25190,10 +25377,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25190
25377
|
throw new Error("Not signed in. Call signIn() first.");
|
|
25191
25378
|
}
|
|
25192
25379
|
const kv = new import_sdk_core9.KVService({});
|
|
25193
|
-
const spaceScopedContext = this._serviceGraph.track(
|
|
25380
|
+
const spaceScopedContext = this._serviceGraph.track(createServiceContext({
|
|
25381
|
+
requestSink: this._serviceGraph.requestSink,
|
|
25194
25382
|
invoke: this._serviceContext.invoke,
|
|
25195
25383
|
invokeAny: this._serviceContext.invokeAny,
|
|
25196
|
-
fetch: this._serviceContext
|
|
25384
|
+
fetch: unrecordedFetchOf(this._serviceContext),
|
|
25197
25385
|
hosts: this._serviceContext.hosts
|
|
25198
25386
|
}));
|
|
25199
25387
|
spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
|
|
@@ -25356,7 +25544,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25356
25544
|
);
|
|
25357
25545
|
if (result.status !== "ok") {
|
|
25358
25546
|
if (result.status === "permission_required") {
|
|
25359
|
-
const hint = (0,
|
|
25547
|
+
const hint = (0, import_sdk_services3.parsePermissionHint)(result.hint);
|
|
25360
25548
|
if (hint === void 0) return { status: "read_failed" };
|
|
25361
25549
|
return {
|
|
25362
25550
|
status: "permission_required",
|
|
@@ -25979,7 +26167,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25979
26167
|
}
|
|
25980
26168
|
if (this._serviceContext) {
|
|
25981
26169
|
const publicKV = new import_sdk_core9.KVService({ prefix: "" });
|
|
25982
|
-
const publicContext = this._serviceGraph.track(
|
|
26170
|
+
const publicContext = this._serviceGraph.track(createServiceContext({
|
|
26171
|
+
requestSink: this._serviceGraph.requestSink,
|
|
25983
26172
|
invoke: this._serviceGraph.invoke,
|
|
25984
26173
|
fetch: this._serviceGraph.fetch,
|
|
25985
26174
|
hosts: this._serviceContext.hosts,
|
|
@@ -27699,7 +27888,7 @@ var import_node_fs = require("fs");
|
|
|
27699
27888
|
var import_promises = require("fs/promises");
|
|
27700
27889
|
var import_node_path = require("path");
|
|
27701
27890
|
var import_sdk_core13 = require("@tinycloud/sdk-core");
|
|
27702
|
-
var
|
|
27891
|
+
var import_sdk_services4 = require("@tinycloud/sdk-services");
|
|
27703
27892
|
var import_contractConstants = require("@tinycloud/sdk-services/kv/replication/contractConstants");
|
|
27704
27893
|
init_authority();
|
|
27705
27894
|
var REPLICA_LOGOUT_PENDING_FILE = "replica-logout-pending.json";
|
|
@@ -28261,7 +28450,7 @@ function sha256Base32(material) {
|
|
|
28261
28450
|
return out.slice(0, 26);
|
|
28262
28451
|
}
|
|
28263
28452
|
function partitionDirOf(root, identity) {
|
|
28264
|
-
return (0, import_node_path.join)(root, sha256Base32((0,
|
|
28453
|
+
return (0, import_node_path.join)(root, sha256Base32((0, import_sdk_services4.replicationIdentityKey)(identity)));
|
|
28265
28454
|
}
|
|
28266
28455
|
function replicaHashOf(prefix, deviceDid) {
|
|
28267
28456
|
return sha256Base32(`${prefix}
|
|
@@ -28335,8 +28524,8 @@ function deviceRecordOf(value) {
|
|
|
28335
28524
|
}
|
|
28336
28525
|
function sameIdentity(a, b) {
|
|
28337
28526
|
try {
|
|
28338
|
-
const left = (0,
|
|
28339
|
-
const right = (0,
|
|
28527
|
+
const left = (0, import_sdk_services4.canonicalReplicationIdentity)(a);
|
|
28528
|
+
const right = (0, import_sdk_services4.canonicalReplicationIdentity)(b);
|
|
28340
28529
|
return left.host === right.host && left.space === right.space && left.principal === right.principal;
|
|
28341
28530
|
} catch {
|
|
28342
28531
|
return false;
|
|
@@ -28352,7 +28541,7 @@ async function ensurePartitionIdentity(dir, identity, dirSync) {
|
|
|
28352
28541
|
const file = (0, import_node_path.join)(dir, "identity.json");
|
|
28353
28542
|
const existing = await readJsonFile(file);
|
|
28354
28543
|
if (existing === void 0) {
|
|
28355
|
-
await writeJsonAtomic(file, { v: 1, ...(0,
|
|
28544
|
+
await writeJsonAtomic(file, { v: 1, ...(0, import_sdk_services4.canonicalReplicationIdentity)(identity) }, dirSync);
|
|
28356
28545
|
return;
|
|
28357
28546
|
}
|
|
28358
28547
|
const record = identityRecordOf(existing);
|
|
@@ -28451,7 +28640,7 @@ withGate_fn = async function(section) {
|
|
|
28451
28640
|
if (snapshot === void 0) throw gated("gate_unavailable");
|
|
28452
28641
|
const [principalHash, identityKeyHash] = await Promise.all([
|
|
28453
28642
|
gate.principalHashOf(snapshot.salt, this.identity.principal),
|
|
28454
|
-
gate.identityHashOf(snapshot.salt, (0,
|
|
28643
|
+
gate.identityHashOf(snapshot.salt, (0, import_sdk_services4.replicationIdentityKey)(this.identity))
|
|
28455
28644
|
]);
|
|
28456
28645
|
const access = {
|
|
28457
28646
|
stamp: __privateGet(this, _stamp),
|
|
@@ -28951,7 +29140,7 @@ function createSqliteReplicaStorage(options) {
|
|
|
28951
29140
|
if (snapshot === void 0) throw gated("gate_unavailable");
|
|
28952
29141
|
const [principalHash, identityKeyHash] = await Promise.all([
|
|
28953
29142
|
gate.principalHashOf(snapshot.salt, principal),
|
|
28954
|
-
identity === void 0 ? Promise.resolve(void 0) : gate.identityHashOf(snapshot.salt, (0,
|
|
29143
|
+
identity === void 0 ? Promise.resolve(void 0) : gate.identityHashOf(snapshot.salt, (0, import_sdk_services4.replicationIdentityKey)(identity))
|
|
28955
29144
|
]);
|
|
28956
29145
|
return profileSection(async () => {
|
|
28957
29146
|
assertLogoutClear(options.logoutPendingFile);
|
|
@@ -28974,7 +29163,7 @@ function createSqliteReplicaStorage(options) {
|
|
|
28974
29163
|
if (snapshot === void 0) throw gated("gate_unavailable");
|
|
28975
29164
|
const [principalHash, identityKeyHash] = await Promise.all([
|
|
28976
29165
|
gate.principalHashOf(snapshot.salt, spec.identity.principal),
|
|
28977
|
-
gate.identityHashOf(snapshot.salt, (0,
|
|
29166
|
+
gate.identityHashOf(snapshot.salt, (0, import_sdk_services4.replicationIdentityKey)(spec.identity))
|
|
28978
29167
|
]);
|
|
28979
29168
|
const access = {
|
|
28980
29169
|
stamp: spec.stamp,
|
|
@@ -29058,7 +29247,7 @@ function createSqliteReplicaStorage(options) {
|
|
|
29058
29247
|
const identity = identityRecordOf(await readJsonFile((0, import_node_path.join)(idDir, "identity.json")));
|
|
29059
29248
|
if (identity === void 0) throw new ReplicaStorageError("STORAGE_ERROR", `Missing identity at ${idDir}.`);
|
|
29060
29249
|
if (await gate.principalHashOf(salt, identity.principal) !== principalHash) continue;
|
|
29061
|
-
const identityKeyHash = await gate.identityHashOf(salt, (0,
|
|
29250
|
+
const identityKeyHash = await gate.identityHashOf(salt, (0, import_sdk_services4.replicationIdentityKey)(identity));
|
|
29062
29251
|
const recordedAt = Date.now();
|
|
29063
29252
|
if (await pathExists((0, import_node_path.join)(idDir, "pending.json")) || await pathExists((0, import_node_path.join)(idDir, "device.jwk"))) {
|
|
29064
29253
|
intents.push({ id: `pending:${identityKeyHash}`, kind: "pending", identityKeyHash, principalHash, recordedAt });
|
|
@@ -29736,7 +29925,7 @@ function createSqliteReplicaStorage(options) {
|
|
|
29736
29925
|
for (const dir of await identityDirs()) {
|
|
29737
29926
|
const identity = identityRecordOf(await readJsonFile((0, import_node_path.join)(dir, "identity.json")));
|
|
29738
29927
|
if (identity === void 0) throw new ReplicaStorageError("STORAGE_ERROR", `Missing identity at ${dir}.`);
|
|
29739
|
-
const hash3 = await gate.identityHashOf(state.salt, (0,
|
|
29928
|
+
const hash3 = await gate.identityHashOf(state.salt, (0, import_sdk_services4.replicationIdentityKey)(identity));
|
|
29740
29929
|
if (intent.kind === "pending" ? hash3 === intent.identityKeyHash : intent.partitionId.startsWith(`${hash3}:`)) {
|
|
29741
29930
|
idDir = dir;
|
|
29742
29931
|
break;
|
|
@@ -29882,7 +30071,7 @@ function createSqliteReplicaStorage(options) {
|
|
|
29882
30071
|
const gate = await fileGate();
|
|
29883
30072
|
const snapshot = await gate.readGateSnapshot(profileDir);
|
|
29884
30073
|
if (snapshot === void 0) throw gated("gate_unavailable");
|
|
29885
|
-
const identityKeyHash = await gate.identityHashOf(snapshot.salt, (0,
|
|
30074
|
+
const identityKeyHash = await gate.identityHashOf(snapshot.salt, (0, import_sdk_services4.replicationIdentityKey)(spec.identity));
|
|
29886
30075
|
const resolvePolicy = async (at, recordFirst) => {
|
|
29887
30076
|
const policy = spec.grantPolicy;
|
|
29888
30077
|
if (!Number.isSafeInteger(policy.grantTtlMs) || policy.grantTtlMs <= 0 || policy.grantTtlMs > import_contractConstants.MAX_GRANT_TTL_MS) {
|
|
@@ -29904,7 +30093,7 @@ function createSqliteReplicaStorage(options) {
|
|
|
29904
30093
|
let partitionId;
|
|
29905
30094
|
const storeGuard = (section) => guarded(spec.identity.principal, spec.stamp, spec.identity, partitionId, section);
|
|
29906
30095
|
return guarded(spec.identity.principal, spec.stamp, spec.identity, void 0, async () => {
|
|
29907
|
-
if ((0,
|
|
30096
|
+
if ((0, import_sdk_services4.requiresSecretsOptIn)(spec.space, spec.prefix) && spec.allowSecrets !== true) {
|
|
29908
30097
|
throw new replica.ReplicaError(
|
|
29909
30098
|
replica.ReplicaErrorCode.SECRETS_OPT_IN_REQUIRED,
|
|
29910
30099
|
`Replicating ${spec.space}/kv/${spec.prefix} copies secret material to disk; pass allowSecrets to opt in.`
|
|
@@ -30150,7 +30339,7 @@ function createSqliteReplicaStorage(options) {
|
|
|
30150
30339
|
const gate = await fileGate();
|
|
30151
30340
|
const currentGate = await gate.readGateSnapshot(profileDir);
|
|
30152
30341
|
if (currentGate !== void 0 && currentGate.principalHash !== null && currentGate.principalHash === await gate.principalHashOf(currentGate.salt, target.identity.principal)) {
|
|
30153
|
-
const identityKeyHash = await gate.identityHashOf(currentGate.salt, (0,
|
|
30342
|
+
const identityKeyHash = await gate.identityHashOf(currentGate.salt, (0, import_sdk_services4.replicationIdentityKey)(target.identity));
|
|
30154
30343
|
await retainGrantInstalls(gate, currentGate, identityKeyHash, store);
|
|
30155
30344
|
}
|
|
30156
30345
|
if (state.revoked === null) {
|