@tinycloud/node-sdk 3.7.0-beta.1 → 3.7.0-beta.3
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-BHiKCQ4W.d.ts → TinyCloudNode-Cw00iiSP.d.ts} +28 -5
- package/dist/{TinyCloudNode-DrLNh4bs.d.cts → TinyCloudNode-DD7qjyLU.d.cts} +28 -5
- package/dist/{authority-BVmX2vCi.d.cts → authority-Ck5hZdBn.d.cts} +1 -1
- package/dist/{authority-BHVqCPyl.d.ts → authority-DXR6887E.d.ts} +1 -1
- package/dist/core.cjs +72 -28
- 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 +72 -28
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +72 -28
- 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 +72 -28
- 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
|
@@ -1400,14 +1400,30 @@ declare class TinyCloudNode {
|
|
|
1400
1400
|
*/
|
|
1401
1401
|
private readonly storageFull;
|
|
1402
1402
|
/**
|
|
1403
|
-
* Subscribe to `storage.full`. It fires
|
|
1404
|
-
*
|
|
1403
|
+
* Subscribe to `storage.full`. It fires on the first write any service had
|
|
1404
|
+
* rejected because the owner's TinyCloud storage is full
|
|
1405
1405
|
* (`STORAGE_QUOTA_EXCEEDED` or `STORAGE_LIMIT_REACHED`), so an app can show
|
|
1406
|
-
* one read-only banner. Reads keep working.
|
|
1407
|
-
*
|
|
1408
|
-
*
|
|
1406
|
+
* one read-only banner. Reads keep working. For the signed-in account's own
|
|
1407
|
+
* storage it fires once per episode: the episode ends only when a write to
|
|
1408
|
+
* that storage succeeds, or on sign-out. A `storage.status()` read does not
|
|
1409
|
+
* end it. A rejection on another owner's delegated space fires once per
|
|
1410
|
+
* owner, until that owner's `storage.status()` reports space again. Returns
|
|
1411
|
+
* the unsubscribe function.
|
|
1409
1412
|
*/
|
|
1410
1413
|
on(event: "storage.full", handler: (event: StorageFullEvent) => void): () => void;
|
|
1414
|
+
/**
|
|
1415
|
+
* Storage episode state for the UI mount. @internal
|
|
1416
|
+
*
|
|
1417
|
+
* `current()` returns the own-storage rejection that started the episode, or
|
|
1418
|
+
* undefined. `subscribe` calls its listener when the own episode starts or
|
|
1419
|
+
* ends; read `current()` inside it. `subscribeDelegated` calls its listener
|
|
1420
|
+
* once per delegated owner found full, until that owner is cleared.
|
|
1421
|
+
*/
|
|
1422
|
+
get storageEpisode(): {
|
|
1423
|
+
current(): StorageFullEvent | undefined;
|
|
1424
|
+
subscribe(listener: () => void): () => void;
|
|
1425
|
+
subscribeDelegated(listener: () => void): () => void;
|
|
1426
|
+
};
|
|
1411
1427
|
/** Owner key of the account the current session's own storage belongs to. */
|
|
1412
1428
|
private currentStorageOwner;
|
|
1413
1429
|
/**
|
|
@@ -1435,6 +1451,13 @@ declare class TinyCloudNode {
|
|
|
1435
1451
|
/** SIWE domain — uses config override or defaults to app.tinycloud.xyz */
|
|
1436
1452
|
private get siweDomain();
|
|
1437
1453
|
private readonly invokeWithRuntimePermissions;
|
|
1454
|
+
/**
|
|
1455
|
+
* The session (key, issuer, proof) that signs an invokeAny call for `entries`:
|
|
1456
|
+
* the explicit revocation authority, else the covering non-primary runtime
|
|
1457
|
+
* grant, else the caller's session. Everything that re-signs the resulting
|
|
1458
|
+
* invocation must use this session's key.
|
|
1459
|
+
*/
|
|
1460
|
+
private selectInvokeAnySession;
|
|
1438
1461
|
private readonly invokeAnyWithRuntimePermissions;
|
|
1439
1462
|
/**
|
|
1440
1463
|
* Create a new TinyCloudNode instance.
|
|
@@ -1400,14 +1400,30 @@ declare class TinyCloudNode {
|
|
|
1400
1400
|
*/
|
|
1401
1401
|
private readonly storageFull;
|
|
1402
1402
|
/**
|
|
1403
|
-
* Subscribe to `storage.full`. It fires
|
|
1404
|
-
*
|
|
1403
|
+
* Subscribe to `storage.full`. It fires on the first write any service had
|
|
1404
|
+
* rejected because the owner's TinyCloud storage is full
|
|
1405
1405
|
* (`STORAGE_QUOTA_EXCEEDED` or `STORAGE_LIMIT_REACHED`), so an app can show
|
|
1406
|
-
* one read-only banner. Reads keep working.
|
|
1407
|
-
*
|
|
1408
|
-
*
|
|
1406
|
+
* one read-only banner. Reads keep working. For the signed-in account's own
|
|
1407
|
+
* storage it fires once per episode: the episode ends only when a write to
|
|
1408
|
+
* that storage succeeds, or on sign-out. A `storage.status()` read does not
|
|
1409
|
+
* end it. A rejection on another owner's delegated space fires once per
|
|
1410
|
+
* owner, until that owner's `storage.status()` reports space again. Returns
|
|
1411
|
+
* the unsubscribe function.
|
|
1409
1412
|
*/
|
|
1410
1413
|
on(event: "storage.full", handler: (event: StorageFullEvent) => void): () => void;
|
|
1414
|
+
/**
|
|
1415
|
+
* Storage episode state for the UI mount. @internal
|
|
1416
|
+
*
|
|
1417
|
+
* `current()` returns the own-storage rejection that started the episode, or
|
|
1418
|
+
* undefined. `subscribe` calls its listener when the own episode starts or
|
|
1419
|
+
* ends; read `current()` inside it. `subscribeDelegated` calls its listener
|
|
1420
|
+
* once per delegated owner found full, until that owner is cleared.
|
|
1421
|
+
*/
|
|
1422
|
+
get storageEpisode(): {
|
|
1423
|
+
current(): StorageFullEvent | undefined;
|
|
1424
|
+
subscribe(listener: () => void): () => void;
|
|
1425
|
+
subscribeDelegated(listener: () => void): () => void;
|
|
1426
|
+
};
|
|
1411
1427
|
/** Owner key of the account the current session's own storage belongs to. */
|
|
1412
1428
|
private currentStorageOwner;
|
|
1413
1429
|
/**
|
|
@@ -1435,6 +1451,13 @@ declare class TinyCloudNode {
|
|
|
1435
1451
|
/** SIWE domain — uses config override or defaults to app.tinycloud.xyz */
|
|
1436
1452
|
private get siweDomain();
|
|
1437
1453
|
private readonly invokeWithRuntimePermissions;
|
|
1454
|
+
/**
|
|
1455
|
+
* The session (key, issuer, proof) that signs an invokeAny call for `entries`:
|
|
1456
|
+
* the explicit revocation authority, else the covering non-primary runtime
|
|
1457
|
+
* grant, else the caller's session. Everything that re-signs the resulting
|
|
1458
|
+
* invocation must use this session's key.
|
|
1459
|
+
*/
|
|
1460
|
+
private selectInvokeAnySession;
|
|
1438
1461
|
private readonly invokeAnyWithRuntimePermissions;
|
|
1439
1462
|
/**
|
|
1440
1463
|
* Create a new TinyCloudNode instance.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReplicationOptions, PermissionEntry, TinyCloudSession, KVReplicaStorage, ServiceContext, IWasmBindings, WasmRecapEntry } from '@tinycloud/sdk-core';
|
|
2
2
|
import { ReplicaConsentAnchor, AuthorityRefusal, ReplicationAuthority } from '@tinycloud/sdk-services';
|
|
3
3
|
import { ReplicaSessionStamp, ReplicaDenyInput } from '@tinycloud/sdk-services/kv/replication';
|
|
4
|
-
import { T as TinyCloudNode } from './TinyCloudNode-
|
|
4
|
+
import { T as TinyCloudNode } from './TinyCloudNode-DD7qjyLU.cjs';
|
|
5
5
|
|
|
6
6
|
/** Constructor-time validation; the space-dependent secrets check runs at sign-in and open. */
|
|
7
7
|
declare function assertValidReplicationConfig(replication: (ReplicationOptions & {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReplicationOptions, PermissionEntry, TinyCloudSession, KVReplicaStorage, ServiceContext, IWasmBindings, WasmRecapEntry } from '@tinycloud/sdk-core';
|
|
2
2
|
import { ReplicaConsentAnchor, AuthorityRefusal, ReplicationAuthority } from '@tinycloud/sdk-services';
|
|
3
3
|
import { ReplicaSessionStamp, ReplicaDenyInput } from '@tinycloud/sdk-services/kv/replication';
|
|
4
|
-
import { T as TinyCloudNode } from './TinyCloudNode-
|
|
4
|
+
import { T as TinyCloudNode } from './TinyCloudNode-Cw00iiSP.js';
|
|
5
5
|
|
|
6
6
|
/** Constructor-time validation; the space-dependent secrets check runs at sign-in and open. */
|
|
7
7
|
declare function assertValidReplicationConfig(replication: (ReplicationOptions & {
|
package/dist/core.cjs
CHANGED
|
@@ -3854,7 +3854,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3854
3854
|
* and remembers whose storage is full so sign-in and listing skip their
|
|
3855
3855
|
* best-effort writes. Lives as long as this instance, across sign-ins.
|
|
3856
3856
|
*/
|
|
3857
|
-
this.storageFull = new import_sdk_core11.StorageFullMonitor(
|
|
3857
|
+
this.storageFull = new import_sdk_core11.StorageFullMonitor(
|
|
3858
|
+
(spaceId) => spaceOwnerKey(spaceId) ?? spaceId,
|
|
3859
|
+
() => this.currentStorageOwner()
|
|
3860
|
+
);
|
|
3858
3861
|
this.invokeWithRuntimePermissions = (session, service, path, action, facts) => {
|
|
3859
3862
|
const operation = {
|
|
3860
3863
|
spaceId: session.spaceId,
|
|
@@ -3886,17 +3889,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3886
3889
|
throw new Error("WASM binding does not support invokeAny");
|
|
3887
3890
|
}
|
|
3888
3891
|
const routedEntries = entries;
|
|
3889
|
-
const
|
|
3890
|
-
const operation = this.operationFromInvokeAnyEntry(entry);
|
|
3891
|
-
return operation ? [operation] : [];
|
|
3892
|
-
});
|
|
3893
|
-
const authorityCid = routedEntries.length === 1 ? routedEntries[0]?.revokeAuthorityCid : void 0;
|
|
3894
|
-
const explicitGrant = authorityCid === void 0 ? void 0 : this.runtimePermissionGrants.find((grant2) => grant2.delegation.cid === authorityCid);
|
|
3895
|
-
if (authorityCid !== void 0 && !explicitGrant) {
|
|
3896
|
-
throw new Error(`Explicit revocation authority ${authorityCid} is not installed.`);
|
|
3897
|
-
}
|
|
3898
|
-
const grant = explicitGrant ?? this.findGrantForOperations(operations);
|
|
3899
|
-
const invocationSession = explicitGrant ? explicitGrant.session : !grant || grant.provenance === "primary" ? session : grant.session;
|
|
3892
|
+
const { session: invocationSession, grant } = this.selectInvokeAnySession(session, entries);
|
|
3900
3893
|
const caveatPreservingEntries = routedEntries.map(({ revokeAuthorityCid: _cid, ...entry }) => {
|
|
3901
3894
|
const requested = this.operationFromInvokeAnyEntry(entry);
|
|
3902
3895
|
const granted = grant && requested && grant.operations.find(
|
|
@@ -4020,12 +4013,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4020
4013
|
return this._bootstrapStatus;
|
|
4021
4014
|
}
|
|
4022
4015
|
/**
|
|
4023
|
-
* Subscribe to `storage.full`. It fires
|
|
4024
|
-
*
|
|
4016
|
+
* Subscribe to `storage.full`. It fires on the first write any service had
|
|
4017
|
+
* rejected because the owner's TinyCloud storage is full
|
|
4025
4018
|
* (`STORAGE_QUOTA_EXCEEDED` or `STORAGE_LIMIT_REACHED`), so an app can show
|
|
4026
|
-
* one read-only banner. Reads keep working.
|
|
4027
|
-
*
|
|
4028
|
-
*
|
|
4019
|
+
* one read-only banner. Reads keep working. For the signed-in account's own
|
|
4020
|
+
* storage it fires once per episode: the episode ends only when a write to
|
|
4021
|
+
* that storage succeeds, or on sign-out. A `storage.status()` read does not
|
|
4022
|
+
* end it. A rejection on another owner's delegated space fires once per
|
|
4023
|
+
* owner, until that owner's `storage.status()` reports space again. Returns
|
|
4024
|
+
* the unsubscribe function.
|
|
4029
4025
|
*/
|
|
4030
4026
|
on(event, handler) {
|
|
4031
4027
|
if (event !== "storage.full") {
|
|
@@ -4033,6 +4029,21 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4033
4029
|
}
|
|
4034
4030
|
return this.storageFull.on(handler);
|
|
4035
4031
|
}
|
|
4032
|
+
/**
|
|
4033
|
+
* Storage episode state for the UI mount. @internal
|
|
4034
|
+
*
|
|
4035
|
+
* `current()` returns the own-storage rejection that started the episode, or
|
|
4036
|
+
* undefined. `subscribe` calls its listener when the own episode starts or
|
|
4037
|
+
* ends; read `current()` inside it. `subscribeDelegated` calls its listener
|
|
4038
|
+
* once per delegated owner found full, until that owner is cleared.
|
|
4039
|
+
*/
|
|
4040
|
+
get storageEpisode() {
|
|
4041
|
+
return {
|
|
4042
|
+
current: () => this.storageFull.rejection,
|
|
4043
|
+
subscribe: (listener) => this.storageFull.onEpisode(listener),
|
|
4044
|
+
subscribeDelegated: (listener) => this.storageFull.onDelegated(listener)
|
|
4045
|
+
};
|
|
4046
|
+
}
|
|
4036
4047
|
/** Owner key of the account the current session's own storage belongs to. */
|
|
4037
4048
|
currentStorageOwner() {
|
|
4038
4049
|
return spaceOwnerKey(this._serviceContext?.session?.spaceId ?? this.currentTinyCloudSession()?.spaceId);
|
|
@@ -4134,6 +4145,27 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4134
4145
|
get siweDomain() {
|
|
4135
4146
|
return this.config.domain ?? "app.tinycloud.xyz";
|
|
4136
4147
|
}
|
|
4148
|
+
/**
|
|
4149
|
+
* The session (key, issuer, proof) that signs an invokeAny call for `entries`:
|
|
4150
|
+
* the explicit revocation authority, else the covering non-primary runtime
|
|
4151
|
+
* grant, else the caller's session. Everything that re-signs the resulting
|
|
4152
|
+
* invocation must use this session's key.
|
|
4153
|
+
*/
|
|
4154
|
+
selectInvokeAnySession(session, entries) {
|
|
4155
|
+
const routedEntries = entries;
|
|
4156
|
+
const operations = routedEntries.flatMap((entry) => {
|
|
4157
|
+
const operation = this.operationFromInvokeAnyEntry(entry);
|
|
4158
|
+
return operation ? [operation] : [];
|
|
4159
|
+
});
|
|
4160
|
+
const authorityCid = routedEntries.length === 1 ? routedEntries[0]?.revokeAuthorityCid : void 0;
|
|
4161
|
+
const explicitGrant = authorityCid === void 0 ? void 0 : this.runtimePermissionGrants.find((grant2) => grant2.delegation.cid === authorityCid);
|
|
4162
|
+
if (authorityCid !== void 0 && !explicitGrant) {
|
|
4163
|
+
throw new Error(`Explicit revocation authority ${authorityCid} is not installed.`);
|
|
4164
|
+
}
|
|
4165
|
+
const grant = explicitGrant ?? this.findGrantForOperations(operations);
|
|
4166
|
+
const invocationSession = explicitGrant ? explicitGrant.session : !grant || grant.provenance === "primary" ? session : grant.session;
|
|
4167
|
+
return { session: invocationSession, grant };
|
|
4168
|
+
}
|
|
4137
4169
|
/**
|
|
4138
4170
|
* SharingService for receive-only access (no session required), bound to the
|
|
4139
4171
|
* current service graph. This lets session-only users receive sharing links
|
|
@@ -6553,7 +6585,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6553
6585
|
async bindInvocationAudience(authorization, audience) {
|
|
6554
6586
|
const session = this.currentTinyCloudSession() ?? this._activeServiceSession;
|
|
6555
6587
|
if (session === void 0) throw new Error("Not signed in. Call signIn() first.");
|
|
6556
|
-
|
|
6588
|
+
const payload = JSON.parse(
|
|
6589
|
+
new TextDecoder().decode(base64UrlDecode(authorization.split(".")[1] ?? ""))
|
|
6590
|
+
);
|
|
6591
|
+
const did = (value) => String(value).split("#", 1)[0];
|
|
6592
|
+
const signer = [session, ...this.runtimePermissionGrants.map((grant) => grant.session)].find((candidate) => did(candidate.verificationMethod) === did(payload.iss));
|
|
6593
|
+
if (!signer) throw new Error("invocation issuer does not match a held session");
|
|
6594
|
+
return rewriteInvocationAudience(authorization, audience, signer.jwk);
|
|
6557
6595
|
}
|
|
6558
6596
|
/**
|
|
6559
6597
|
* Connect a wallet to upgrade from session-only mode to wallet mode.
|
|
@@ -6888,23 +6926,25 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6888
6926
|
throw new Error("WASM binding does not support invocation CID computation");
|
|
6889
6927
|
}
|
|
6890
6928
|
const session = binding?.session ?? this.requireEncryptionSession();
|
|
6929
|
+
const entries = [
|
|
6930
|
+
{
|
|
6931
|
+
resource: input.networkId,
|
|
6932
|
+
service: "encryption",
|
|
6933
|
+
path: input.networkId,
|
|
6934
|
+
action: input.action
|
|
6935
|
+
}
|
|
6936
|
+
];
|
|
6891
6937
|
const headers = this.invokeAnyWithRuntimePermissions(
|
|
6892
6938
|
session,
|
|
6893
|
-
|
|
6894
|
-
{
|
|
6895
|
-
resource: input.networkId,
|
|
6896
|
-
service: "encryption",
|
|
6897
|
-
path: input.networkId,
|
|
6898
|
-
action: input.action
|
|
6899
|
-
}
|
|
6900
|
-
],
|
|
6939
|
+
entries,
|
|
6901
6940
|
[input.facts]
|
|
6902
6941
|
);
|
|
6942
|
+
const signingSession = this.selectInvokeAnySession(session, entries).session;
|
|
6903
6943
|
const authorization = authorizationHeader(headers);
|
|
6904
6944
|
const audienceBound = await rewriteInvocationAudience(
|
|
6905
6945
|
authorization,
|
|
6906
6946
|
input.targetNode,
|
|
6907
|
-
|
|
6947
|
+
signingSession.jwk
|
|
6908
6948
|
);
|
|
6909
6949
|
binding?.graph.assertActive();
|
|
6910
6950
|
return {
|
|
@@ -6957,7 +6997,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6957
6997
|
path: networkId,
|
|
6958
6998
|
actions: ["tinycloud.encryption/decrypt"]
|
|
6959
6999
|
}) : void 0;
|
|
6960
|
-
throw new import_sdk_core11.DecryptTransportResponseError(
|
|
7000
|
+
throw new import_sdk_core11.DecryptTransportResponseError(
|
|
7001
|
+
response.status,
|
|
7002
|
+
permissionHint,
|
|
7003
|
+
response.status === 404 && networkId === this.getDefaultEncryptionNetworkId() && await response.text().catch(() => "") === "network not found" ? `Network not found: ${networkId}. Sign in again with a current SDK to create the account's encryption network.` : void 0
|
|
7004
|
+
);
|
|
6961
7005
|
}
|
|
6962
7006
|
return await response.json();
|
|
6963
7007
|
}
|