@tinycloud/node-sdk 3.8.0-beta.1 → 3.8.0-beta.2
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-Ckqu_fqH.d.ts → TinyCloudNode-B6VOBrCb.d.ts} +14 -1
- package/dist/{TinyCloudNode-DDfx8Fx5.d.cts → TinyCloudNode-CVO41O12.d.cts} +14 -1
- package/dist/{authority-DcyJpajL.d.ts → authority-DGi1hIMK.d.ts} +20 -4
- package/dist/{authority-BwM_s3Ya.d.cts → authority-DgVV80bI.d.cts} +20 -4
- package/dist/core.cjs +47 -13
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +3 -3
- package/dist/core.d.ts +3 -3
- package/dist/core.js +47 -13
- package/dist/core.js.map +1 -1
- package/dist/encryption-keys.d.cts +1 -1
- package/dist/encryption-keys.d.ts +1 -1
- package/dist/index.cjs +83 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +83 -14
- package/dist/index.js.map +1 -1
- package/dist/replication/authority.cjs +36 -0
- package/dist/replication/authority.cjs.map +1 -1
- package/dist/replication/authority.d.cts +2 -2
- package/dist/replication/authority.d.ts +2 -2
- package/dist/replication/authority.js +35 -0
- package/dist/replication/authority.js.map +1 -1
- package/dist/replication/runtime.cjs.map +1 -1
- package/dist/replication/runtime.d.cts +1 -1
- package/dist/replication/runtime.d.ts +1 -1
- package/dist/replication/runtime.js.map +1 -1
- package/dist/{runtime-v62FzQHz.d.ts → runtime-CO4VXnPq.d.ts} +2 -1
- package/dist/{runtime-D1o9Eybt.d.cts → runtime-mRhSu-vJ.d.cts} +2 -1
- package/package.json +4 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NamedKeyClient } from '@tinycloud/sdk-services/encryption/named-keys';
|
|
2
2
|
export { DecryptManyResult, KeyCallOptions, KeyDescriptor, KeyEncryptOptions, NamedKeyClient, NamedKeyEnvelope, NamedKeyError, NamedKeyErrorCode, PublicKeyDescriptor, buildKeyAdminFacts, buildKeyDescribeFacts } from '@tinycloud/sdk-services/encryption/named-keys';
|
|
3
|
-
import { T as TinyCloudNode } from './TinyCloudNode-
|
|
3
|
+
import { T as TinyCloudNode } from './TinyCloudNode-CVO41O12.cjs';
|
|
4
4
|
import '@tinycloud/sdk-core';
|
|
5
5
|
import '@tinycloud/sdk-services/kv/replication';
|
|
6
6
|
import '@tinycloud/sdk-services';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NamedKeyClient } from '@tinycloud/sdk-services/encryption/named-keys';
|
|
2
2
|
export { DecryptManyResult, KeyCallOptions, KeyDescriptor, KeyEncryptOptions, NamedKeyClient, NamedKeyEnvelope, NamedKeyError, NamedKeyErrorCode, PublicKeyDescriptor, buildKeyAdminFacts, buildKeyDescribeFacts } from '@tinycloud/sdk-services/encryption/named-keys';
|
|
3
|
-
import { T as TinyCloudNode } from './TinyCloudNode-
|
|
3
|
+
import { T as TinyCloudNode } from './TinyCloudNode-B6VOBrCb.js';
|
|
4
4
|
import '@tinycloud/sdk-core';
|
|
5
5
|
import '@tinycloud/sdk-services/kv/replication';
|
|
6
6
|
import '@tinycloud/sdk-services';
|
package/dist/index.cjs
CHANGED
|
@@ -17414,6 +17414,7 @@ __export(authority_exports, {
|
|
|
17414
17414
|
assertValidReplicationConfig: () => assertValidReplicationConfig,
|
|
17415
17415
|
augmentSignInEntriesWithReplication: () => augmentSignInEntriesWithReplication,
|
|
17416
17416
|
createReplicationAuthority: () => createReplicationAuthority,
|
|
17417
|
+
eraseReplicaLocalCopy: () => eraseReplicaLocalCopy,
|
|
17417
17418
|
establishReplicaSessionStamp: () => establishReplicaSessionStamp,
|
|
17418
17419
|
hasUnrestrictedGetCoverage: () => hasUnrestrictedGetCoverage,
|
|
17419
17420
|
mintNodeReplicationGrant: () => mintNodeReplicationGrant,
|
|
@@ -17444,6 +17445,38 @@ function reportReplicaDenial(result, reason, onEvent, context) {
|
|
|
17444
17445
|
} catch {
|
|
17445
17446
|
}
|
|
17446
17447
|
}
|
|
17448
|
+
async function eraseReplicaLocalCopy(lifecycle, trigger, denyStatus, handlers) {
|
|
17449
|
+
if (lifecycle?.kind !== "indexeddb" || lifecycle.eraseLocalCopy === void 0) return void 0;
|
|
17450
|
+
let outcome = { status: "failed", code: "STORAGE_ERROR", marker: false };
|
|
17451
|
+
for (let attempt = 0; attempt <= ERASE_RETRY_DELAYS_MS.length; attempt++) {
|
|
17452
|
+
if (attempt > 0) await new Promise((resolve2) => setTimeout(resolve2, ERASE_RETRY_DELAYS_MS[attempt - 1]));
|
|
17453
|
+
try {
|
|
17454
|
+
outcome = await lifecycle.eraseLocalCopy({ signal: AbortSignal.timeout(ERASE_ATTEMPT_MS) });
|
|
17455
|
+
} catch {
|
|
17456
|
+
outcome = { status: "failed", code: "STORAGE_ERROR", marker: false };
|
|
17457
|
+
}
|
|
17458
|
+
if (outcome.status !== "failed") break;
|
|
17459
|
+
}
|
|
17460
|
+
const keysKept = denyStatus === "marker" || denyStatus === "unguarded";
|
|
17461
|
+
const purge = outcome.status === "erased" ? { ok: true } : { ok: false, retryNow: outcome.status === "failed" };
|
|
17462
|
+
if (outcome.status === "erased" || outcome.status === "refused" && !keysKept) return { outcome, purge };
|
|
17463
|
+
const logoutPending = outcome.status === "failed" && outcome.marker;
|
|
17464
|
+
const event = {
|
|
17465
|
+
type: "replica.purge.failed",
|
|
17466
|
+
trigger,
|
|
17467
|
+
reason: logoutPending ? "logout_pending" : "gate_unavailable",
|
|
17468
|
+
code: outcome.code,
|
|
17469
|
+
retryNow: outcome.status === "failed"
|
|
17470
|
+
};
|
|
17471
|
+
for (const handler of handlers) {
|
|
17472
|
+
try {
|
|
17473
|
+
handler(event);
|
|
17474
|
+
} catch (error) {
|
|
17475
|
+
console.error('Error in "replica.purge.failed" handler:', error);
|
|
17476
|
+
}
|
|
17477
|
+
}
|
|
17478
|
+
return logoutPending ? { outcome, purge, logoutPending } : { outcome, purge };
|
|
17479
|
+
}
|
|
17447
17480
|
function verifiedOwnerConsentAnchor(session, wasmBindings, exactVerifiedRecap2) {
|
|
17448
17481
|
if (typeof session.siwe !== "string" || typeof session.signature !== "string" || typeof session.address !== "string" || typeof session.chainId !== "number") return null;
|
|
17449
17482
|
try {
|
|
@@ -17702,7 +17735,7 @@ function createReplicationAuthority(host) {
|
|
|
17702
17735
|
};
|
|
17703
17736
|
return authority;
|
|
17704
17737
|
}
|
|
17705
|
-
var import_siwe3, import_sdk_core12, import_replica, parseUcanGrant, KV_GET2, KV_SYNC2, KV_SERVICE2, AUTHORITY_EXPIRY_MARGIN_MS;
|
|
17738
|
+
var import_siwe3, import_sdk_core12, import_replica, parseUcanGrant, ERASE_RETRY_DELAYS_MS, ERASE_ATTEMPT_MS, KV_GET2, KV_SYNC2, KV_SERVICE2, AUTHORITY_EXPIRY_MARGIN_MS;
|
|
17706
17739
|
var init_authority = __esm({
|
|
17707
17740
|
"src/replication/authority.ts"() {
|
|
17708
17741
|
"use strict";
|
|
@@ -17712,6 +17745,8 @@ var init_authority = __esm({
|
|
|
17712
17745
|
init_config();
|
|
17713
17746
|
init_authority_sign_in();
|
|
17714
17747
|
parseUcanGrant = import_replica.parseUcanGrant;
|
|
17748
|
+
ERASE_RETRY_DELAYS_MS = [150, 450];
|
|
17749
|
+
ERASE_ATTEMPT_MS = 3e3;
|
|
17715
17750
|
KV_GET2 = import_sdk_core12.KV.GET;
|
|
17716
17751
|
KV_SYNC2 = import_sdk_core12.KV.SYNC;
|
|
17717
17752
|
KV_SERVICE2 = "tinycloud.kv";
|
|
@@ -21565,6 +21600,7 @@ function replicaRestoreRefusal(error) {
|
|
|
21565
21600
|
case "purge_pending":
|
|
21566
21601
|
case "logout_pending":
|
|
21567
21602
|
case "gate_unavailable":
|
|
21603
|
+
case "wallet_provider_required":
|
|
21568
21604
|
return error.gate;
|
|
21569
21605
|
}
|
|
21570
21606
|
}
|
|
@@ -21599,6 +21635,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21599
21635
|
this.auth = null;
|
|
21600
21636
|
this.tc = null;
|
|
21601
21637
|
this._chainId = 1;
|
|
21638
|
+
this.replicaPurgeFailedHandlers = /* @__PURE__ */ new Set();
|
|
21602
21639
|
/** Mints the replica session stamp on each fresh sign-in (TC-858 §4.1). Undefined when replication is off. */
|
|
21603
21640
|
this.establishReplicaStamp = async (session) => {
|
|
21604
21641
|
const replication = this.config.replication;
|
|
@@ -21805,6 +21842,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21805
21842
|
return instance ? instance.control.purge(input) : runtime.then((ready) => ready.control.purge(input));
|
|
21806
21843
|
},
|
|
21807
21844
|
clearPending: async () => (await runtime).control.clearPending(),
|
|
21845
|
+
purgeLocalCopy: async () => (await this.eraseReplicaLocalCopy("purge_local_copy"))?.purge ?? { ok: false, retryNow: false },
|
|
21808
21846
|
close: async () => (await runtime).control.close()
|
|
21809
21847
|
};
|
|
21810
21848
|
}
|
|
@@ -21859,18 +21897,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21859
21897
|
get freshEncryptionNetworkCreated() {
|
|
21860
21898
|
return this._freshEncryptionNetworkCreated;
|
|
21861
21899
|
}
|
|
21862
|
-
/**
|
|
21863
|
-
* Subscribe to `storage.full`. It fires on the first write any service had
|
|
21864
|
-
* rejected because the owner's TinyCloud storage is full
|
|
21865
|
-
* (`STORAGE_QUOTA_EXCEEDED` or `STORAGE_LIMIT_REACHED`), so an app can show
|
|
21866
|
-
* one read-only banner. Reads keep working. For the signed-in account's own
|
|
21867
|
-
* storage it fires once per episode: the episode ends only when a write to
|
|
21868
|
-
* that storage succeeds, or on sign-out. A `storage.status()` read does not
|
|
21869
|
-
* end it. A rejection on another owner's delegated space fires once per
|
|
21870
|
-
* owner, until that owner's `storage.status()` reports space again. Returns
|
|
21871
|
-
* the unsubscribe function.
|
|
21872
|
-
*/
|
|
21873
21900
|
on(event, handler) {
|
|
21901
|
+
if (event === "replica.purge.failed") {
|
|
21902
|
+
const listener = handler;
|
|
21903
|
+
this.replicaPurgeFailedHandlers.add(listener);
|
|
21904
|
+
return () => {
|
|
21905
|
+
this.replicaPurgeFailedHandlers.delete(listener);
|
|
21906
|
+
};
|
|
21907
|
+
}
|
|
21874
21908
|
if (event !== "storage.full") {
|
|
21875
21909
|
throw new Error(`Unknown TinyCloud event: ${String(event)}`);
|
|
21876
21910
|
}
|
|
@@ -22351,6 +22385,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22351
22385
|
const leavingAuth = this.auth;
|
|
22352
22386
|
const leavingContext = this._serviceContext;
|
|
22353
22387
|
let denied;
|
|
22388
|
+
let erased;
|
|
22354
22389
|
try {
|
|
22355
22390
|
this.teardownSession();
|
|
22356
22391
|
} finally {
|
|
@@ -22361,6 +22396,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22361
22396
|
try {
|
|
22362
22397
|
await this.accountRegistryTail;
|
|
22363
22398
|
await this.quiesceReplicaRuntime();
|
|
22399
|
+
if (denied) erased = await this.eraseReplicaLocalCopy("sign_out", denied.status);
|
|
22364
22400
|
} finally {
|
|
22365
22401
|
if (leavingAddress) {
|
|
22366
22402
|
await (leavingAuth ? leavingAuth.clearPersistedSession(leavingAddress) : this.config.sessionStorage?.clear(leavingAddress));
|
|
@@ -22368,8 +22404,37 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22368
22404
|
}
|
|
22369
22405
|
}
|
|
22370
22406
|
}
|
|
22371
|
-
if (denied?.status === "unguarded") {
|
|
22372
|
-
throw
|
|
22407
|
+
if (denied?.status === "unguarded" && erased?.outcome.status !== "erased") {
|
|
22408
|
+
throw Object.assign(
|
|
22409
|
+
new Error(`Replica gate was not denied (${denied.code ?? "unknown"}); the replica may still be restorable.`),
|
|
22410
|
+
{
|
|
22411
|
+
code: "REPLICA_PURGE_FAILED",
|
|
22412
|
+
reason: "gate_unavailable",
|
|
22413
|
+
retryNow: erased?.outcome.status === "failed"
|
|
22414
|
+
}
|
|
22415
|
+
);
|
|
22416
|
+
}
|
|
22417
|
+
}
|
|
22418
|
+
/**
|
|
22419
|
+
* Erases the browser local copy after a deny (retry, event and next-load marker live in the lazy
|
|
22420
|
+
* replication authority). Never rejects; `undefined` when replication is off or the storage keeps
|
|
22421
|
+
* no browser database.
|
|
22422
|
+
*/
|
|
22423
|
+
async eraseReplicaLocalCopy(trigger, denyStatus) {
|
|
22424
|
+
const replication = this.config.replication;
|
|
22425
|
+
if (!replication?.enabled) return void 0;
|
|
22426
|
+
try {
|
|
22427
|
+
const { eraseReplicaLocalCopy: eraseReplicaLocalCopy2 } = await getNodeReplicationLoaders().authority();
|
|
22428
|
+
const erased = await eraseReplicaLocalCopy2(
|
|
22429
|
+
replication.storage.lifecycle,
|
|
22430
|
+
trigger,
|
|
22431
|
+
denyStatus,
|
|
22432
|
+
this.replicaPurgeFailedHandlers
|
|
22433
|
+
);
|
|
22434
|
+
if (erased?.logoutPending) this.replicaRestoreGate = "logout_pending";
|
|
22435
|
+
return erased;
|
|
22436
|
+
} catch {
|
|
22437
|
+
return void 0;
|
|
22373
22438
|
}
|
|
22374
22439
|
}
|
|
22375
22440
|
/**
|
|
@@ -22533,6 +22598,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22533
22598
|
const priorPrincipal = this.replicaSessionPrincipal ?? (this.address ? (0, import_sdk_core10.pkhDid)(this.address, this._chainId) : void 0);
|
|
22534
22599
|
if (this.config.replication?.enabled && priorPrincipal && priorPrincipal !== nextPrincipal) {
|
|
22535
22600
|
const denial = await this.denyReplicaGate({ reason: "account_switch", principal: priorPrincipal, next: nextPrincipal });
|
|
22601
|
+
if (denial) {
|
|
22602
|
+
await this.quiesceReplicaRuntime();
|
|
22603
|
+
await this.eraseReplicaLocalCopy("account_switch", denial.status);
|
|
22604
|
+
}
|
|
22536
22605
|
this.replicaRestoreGate = denial?.status === "unguarded" ? "gate_unavailable" : "stamp_stale";
|
|
22537
22606
|
}
|
|
22538
22607
|
if (address !== this._address || chainId !== this._chainId) {
|