@tinycloud/node-sdk 3.3.0-beta.9 → 3.3.1-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-CcNh20QX.d.cts → TinyCloudNode-DeV-L_14.d.cts} +123 -46
- package/dist/{TinyCloudNode-CcNh20QX.d.ts → TinyCloudNode-DeV-L_14.d.ts} +123 -46
- package/dist/{authority-Cwotwza3.d.cts → authority-BO2VqGnD.d.cts} +1 -1
- package/dist/{authority-D_u9a7Wl.d.ts → authority-CtsxSAoP.d.ts} +1 -1
- package/dist/core.cjs +178 -93
- 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 +189 -96
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +229 -97
- 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 +240 -100
- 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 +5 -5
package/dist/index.js
CHANGED
|
@@ -18114,24 +18114,17 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
18114
18114
|
));
|
|
18115
18115
|
continue;
|
|
18116
18116
|
}
|
|
18117
|
-
const
|
|
18118
|
-
const policyMatch = /^tinycloud:\/\/([^/]+)\/(kv|sql|duckdb|hooks)\/(.*)$/.exec(resource);
|
|
18119
|
-
const match = nativeMatch ?? policyMatch;
|
|
18117
|
+
const match = /^(?:tinycloud:\/\/([^/]+)|(tinycloud:[^/]+))\/(kv|sql|duckdb|hooks)(?:\/|$)(.*)$/.exec(resource);
|
|
18120
18118
|
if (!match) {
|
|
18121
18119
|
throw new Error(
|
|
18122
18120
|
`Validated runtime delegation has an unsupported signed resource '${resource}'.`
|
|
18123
18121
|
);
|
|
18124
18122
|
}
|
|
18125
|
-
const [,
|
|
18123
|
+
const [, policySpace, nativeSpace, shortService, path] = match;
|
|
18126
18124
|
const service = SERVICE_BY_SHORT_NAME[shortService];
|
|
18127
|
-
if (service === void 0) {
|
|
18128
|
-
throw new Error(
|
|
18129
|
-
`Validated runtime delegation has an unsupported signed service '${shortService}'.`
|
|
18130
|
-
);
|
|
18131
|
-
}
|
|
18132
18125
|
permissions.push(...groupedSignedEntries(
|
|
18133
18126
|
service,
|
|
18134
|
-
|
|
18127
|
+
nativeSpace ?? policySpace,
|
|
18135
18128
|
path,
|
|
18136
18129
|
abilities
|
|
18137
18130
|
));
|
|
@@ -18557,6 +18550,8 @@ import {
|
|
|
18557
18550
|
canonicalizeAddress as canonicalizeAddress2,
|
|
18558
18551
|
pkhDid as pkhDid2,
|
|
18559
18552
|
resolveTinyCloudHosts as resolveTinyCloudHosts2,
|
|
18553
|
+
resolveFailClosedTinyCloudHosts as resolveFailClosedTinyCloudHosts2,
|
|
18554
|
+
createInMemoryRegistrySequenceStore as createInMemoryRegistrySequenceStore2,
|
|
18560
18555
|
publishLocationRecord,
|
|
18561
18556
|
principalDidEquals as principalDidEquals3,
|
|
18562
18557
|
parseNetworkId as parseNetworkId2,
|
|
@@ -18577,7 +18572,8 @@ import {
|
|
|
18577
18572
|
serviceError
|
|
18578
18573
|
} from "@tinycloud/sdk-core";
|
|
18579
18574
|
import {
|
|
18580
|
-
parsePermissionHint
|
|
18575
|
+
parsePermissionHint,
|
|
18576
|
+
tinyCloudDebugLogger
|
|
18581
18577
|
} from "@tinycloud/sdk-services";
|
|
18582
18578
|
|
|
18583
18579
|
// src/authorization/NodeUserAuthorization.ts
|
|
@@ -18598,6 +18594,11 @@ import {
|
|
|
18598
18594
|
resourceCapabilitiesToAbilitiesMap,
|
|
18599
18595
|
resourceCapabilitiesToSpaceAbilitiesMap,
|
|
18600
18596
|
resolveTinyCloudHosts,
|
|
18597
|
+
resolveFailClosedTinyCloudHosts,
|
|
18598
|
+
lookupOwnerRegistryVerdict,
|
|
18599
|
+
assertSpaceCreationAllowed,
|
|
18600
|
+
createInMemoryRegistrySequenceStore,
|
|
18601
|
+
registryOwnerSubjectV1,
|
|
18601
18602
|
EXPIRY,
|
|
18602
18603
|
canonicalizeAddress,
|
|
18603
18604
|
makePkhSpaceId,
|
|
@@ -18812,6 +18813,11 @@ var NodeUserAuthorization = class {
|
|
|
18812
18813
|
this.tinycloudHosts = config.tinycloudHosts;
|
|
18813
18814
|
this.tinycloudRegistryUrl = config.tinycloudRegistryUrl;
|
|
18814
18815
|
this.tinycloudFallbackHosts = config.tinycloudFallbackHosts;
|
|
18816
|
+
this.registryPolicy = config.registryPolicy;
|
|
18817
|
+
this.newUserHost = config.newUserHost;
|
|
18818
|
+
this.registryChainId = config.registryChainId;
|
|
18819
|
+
this.registrySequenceStore = config.registrySequenceStore ?? createInMemoryRegistrySequenceStore();
|
|
18820
|
+
this.onNodeNotFound = config.onNodeNotFound;
|
|
18815
18821
|
this.autoDiscoverLocalNode = config.autoDiscoverLocalNode;
|
|
18816
18822
|
this.localNodeUrl = config.localNodeUrl;
|
|
18817
18823
|
this.localLinkName = config.localLinkName;
|
|
@@ -18923,6 +18929,7 @@ var NodeUserAuthorization = class {
|
|
|
18923
18929
|
this._nodeFeaturesKnown = nodeFeatures !== void 0;
|
|
18924
18930
|
this._nodeInfoIdentity = void 0;
|
|
18925
18931
|
this.tinycloudHosts = hosts && hosts.length > 0 ? [...hosts] : void 0;
|
|
18932
|
+
this.registryVerdict = void 0;
|
|
18926
18933
|
this._lastActivationSkippedSpaceIds = [];
|
|
18927
18934
|
this._lastActivationActivatedSpaceIds = [];
|
|
18928
18935
|
if (!session) {
|
|
@@ -18973,6 +18980,23 @@ var NodeUserAuthorization = class {
|
|
|
18973
18980
|
if (this.tinycloudHosts && this.tinycloudHosts.length > 0) {
|
|
18974
18981
|
return;
|
|
18975
18982
|
}
|
|
18983
|
+
if (this.registryPolicy === "fail-closed") {
|
|
18984
|
+
const resolved2 = await resolveFailClosedTinyCloudHosts(address, {
|
|
18985
|
+
registryUrl: this.tinycloudRegistryUrl,
|
|
18986
|
+
registryChainId: this.registryChainId,
|
|
18987
|
+
newUserHost: this.newUserHost,
|
|
18988
|
+
sequenceStore: this.registrySequenceStore,
|
|
18989
|
+
onNodeNotFound: this.onNodeNotFound,
|
|
18990
|
+
autoDiscoverLocalNode: this.autoDiscoverLocalNode,
|
|
18991
|
+
localNodeUrl: this.localNodeUrl,
|
|
18992
|
+
localLinkName: this.localLinkName,
|
|
18993
|
+
expectedNodeDid: this.expectedNodeDid,
|
|
18994
|
+
localNodeIdentityStore: this.localNodeIdentityStore
|
|
18995
|
+
});
|
|
18996
|
+
this.tinycloudHosts = resolved2.hosts;
|
|
18997
|
+
this.registryVerdict = resolved2.verdict;
|
|
18998
|
+
return;
|
|
18999
|
+
}
|
|
18976
19000
|
const subject = pkhDid(address, chainId);
|
|
18977
19001
|
const resolved = await resolveTinyCloudHosts(subject, {
|
|
18978
19002
|
registryUrl: this.tinycloudRegistryUrl,
|
|
@@ -18985,6 +19009,32 @@ var NodeUserAuthorization = class {
|
|
|
18985
19009
|
});
|
|
18986
19010
|
this.tinycloudHosts = resolved.hosts;
|
|
18987
19011
|
}
|
|
19012
|
+
/**
|
|
19013
|
+
* Space-creation guard (TC-1443). Under `registryPolicy: "fail-closed"`,
|
|
19014
|
+
* throws unless the owner's registry verdict allows a space on the primary
|
|
19015
|
+
* host: `NodeRegistryEntryExistsError` when the owner's record does not
|
|
19016
|
+
* list it, `RegistryUnavailableError` when the registry gives no
|
|
19017
|
+
* verdict. Reuses this session's sign-in verdict unless it was
|
|
19018
|
+
* `unavailable`, else looks it up now (explicit-host apps). Under the
|
|
19019
|
+
* default policy it returns at once and performs no lookup.
|
|
19020
|
+
*/
|
|
19021
|
+
async assertMayCreateSpace() {
|
|
19022
|
+
if (this.registryPolicy !== "fail-closed") return;
|
|
19023
|
+
if (this._address === void 0) {
|
|
19024
|
+
throw new Error("Must be signed in to create a space");
|
|
19025
|
+
}
|
|
19026
|
+
await this.ensureTinyCloudHosts();
|
|
19027
|
+
const subject = registryOwnerSubjectV1(this._address, this.registryChainId);
|
|
19028
|
+
let verdict = this.registryVerdict;
|
|
19029
|
+
if (verdict?.subject !== subject || verdict.status === "unavailable") {
|
|
19030
|
+
verdict = await lookupOwnerRegistryVerdict(subject, {
|
|
19031
|
+
registryUrl: this.tinycloudRegistryUrl,
|
|
19032
|
+
sequenceStore: this.registrySequenceStore
|
|
19033
|
+
});
|
|
19034
|
+
this.registryVerdict = verdict;
|
|
19035
|
+
}
|
|
19036
|
+
assertSpaceCreationAllowed(verdict, this.primaryTinyCloudHost);
|
|
19037
|
+
}
|
|
18988
19038
|
requireTinyCloudHosts() {
|
|
18989
19039
|
if (!this.tinycloudHosts || this.tinycloudHosts.length === 0) {
|
|
18990
19040
|
throw new Error("TinyCloud hosts have not been resolved. Call signIn() first.");
|
|
@@ -19433,6 +19483,7 @@ var NodeUserAuthorization = class {
|
|
|
19433
19483
|
if (!handler) {
|
|
19434
19484
|
return;
|
|
19435
19485
|
}
|
|
19486
|
+
await this.guardSpaceCreation(handler, creationContext);
|
|
19436
19487
|
const confirmed = await handler.confirmSpaceCreation(creationContext);
|
|
19437
19488
|
if (!confirmed) {
|
|
19438
19489
|
return;
|
|
@@ -19473,6 +19524,7 @@ var NodeUserAuthorization = class {
|
|
|
19473
19524
|
if (!handler) {
|
|
19474
19525
|
return;
|
|
19475
19526
|
}
|
|
19527
|
+
await this.guardSpaceCreation(handler, creationContext);
|
|
19476
19528
|
const confirmed = await handler.confirmSpaceCreation(creationContext);
|
|
19477
19529
|
if (!confirmed) {
|
|
19478
19530
|
return;
|
|
@@ -19514,6 +19566,16 @@ var NodeUserAuthorization = class {
|
|
|
19514
19566
|
{ cause: result }
|
|
19515
19567
|
);
|
|
19516
19568
|
}
|
|
19569
|
+
/** {@link assertMayCreateSpace}, reporting a refusal to the creation handler before rethrowing it. */
|
|
19570
|
+
async guardSpaceCreation(handler, context) {
|
|
19571
|
+
try {
|
|
19572
|
+
await this.assertMayCreateSpace();
|
|
19573
|
+
} catch (error) {
|
|
19574
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
19575
|
+
handler.onSpaceCreationFailed?.(context, failure);
|
|
19576
|
+
throw failure;
|
|
19577
|
+
}
|
|
19578
|
+
}
|
|
19517
19579
|
recordActivationSkippedSpaces(result, primarySpaceId) {
|
|
19518
19580
|
if (result.success) {
|
|
19519
19581
|
this._lastActivationSkippedSpaceIds = result.skipped ?? [];
|
|
@@ -21086,6 +21148,12 @@ function describeHostFailure2(result) {
|
|
|
21086
21148
|
const text = result.error?.trim();
|
|
21087
21149
|
return text ? `${result.status} - ${text}` : `${result.status}`;
|
|
21088
21150
|
}
|
|
21151
|
+
function assertDelegationActivated(result, delegation, requireActivation) {
|
|
21152
|
+
const skipped = requireActivation ? (delegation.resources?.map((r2) => r2.space) ?? [delegation.spaceId]).filter((space) => result.skipped?.includes(space)) : [];
|
|
21153
|
+
if (result.success && skipped.length === 0) return;
|
|
21154
|
+
const detail = result.success ? `the node skipped ${[...new Set(skipped)].join(", ")} (space not hosted on the node)` : describeHostFailure2(result);
|
|
21155
|
+
throw Object.assign(new Error(`Failed to activate delegation with host: ${detail}`), { cause: result });
|
|
21156
|
+
}
|
|
21089
21157
|
function ownerDelegationPermissions(params) {
|
|
21090
21158
|
const hasPermissions = Object.prototype.hasOwnProperty.call(params, "permissions");
|
|
21091
21159
|
const hasLegacy = Object.prototype.hasOwnProperty.call(params, "path") || Object.prototype.hasOwnProperty.call(params, "actions");
|
|
@@ -21168,7 +21236,7 @@ function ownerPermissionsToAbilities(permissions) {
|
|
|
21168
21236
|
}
|
|
21169
21237
|
return { abilities, rawAbilities };
|
|
21170
21238
|
}
|
|
21171
|
-
var TERMINAL_DELEGATION_REQUIRES_SESSION_KEY = "disableSubDelegation requires a session-key delegation";
|
|
21239
|
+
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";
|
|
21172
21240
|
function base64UrlEncode(bytes) {
|
|
21173
21241
|
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
21174
21242
|
let output = "";
|
|
@@ -21482,7 +21550,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21482
21550
|
this.explicitHost = config.host;
|
|
21483
21551
|
this.config = {
|
|
21484
21552
|
...config,
|
|
21485
|
-
host: config.host ?? DEFAULT_HOST
|
|
21553
|
+
host: config.host ?? DEFAULT_HOST,
|
|
21554
|
+
// One store for every authorization this client creates.
|
|
21555
|
+
registrySequenceStore: config.registrySequenceStore ?? createInMemoryRegistrySequenceStore2()
|
|
21486
21556
|
};
|
|
21487
21557
|
if (this.config.replication?.enabled) {
|
|
21488
21558
|
const runtime = getNodeReplicationLoaders().runtime().then(({ ReplicationRuntime: ReplicationRuntime2 }) => {
|
|
@@ -21717,7 +21787,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21717
21787
|
if (!this.wasmBindings.computeCid) throw new Error("computeCid is unavailable");
|
|
21718
21788
|
return this.wasmBindings.computeCid(data, codec);
|
|
21719
21789
|
},
|
|
21720
|
-
// delegationManager: undefined - not needed for receive()
|
|
21721
21790
|
createKVService: (config) => {
|
|
21722
21791
|
const prefix = config.pathPrefix?.replace(/\/$/, "");
|
|
21723
21792
|
const kvService = new KVService2({ prefix });
|
|
@@ -21725,7 +21794,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21725
21794
|
invoke: config.invoke,
|
|
21726
21795
|
fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
|
|
21727
21796
|
hosts: config.hosts,
|
|
21728
|
-
telemetry: this.config.telemetry
|
|
21797
|
+
telemetry: this.config.telemetry,
|
|
21798
|
+
retryPolicy: this.config.retryPolicy
|
|
21729
21799
|
}));
|
|
21730
21800
|
kvContext.setSession(config.session);
|
|
21731
21801
|
kvService.initialize(kvContext);
|
|
@@ -21752,6 +21822,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21752
21822
|
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
21753
21823
|
tinycloudRegistryUrl: config.tinycloudRegistryUrl,
|
|
21754
21824
|
tinycloudFallbackHosts: config.tinycloudFallbackHosts,
|
|
21825
|
+
...this.registryPolicyConfig(),
|
|
21755
21826
|
autoDiscoverLocalNode: config.autoDiscoverLocalNode,
|
|
21756
21827
|
localNodeUrl: config.localNodeUrl,
|
|
21757
21828
|
localLinkName: config.localLinkName,
|
|
@@ -21775,7 +21846,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21775
21846
|
});
|
|
21776
21847
|
this.tc = new TinyCloud(this.auth, {
|
|
21777
21848
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
21778
|
-
telemetry: config.telemetry
|
|
21849
|
+
telemetry: config.telemetry,
|
|
21850
|
+
retryPolicy: config.retryPolicy
|
|
21779
21851
|
});
|
|
21780
21852
|
}
|
|
21781
21853
|
shouldUseBootstrapSignInRequest(config) {
|
|
@@ -22137,7 +22209,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22137
22209
|
this.auth = oldAuth;
|
|
22138
22210
|
this.tc = this.auth ? new TinyCloud(this.auth, {
|
|
22139
22211
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
22140
|
-
telemetry: this.config.telemetry
|
|
22212
|
+
telemetry: this.config.telemetry,
|
|
22213
|
+
retryPolicy: this.config.retryPolicy
|
|
22141
22214
|
}) : null;
|
|
22142
22215
|
this._capabilityRegistry = new CapabilityKeyRegistry();
|
|
22143
22216
|
this._keyProvider = new WasmKeyProvider({ sessionManager: this.sessionManager });
|
|
@@ -22457,6 +22530,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22457
22530
|
const primarySession = auth.tinyCloudSession;
|
|
22458
22531
|
const defaultSpaceId = this.ownedSpaceId("default");
|
|
22459
22532
|
const canReusePrimaryBootstrapSession = primarySession?.spaceId === defaultSpaceId && auth.capabilityRequest === BOOTSTRAP_SESSION_REQUESTS.default;
|
|
22533
|
+
if (steps.some((step) => step.kind === "host")) {
|
|
22534
|
+
await this.assertMayCreateSpace();
|
|
22535
|
+
}
|
|
22460
22536
|
for (const step of steps) {
|
|
22461
22537
|
if (step.kind !== "session") continue;
|
|
22462
22538
|
graph.assertActive();
|
|
@@ -22785,7 +22861,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22785
22861
|
invokeAny: context.invokeAny,
|
|
22786
22862
|
fetch: context.fetch,
|
|
22787
22863
|
hosts: context.hosts,
|
|
22788
|
-
telemetry: this.config.telemetry
|
|
22864
|
+
telemetry: this.config.telemetry,
|
|
22865
|
+
retryPolicy: this.config.retryPolicy
|
|
22789
22866
|
}));
|
|
22790
22867
|
scoped.setOperationAbortSignal(signal);
|
|
22791
22868
|
scoped.setSession({ ...session, spaceId });
|
|
@@ -22832,6 +22909,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22832
22909
|
return;
|
|
22833
22910
|
}
|
|
22834
22911
|
if (!this.currentSessionCoversAccountRegistry()) {
|
|
22912
|
+
if (!_TinyCloudNode.accountRegistrySkipLogged) {
|
|
22913
|
+
_TinyCloudNode.accountRegistrySkipLogged = true;
|
|
22914
|
+
tinyCloudDebugLogger.log("registry.skip");
|
|
22915
|
+
}
|
|
22835
22916
|
return;
|
|
22836
22917
|
}
|
|
22837
22918
|
const controller = new AbortController();
|
|
@@ -22847,7 +22928,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22847
22928
|
invokeAny: sharedContext.invokeAny,
|
|
22848
22929
|
fetch: sharedContext.fetch,
|
|
22849
22930
|
hosts: sharedContext.hosts,
|
|
22850
|
-
telemetry: this.config.telemetry
|
|
22931
|
+
telemetry: this.config.telemetry,
|
|
22932
|
+
retryPolicy: this.config.retryPolicy
|
|
22851
22933
|
}));
|
|
22852
22934
|
context.setOperationAbortSignal(controller.signal);
|
|
22853
22935
|
const current = this.currentTinyCloudSession();
|
|
@@ -23098,6 +23180,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23098
23180
|
{ cause: activation }
|
|
23099
23181
|
);
|
|
23100
23182
|
}
|
|
23183
|
+
await this.assertMayCreateSpace();
|
|
23184
|
+
if (signal?.aborted) throw signal.reason;
|
|
23101
23185
|
const created = await this.hostOwnedSpaceOnce(spaceId, signal);
|
|
23102
23186
|
if (!created.success) {
|
|
23103
23187
|
throw Object.assign(
|
|
@@ -23211,6 +23295,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23211
23295
|
* session's recap doesn't cover it and the registry has no record; the host
|
|
23212
23296
|
* SIWE is idempotent server-side. Must be called after {@link signIn}.
|
|
23213
23297
|
*
|
|
23298
|
+
* Under `registryPolicy: "fail-closed"`, hosting is refused with
|
|
23299
|
+
* `NodeRegistryEntryExistsError` when the owner's registry record does not
|
|
23300
|
+
* list the host, or `RegistryUnavailableError` when the registry gives no
|
|
23301
|
+
* verdict. {@link hostOwnedSpace} itself is an explicit action and is not
|
|
23302
|
+
* guarded.
|
|
23303
|
+
*
|
|
23214
23304
|
* @param name - The owned space name (e.g. `"secrets"`).
|
|
23215
23305
|
* @returns The hosted owned-space URI.
|
|
23216
23306
|
*/
|
|
@@ -23222,8 +23312,25 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23222
23312
|
if (this.hostedOwnedSpaceIds.has(spaceId) || await this.isOwnedSpaceRegistered(spaceId)) {
|
|
23223
23313
|
return spaceId;
|
|
23224
23314
|
}
|
|
23315
|
+
await this.assertMayCreateSpace();
|
|
23225
23316
|
return this.hostOwnedSpace(name);
|
|
23226
23317
|
}
|
|
23318
|
+
/**
|
|
23319
|
+
* Space-creation guard (TC-1443) for the automatic hosting paths: sign-in's
|
|
23320
|
+
* owned spaces, account bootstrap, {@link ensureOwnedSpaceHosted} and
|
|
23321
|
+
* {@link ensurePublicSpace}. Only `registryPolicy: "fail-closed"` consults
|
|
23322
|
+
* the registry ({@link NodeUserAuthorization.assertMayCreateSpace}); the
|
|
23323
|
+
* default policy performs no lookup.
|
|
23324
|
+
*/
|
|
23325
|
+
async assertMayCreateSpace() {
|
|
23326
|
+
if (this.config.registryPolicy !== "fail-closed") return;
|
|
23327
|
+
await this.auth.assertMayCreateSpace();
|
|
23328
|
+
}
|
|
23329
|
+
/** Registry-policy settings shared by every authorization this client creates. */
|
|
23330
|
+
registryPolicyConfig() {
|
|
23331
|
+
const { registryPolicy, newUserHost, registryChainId, registrySequenceStore, onNodeNotFound } = this.config;
|
|
23332
|
+
return { registryPolicy, newUserHost, registryChainId, registrySequenceStore, onNodeNotFound };
|
|
23333
|
+
}
|
|
23227
23334
|
/**
|
|
23228
23335
|
* Submit the host delegation for an owned space, sharing one in-flight
|
|
23229
23336
|
* request (and so one approval) between concurrent callers in this session,
|
|
@@ -23664,7 +23771,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23664
23771
|
const graph = this.createServiceGraphLifetime();
|
|
23665
23772
|
const core = this.auth ? new TinyCloud(this.auth, {
|
|
23666
23773
|
invokeAny: graph.invokeAny,
|
|
23667
|
-
telemetry: this.config.telemetry
|
|
23774
|
+
telemetry: this.config.telemetry,
|
|
23775
|
+
retryPolicy: this.config.retryPolicy
|
|
23668
23776
|
}) : null;
|
|
23669
23777
|
if (core) {
|
|
23670
23778
|
core.initializeServices(graph.invoke, [input.host], graph.fetch);
|
|
@@ -23676,7 +23784,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23676
23784
|
invokeAny: graph.invokeAny,
|
|
23677
23785
|
fetch: graph.fetch,
|
|
23678
23786
|
hosts: [input.host],
|
|
23679
|
-
telemetry: this.config.telemetry
|
|
23787
|
+
telemetry: this.config.telemetry,
|
|
23788
|
+
retryPolicy: this.config.retryPolicy
|
|
23680
23789
|
}));
|
|
23681
23790
|
const kv = new KVService2({});
|
|
23682
23791
|
kv.initialize(serviceContext);
|
|
@@ -23762,7 +23871,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23762
23871
|
invoke: config.invoke,
|
|
23763
23872
|
fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
|
|
23764
23873
|
hosts: config.hosts,
|
|
23765
|
-
telemetry: this.config.telemetry
|
|
23874
|
+
telemetry: this.config.telemetry,
|
|
23875
|
+
retryPolicy: this.config.retryPolicy
|
|
23766
23876
|
}));
|
|
23767
23877
|
context.setSession(config.session);
|
|
23768
23878
|
service.initialize(context);
|
|
@@ -23772,7 +23882,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23772
23882
|
});
|
|
23773
23883
|
sharingService.updateConfig({
|
|
23774
23884
|
session: input.serviceSession,
|
|
23775
|
-
delegationManager,
|
|
23776
23885
|
sessionExpiry: input.sessionExpiry,
|
|
23777
23886
|
createDelegationWasm: (params) => {
|
|
23778
23887
|
graph.assertActive();
|
|
@@ -23803,7 +23912,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23803
23912
|
invokeAny: graph.invokeAny,
|
|
23804
23913
|
fetch: graph.fetch,
|
|
23805
23914
|
hosts: [input.host],
|
|
23806
|
-
telemetry: this.config.telemetry
|
|
23915
|
+
telemetry: this.config.telemetry,
|
|
23916
|
+
retryPolicy: this.config.retryPolicy
|
|
23807
23917
|
}));
|
|
23808
23918
|
context.setSession({ ...input.serviceSession, spaceId });
|
|
23809
23919
|
scopedKv.initialize(context);
|
|
@@ -23818,7 +23928,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23818
23928
|
invokeAny: graph.invokeAny,
|
|
23819
23929
|
fetch: graph.fetch,
|
|
23820
23930
|
hosts: [input.host],
|
|
23821
|
-
telemetry: this.config.telemetry
|
|
23931
|
+
telemetry: this.config.telemetry,
|
|
23932
|
+
retryPolicy: this.config.retryPolicy
|
|
23822
23933
|
}));
|
|
23823
23934
|
context.setSession({ ...input.serviceSession, spaceId });
|
|
23824
23935
|
scopedKv.initialize(context);
|
|
@@ -23901,6 +24012,21 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23901
24012
|
if (address === void 0 || chainId === void 0) {
|
|
23902
24013
|
return void 0;
|
|
23903
24014
|
}
|
|
24015
|
+
if (this.config.registryPolicy === "fail-closed") {
|
|
24016
|
+
const resolved2 = await resolveFailClosedTinyCloudHosts2(address, {
|
|
24017
|
+
registryUrl: this.config.tinycloudRegistryUrl,
|
|
24018
|
+
registryChainId: this.config.registryChainId,
|
|
24019
|
+
newUserHost: this.config.newUserHost,
|
|
24020
|
+
sequenceStore: this.config.registrySequenceStore,
|
|
24021
|
+
onNodeNotFound: this.config.onNodeNotFound,
|
|
24022
|
+
autoDiscoverLocalNode: this.config.autoDiscoverLocalNode,
|
|
24023
|
+
localNodeUrl: this.config.localNodeUrl,
|
|
24024
|
+
localLinkName: this.config.localLinkName,
|
|
24025
|
+
expectedNodeDid: this.config.expectedNodeDid,
|
|
24026
|
+
localNodeIdentityStore: this.config.localNodeIdentityStore
|
|
24027
|
+
});
|
|
24028
|
+
return resolved2.hosts[0];
|
|
24029
|
+
}
|
|
23904
24030
|
const resolved = await resolveTinyCloudHosts2(pkhDid2(address, chainId), {
|
|
23905
24031
|
registryUrl: this.config.tinycloudRegistryUrl,
|
|
23906
24032
|
fallbackHosts: this.config.tinycloudFallbackHosts,
|
|
@@ -24093,6 +24219,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24093
24219
|
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
24094
24220
|
tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
|
|
24095
24221
|
tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
|
|
24222
|
+
...this.registryPolicyConfig(),
|
|
24096
24223
|
autoDiscoverLocalNode: this.config.autoDiscoverLocalNode,
|
|
24097
24224
|
localNodeUrl: this.config.localNodeUrl,
|
|
24098
24225
|
localLinkName: this.config.localLinkName,
|
|
@@ -24114,7 +24241,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24114
24241
|
});
|
|
24115
24242
|
this.tc = new TinyCloud(this.auth, {
|
|
24116
24243
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
24117
|
-
telemetry: this.config.telemetry
|
|
24244
|
+
telemetry: this.config.telemetry,
|
|
24245
|
+
retryPolicy: this.config.retryPolicy
|
|
24118
24246
|
});
|
|
24119
24247
|
this.config.prefix = prefix;
|
|
24120
24248
|
}
|
|
@@ -24152,6 +24280,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24152
24280
|
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
24153
24281
|
tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
|
|
24154
24282
|
tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
|
|
24283
|
+
...this.registryPolicyConfig(),
|
|
24155
24284
|
autoDiscoverLocalNode: this.config.autoDiscoverLocalNode,
|
|
24156
24285
|
localNodeUrl: this.config.localNodeUrl,
|
|
24157
24286
|
localLinkName: this.config.localLinkName,
|
|
@@ -24173,7 +24302,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24173
24302
|
});
|
|
24174
24303
|
this.tc = new TinyCloud(this.auth, {
|
|
24175
24304
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
24176
|
-
telemetry: this.config.telemetry
|
|
24305
|
+
telemetry: this.config.telemetry,
|
|
24306
|
+
retryPolicy: this.config.retryPolicy
|
|
24177
24307
|
});
|
|
24178
24308
|
this.config.prefix = prefix;
|
|
24179
24309
|
}
|
|
@@ -24197,7 +24327,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24197
24327
|
invokeAny: this._serviceGraph.invokeAny,
|
|
24198
24328
|
fetch: this._serviceGraph.fetch,
|
|
24199
24329
|
hosts: [this.config.host],
|
|
24200
|
-
telemetry: this.config.telemetry
|
|
24330
|
+
telemetry: this.config.telemetry,
|
|
24331
|
+
retryPolicy: this.config.retryPolicy
|
|
24201
24332
|
}));
|
|
24202
24333
|
this._kv = new KVService2({});
|
|
24203
24334
|
this._kv.initialize(this._serviceContext);
|
|
@@ -24244,7 +24375,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24244
24375
|
invokeAny: this._serviceContext.invokeAny,
|
|
24245
24376
|
fetch: this._serviceContext.fetch,
|
|
24246
24377
|
hosts: this._serviceContext.hosts,
|
|
24247
|
-
telemetry: this.config.telemetry
|
|
24378
|
+
telemetry: this.config.telemetry,
|
|
24379
|
+
retryPolicy: this.config.retryPolicy
|
|
24248
24380
|
}));
|
|
24249
24381
|
const session = this._serviceContext.session;
|
|
24250
24382
|
if (session) {
|
|
@@ -24695,7 +24827,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24695
24827
|
assertActive: () => graph.assertActive(),
|
|
24696
24828
|
keyProvider: this._keyProvider,
|
|
24697
24829
|
registry: this._capabilityRegistry,
|
|
24698
|
-
delegationManager: this._delegationManager,
|
|
24699
24830
|
sessionExpiry: this.getSessionExpiry(),
|
|
24700
24831
|
createDelegationWasm: (params) => {
|
|
24701
24832
|
graph.assertActive();
|
|
@@ -24712,7 +24843,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24712
24843
|
invoke: config.invoke,
|
|
24713
24844
|
fetch: config.fetch ?? graph.fetch,
|
|
24714
24845
|
hosts: config.hosts,
|
|
24715
|
-
telemetry: this.config.telemetry
|
|
24846
|
+
telemetry: this.config.telemetry,
|
|
24847
|
+
retryPolicy: this.config.retryPolicy
|
|
24716
24848
|
}));
|
|
24717
24849
|
context.setSession(config.session);
|
|
24718
24850
|
service.initialize(context);
|
|
@@ -25033,7 +25165,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25033
25165
|
invokeAny: this._serviceContext.invokeAny,
|
|
25034
25166
|
fetch: this._serviceContext.fetch,
|
|
25035
25167
|
hosts: this._serviceContext.hosts,
|
|
25036
|
-
telemetry: this.config.telemetry
|
|
25168
|
+
telemetry: this.config.telemetry,
|
|
25169
|
+
retryPolicy: this.config.retryPolicy
|
|
25037
25170
|
}));
|
|
25038
25171
|
spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
|
|
25039
25172
|
sql.initialize(spaceScopedContext);
|
|
@@ -25236,6 +25369,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25236
25369
|
}
|
|
25237
25370
|
};
|
|
25238
25371
|
}
|
|
25372
|
+
if (result.status === "aad_mismatch") return { status: "read_failed" };
|
|
25239
25373
|
return { status: result.status };
|
|
25240
25374
|
}
|
|
25241
25375
|
if (!isSecretPayload(result.entry.value)) {
|
|
@@ -25677,16 +25811,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25677
25811
|
* ```typescript
|
|
25678
25812
|
* const delegations = alice.delegationManager;
|
|
25679
25813
|
*
|
|
25680
|
-
* //
|
|
25681
|
-
* const
|
|
25682
|
-
* delegateDID: bob.did,
|
|
25683
|
-
* path: "shared/",
|
|
25684
|
-
* actions: ["tinycloud.kv/get", "tinycloud.kv/put"],
|
|
25685
|
-
* expiry: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours
|
|
25686
|
-
* });
|
|
25687
|
-
*
|
|
25688
|
-
* // List delegations
|
|
25689
|
-
* const listResult = await delegations.list();
|
|
25814
|
+
* // Query account delegations
|
|
25815
|
+
* const page = await delegations.query();
|
|
25690
25816
|
*
|
|
25691
25817
|
* // Revoke a delegation
|
|
25692
25818
|
* await delegations.revoke(delegationCid);
|
|
@@ -25788,7 +25914,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25788
25914
|
* Ensure the user's public space exists and is accessible.
|
|
25789
25915
|
* Creates the space and activates a session delegation for it.
|
|
25790
25916
|
* This is the trigger for lazy public space creation — call it
|
|
25791
|
-
* before writing to spaces.get('public').kv.
|
|
25917
|
+
* before writing to spaces.get('public').kv. The vault calls it on unlock.
|
|
25918
|
+
* Under `registryPolicy: "fail-closed"` creation goes through the
|
|
25919
|
+
* space-creation guard.
|
|
25792
25920
|
*/
|
|
25793
25921
|
async ensurePublicSpace() {
|
|
25794
25922
|
if (!this.auth || !this.session || !this.signer) {
|
|
@@ -25798,6 +25926,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25798
25926
|
if (!publicSpaceId) {
|
|
25799
25927
|
throw new Error("Public space not enabled. Set enablePublicSpace: true in config.");
|
|
25800
25928
|
}
|
|
25929
|
+
await this.assertMayCreateSpace();
|
|
25801
25930
|
await this.auth.hostPublicSpace(publicSpaceId);
|
|
25802
25931
|
const kvActions = [KV3.PUT, KV3.GET, KV3.DEL, KV3.LIST, KV3.METADATA];
|
|
25803
25932
|
const abilities = { kv: { "": kvActions } };
|
|
@@ -25855,7 +25984,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25855
25984
|
invoke: this._serviceGraph.invoke,
|
|
25856
25985
|
fetch: this._serviceGraph.fetch,
|
|
25857
25986
|
hosts: this._serviceContext.hosts,
|
|
25858
|
-
telemetry: this.config.telemetry
|
|
25987
|
+
telemetry: this.config.telemetry,
|
|
25988
|
+
retryPolicy: this.config.retryPolicy
|
|
25859
25989
|
}));
|
|
25860
25990
|
publicContext.setSession({
|
|
25861
25991
|
delegationHeader: delegationSession.delegationHeader,
|
|
@@ -25884,32 +26014,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25884
26014
|
// ===========================================================================
|
|
25885
26015
|
// v2 Delegation Convenience Methods
|
|
25886
26016
|
// ===========================================================================
|
|
25887
|
-
/**
|
|
25888
|
-
* Create a delegation using the v2 DelegationManager.
|
|
25889
|
-
*
|
|
25890
|
-
* This is a convenience method that wraps DelegationManager.create().
|
|
25891
|
-
* For more control, use `this.delegationManager` directly.
|
|
25892
|
-
*
|
|
25893
|
-
* @param params - Delegation parameters
|
|
25894
|
-
* @returns Result containing the created Delegation
|
|
25895
|
-
*
|
|
25896
|
-
* @example
|
|
25897
|
-
* ```typescript
|
|
25898
|
-
* const result = await alice.delegate({
|
|
25899
|
-
* delegateDID: bob.did,
|
|
25900
|
-
* path: "shared/",
|
|
25901
|
-
* actions: ["tinycloud.kv/get", "tinycloud.kv/put"],
|
|
25902
|
-
* expiry: new Date(Date.now() + 24 * 60 * 60 * 1000),
|
|
25903
|
-
* });
|
|
25904
|
-
*
|
|
25905
|
-
* if (result.ok) {
|
|
25906
|
-
* console.log("Delegation created:", result.data.cid);
|
|
25907
|
-
* }
|
|
25908
|
-
* ```
|
|
25909
|
-
*/
|
|
25910
|
-
async delegate(params) {
|
|
25911
|
-
return this.delegationManager.create(params);
|
|
25912
|
-
}
|
|
25913
26017
|
/**
|
|
25914
26018
|
* Revoke a delegation with the owner wallet when available. Session-only
|
|
25915
26019
|
* clients continue to use their delegated revocation authority.
|
|
@@ -25935,14 +26039,6 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25935
26039
|
0x55n
|
|
25936
26040
|
);
|
|
25937
26041
|
}
|
|
25938
|
-
/**
|
|
25939
|
-
* List all delegations for the current session's space.
|
|
25940
|
-
*
|
|
25941
|
-
* @returns Result containing an array of Delegations
|
|
25942
|
-
*/
|
|
25943
|
-
async listDelegations() {
|
|
25944
|
-
return this.delegationManager.list();
|
|
25945
|
-
}
|
|
25946
26042
|
/**
|
|
25947
26043
|
* Check if the current session has permission for a path and action.
|
|
25948
26044
|
*
|
|
@@ -26002,6 +26098,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26002
26098
|
"delegateTo: onPrepared cannot be combined with forceWalletSign=true; the wallet-signed path activates the delegation before it could be handed to onPrepared."
|
|
26003
26099
|
);
|
|
26004
26100
|
}
|
|
26101
|
+
if (options?.disableSubDelegation && did.startsWith("did:pkh:")) {
|
|
26102
|
+
throw new Error(TERMINAL_DELEGATION_REQUIRES_SESSION_KEY);
|
|
26103
|
+
}
|
|
26005
26104
|
const session = this.currentTinyCloudSession();
|
|
26006
26105
|
if (!session) {
|
|
26007
26106
|
throw new SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
@@ -26067,7 +26166,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26067
26166
|
plan.grant,
|
|
26068
26167
|
plan.operations,
|
|
26069
26168
|
onPrepared,
|
|
26070
|
-
options?.disableSubDelegation === true
|
|
26169
|
+
options?.disableSubDelegation === true,
|
|
26170
|
+
options?.requireActivation === true
|
|
26071
26171
|
);
|
|
26072
26172
|
return { delegation: delegation2, prompted: false };
|
|
26073
26173
|
}
|
|
@@ -26077,7 +26177,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26077
26177
|
effectiveExpiration,
|
|
26078
26178
|
session,
|
|
26079
26179
|
onPrepared,
|
|
26080
|
-
options?.disableSubDelegation === true
|
|
26180
|
+
options?.disableSubDelegation === true,
|
|
26181
|
+
options?.requireActivation === true
|
|
26081
26182
|
);
|
|
26082
26183
|
return { delegation, prompted: false };
|
|
26083
26184
|
}
|
|
@@ -26308,7 +26409,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26308
26409
|
*
|
|
26309
26410
|
* @internal
|
|
26310
26411
|
*/
|
|
26311
|
-
async createDelegationViaWasmPath(did, entries, expirationTime, session, onPrepared, disableSubDelegation = false) {
|
|
26412
|
+
async createDelegationViaWasmPath(did, entries, expirationTime, session, onPrepared, disableSubDelegation = false, requireActivation = false) {
|
|
26312
26413
|
if (entries.length === 0) {
|
|
26313
26414
|
throw new Error(
|
|
26314
26415
|
"createDelegationViaWasmPath requires a non-empty entries array"
|
|
@@ -26392,15 +26493,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26392
26493
|
this.config.host,
|
|
26393
26494
|
delegationHeader
|
|
26394
26495
|
);
|
|
26395
|
-
|
|
26396
|
-
throw Object.assign(
|
|
26397
|
-
new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
|
|
26398
|
-
{ cause: activateResult }
|
|
26399
|
-
);
|
|
26400
|
-
}
|
|
26496
|
+
assertDelegationActivated(activateResult, delegation, requireActivation);
|
|
26401
26497
|
return delegation;
|
|
26402
26498
|
}
|
|
26403
|
-
async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant, requestedOperations, onPrepared, disableSubDelegation = false) {
|
|
26499
|
+
async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant, requestedOperations, onPrepared, disableSubDelegation = false, requireActivation = false) {
|
|
26404
26500
|
this.assertRuntimeGrantCaveatsPreservable(entries, requestedOperations, grant);
|
|
26405
26501
|
this.assertDelegationCaveatsPreservable(entries);
|
|
26406
26502
|
const result = this.createDelegationWrapper({
|
|
@@ -26434,12 +26530,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
26434
26530
|
targetHost,
|
|
26435
26531
|
delegationHeader
|
|
26436
26532
|
);
|
|
26437
|
-
|
|
26438
|
-
throw Object.assign(
|
|
26439
|
-
new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
|
|
26440
|
-
{ cause: activateResult }
|
|
26441
|
-
);
|
|
26442
|
-
}
|
|
26533
|
+
assertDelegationActivated(activateResult, delegation, requireActivation);
|
|
26443
26534
|
return delegation;
|
|
26444
26535
|
}
|
|
26445
26536
|
resolvePermissionSpace(space, session) {
|
|
@@ -27386,6 +27477,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
27386
27477
|
};
|
|
27387
27478
|
}
|
|
27388
27479
|
};
|
|
27480
|
+
/** Set once per process: the registry sync was skipped for want of account access. */
|
|
27481
|
+
_TinyCloudNode.accountRegistrySkipLogged = false;
|
|
27389
27482
|
// ===========================================================================
|
|
27390
27483
|
// Capability-chain delegation (spec: .claude/specs/capability-chain.md)
|
|
27391
27484
|
// ===========================================================================
|
|
@@ -27440,7 +27533,7 @@ import {
|
|
|
27440
27533
|
principalDidEquals as principalDidEquals4,
|
|
27441
27534
|
parseCanonicalNetworkId,
|
|
27442
27535
|
TinyCloudDebugLogger,
|
|
27443
|
-
tinyCloudDebugLogger,
|
|
27536
|
+
tinyCloudDebugLogger as tinyCloudDebugLogger2,
|
|
27444
27537
|
enableTinyCloudDebug,
|
|
27445
27538
|
disableTinyCloudDebug,
|
|
27446
27539
|
getTinyCloudDebugLogs,
|
|
@@ -28945,6 +29038,34 @@ assertSyncEffective_fn = async function() {
|
|
|
28945
29038
|
throw new ReplicaStorageError("GRANT_EXPIRED", "The replica grant's effective lifetime has expired.");
|
|
28946
29039
|
}
|
|
28947
29040
|
};
|
|
29041
|
+
async function listDir(dir) {
|
|
29042
|
+
try {
|
|
29043
|
+
return await readdir(dir);
|
|
29044
|
+
} catch (error) {
|
|
29045
|
+
if (error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
|
|
29046
|
+
return [];
|
|
29047
|
+
}
|
|
29048
|
+
throw error;
|
|
29049
|
+
}
|
|
29050
|
+
}
|
|
29051
|
+
async function collectProfileOrphans(root, collectOrphans) {
|
|
29052
|
+
for (const partition of await listDir(root)) {
|
|
29053
|
+
const replicasDir = join2(root, partition, "replicas");
|
|
29054
|
+
for (const replicaName of await listDir(replicasDir)) {
|
|
29055
|
+
await collectOrphans(join2(replicasDir, replicaName));
|
|
29056
|
+
}
|
|
29057
|
+
}
|
|
29058
|
+
}
|
|
29059
|
+
async function profileContentBytes(root, contentBytes) {
|
|
29060
|
+
let total = 0;
|
|
29061
|
+
for (const partition of await listDir(root)) {
|
|
29062
|
+
const replicasDir = join2(root, partition, "replicas");
|
|
29063
|
+
for (const replicaName of await listDir(replicasDir)) {
|
|
29064
|
+
total += await contentBytes(join2(replicasDir, replicaName));
|
|
29065
|
+
}
|
|
29066
|
+
}
|
|
29067
|
+
return total;
|
|
29068
|
+
}
|
|
28948
29069
|
function createSqliteReplicaStorage(options) {
|
|
28949
29070
|
const root = options.dir;
|
|
28950
29071
|
const profileDir = dirname2(options.gateFile ?? join2(dirname2(root), REPLICA_GATE_FILE));
|
|
@@ -29939,10 +30060,29 @@ function createSqliteReplicaStorage(options) {
|
|
|
29939
30060
|
const replicaHash = replicaHashOf(spec.prefix, device.did);
|
|
29940
30061
|
partitionId = `${identityKeyHash}:${replicaHash}`;
|
|
29941
30062
|
const replicaDir = join2(idDir, "replicas", replicaHash);
|
|
29942
|
-
const
|
|
29943
|
-
|
|
29944
|
-
|
|
29945
|
-
}
|
|
30063
|
+
const quota = spec.quota?.maxBytes ?? options.maxBytes;
|
|
30064
|
+
if (quota !== void 0 && (!Number.isSafeInteger(quota) || quota < 0)) {
|
|
30065
|
+
throw new TypeError(`maxBytes must be a non-negative safe integer, got ${quota}.`);
|
|
30066
|
+
}
|
|
30067
|
+
if (quota !== void 0) await collectProfileOrphans(root, sqlite.SqliteReplicaStore.collectOrphans);
|
|
30068
|
+
const store = await sqlite.SqliteReplicaStore.open(
|
|
30069
|
+
replicaDir,
|
|
30070
|
+
quota === void 0 ? { create: true, guard: storeGuard } : {
|
|
30071
|
+
create: true,
|
|
30072
|
+
guard: storeGuard,
|
|
30073
|
+
partitionId: basename(idDir),
|
|
30074
|
+
admit: async (page) => {
|
|
30075
|
+
await collectProfileOrphans(root, sqlite.SqliteReplicaStore.collectOrphans);
|
|
30076
|
+
const used = await profileContentBytes(root, sqlite.SqliteReplicaStore.contentBytes);
|
|
30077
|
+
if (page.blobBytes > 0 && used + page.blobBytes > quota) {
|
|
30078
|
+
throw new replica.ReplicaError(
|
|
30079
|
+
replica.ReplicaErrorCode.STORAGE_BUDGET,
|
|
30080
|
+
`Profile storage holds ${used} bytes; this page adds ${page.blobBytes} against a ${quota}-byte quota. Nothing was committed.`
|
|
30081
|
+
);
|
|
30082
|
+
}
|
|
30083
|
+
}
|
|
30084
|
+
}
|
|
30085
|
+
);
|
|
29946
30086
|
let generation;
|
|
29947
30087
|
try {
|
|
29948
30088
|
try {
|
|
@@ -30369,7 +30509,7 @@ export {
|
|
|
30369
30509
|
siweRuntimeDelegation,
|
|
30370
30510
|
sqliteReplicaStorage,
|
|
30371
30511
|
storageUsageState,
|
|
30372
|
-
tinyCloudDebugLogger,
|
|
30512
|
+
tinyCloudDebugLogger2 as tinyCloudDebugLogger,
|
|
30373
30513
|
validateEnvelope,
|
|
30374
30514
|
validateManifest,
|
|
30375
30515
|
verifyDecryptResponse,
|