@weaveprotocol/cli 0.2.1 → 0.2.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/README.md +2 -2
- package/dist/weave.mjs +196 -114
- package/package.json +11 -6
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ To have `weave` everywhere:
|
|
|
30
30
|
npm install -g @weaveprotocol/cli # or run it without installing: npx @weaveprotocol/cli <command>
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
From this repo: `npm install` at the repo root (the CLI is a workspace), then `cd cli && npm run bundle && npm link`, or a
|
|
33
|
+
From this repo: `npm install` at the repo root (the CLI is a workspace), then `cd packages/cli && npm run bundle && npm link`, or a
|
|
34
34
|
binary with no Node at all: `bun build.ts --native`.
|
|
35
35
|
|
|
36
36
|
```bash
|
|
@@ -230,5 +230,5 @@ space anywhere leaves it everywhere.
|
|
|
230
230
|
across real networks, behind a strict NAT, in Safari, and on a phone
|
|
231
231
|
switching apps.
|
|
232
232
|
|
|
233
|
-
What the protocol still has planned is in [the spec](
|
|
233
|
+
What the protocol still has planned is in [the spec](../../spec/README.md),
|
|
234
234
|
under **Planned** in each part.
|
package/dist/weave.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import path6 from "node:path";
|
|
|
6
6
|
import { createInterface as createInterface2 } from "node:readline";
|
|
7
7
|
import { parseArgs } from "node:util";
|
|
8
8
|
|
|
9
|
-
// ../src/utils/encoding.ts
|
|
9
|
+
// ../core/src/utils/encoding.ts
|
|
10
10
|
var encoder = new TextEncoder();
|
|
11
11
|
var decoder = new TextDecoder();
|
|
12
12
|
function utf8Encode(str2) {
|
|
@@ -46,7 +46,7 @@ function bytesToHex(bytes) {
|
|
|
46
46
|
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
//
|
|
49
|
+
// ../../node_modules/@noble/hashes/_u64.js
|
|
50
50
|
var fromNumH = (n) => n / 2 ** 32 | 0;
|
|
51
51
|
var fromNumL = (n) => n >>> 0;
|
|
52
52
|
function setU64FromNum(view, byteOffset, n, isLE) {
|
|
@@ -56,7 +56,7 @@ function setU64FromNum(view, byteOffset, n, isLE) {
|
|
|
56
56
|
view.setUint32(byteOffset + 4, isLE ? h : l, isLE);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
//
|
|
59
|
+
// ../../node_modules/@noble/hashes/utils.js
|
|
60
60
|
function isBytes(a) {
|
|
61
61
|
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
62
62
|
}
|
|
@@ -221,7 +221,7 @@ var oidNist = (suffix) => ({
|
|
|
221
221
|
oid: Uint8Array.from([6, 9, 96, 134, 72, 1, 101, 3, 4, 2, suffix])
|
|
222
222
|
});
|
|
223
223
|
|
|
224
|
-
//
|
|
224
|
+
// ../../node_modules/@noble/hashes/_md.js
|
|
225
225
|
function Chi(a, b, c) {
|
|
226
226
|
return a & b ^ ~a & c;
|
|
227
227
|
}
|
|
@@ -334,7 +334,7 @@ var SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
|
|
334
334
|
1541459225
|
|
335
335
|
]);
|
|
336
336
|
|
|
337
|
-
//
|
|
337
|
+
// ../../node_modules/@noble/hashes/sha2.js
|
|
338
338
|
var SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
339
339
|
1116352408,
|
|
340
340
|
1899447441,
|
|
@@ -499,7 +499,7 @@ var sha256 = /* @__PURE__ */ createHasher(
|
|
|
499
499
|
/* @__PURE__ */ oidNist(1)
|
|
500
500
|
);
|
|
501
501
|
|
|
502
|
-
//
|
|
502
|
+
// ../../node_modules/@noble/curves/utils.js
|
|
503
503
|
function aarray(item, title, inner = () => {
|
|
504
504
|
}) {
|
|
505
505
|
if (!Array.isArray(item))
|
|
@@ -681,7 +681,7 @@ function validateObject(object, fields = {}, optFields = {}, title = "object") {
|
|
|
681
681
|
iter(optFields, true);
|
|
682
682
|
}
|
|
683
683
|
|
|
684
|
-
//
|
|
684
|
+
// ../../node_modules/@noble/curves/abstract/modular.js
|
|
685
685
|
var _0n2 = /* @__PURE__ */ BigInt(0);
|
|
686
686
|
var _1n2 = /* @__PURE__ */ BigInt(1);
|
|
687
687
|
var _2n = /* @__PURE__ */ BigInt(2);
|
|
@@ -1131,7 +1131,7 @@ function mapHashToField(key3, fieldOrder, isLE = false) {
|
|
|
1131
1131
|
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
|
1132
1132
|
}
|
|
1133
1133
|
|
|
1134
|
-
//
|
|
1134
|
+
// ../../node_modules/@noble/curves/abstract/curve.js
|
|
1135
1135
|
var _0n3 = /* @__PURE__ */ BigInt(0);
|
|
1136
1136
|
var _1n3 = /* @__PURE__ */ BigInt(1);
|
|
1137
1137
|
var _4n2 = /* @__PURE__ */ BigInt(4);
|
|
@@ -1518,7 +1518,7 @@ function createKeygen(randomSecretKey, getPublicKey) {
|
|
|
1518
1518
|
};
|
|
1519
1519
|
}
|
|
1520
1520
|
|
|
1521
|
-
//
|
|
1521
|
+
// ../../node_modules/@noble/hashes/hmac.js
|
|
1522
1522
|
var _HMAC = class {
|
|
1523
1523
|
oHash;
|
|
1524
1524
|
iHash;
|
|
@@ -1595,7 +1595,7 @@ var hmac = /* @__PURE__ */ (() => {
|
|
|
1595
1595
|
return hmac_;
|
|
1596
1596
|
})();
|
|
1597
1597
|
|
|
1598
|
-
//
|
|
1598
|
+
// ../../node_modules/@noble/curves/abstract/der.js
|
|
1599
1599
|
var _0n4 = /* @__PURE__ */ BigInt(0);
|
|
1600
1600
|
var DERErr = class extends Error {
|
|
1601
1601
|
constructor(m = "") {
|
|
@@ -1722,7 +1722,7 @@ var DER = /* @__PURE__ */ (() => {
|
|
|
1722
1722
|
return Object.freeze(_DER);
|
|
1723
1723
|
})();
|
|
1724
1724
|
|
|
1725
|
-
//
|
|
1725
|
+
// ../../node_modules/@noble/curves/abstract/weierstrass.js
|
|
1726
1726
|
var divNearest = (num, den) => (num + (num >= 0 ? den : -den) / _2n2) / den;
|
|
1727
1727
|
function _splitEndoScalar(k, basis, n) {
|
|
1728
1728
|
aInRange("scalar", k, _0n5, n);
|
|
@@ -2554,7 +2554,7 @@ function ecdsa(Point, hash2, ecdsaOpts = {}) {
|
|
|
2554
2554
|
});
|
|
2555
2555
|
}
|
|
2556
2556
|
|
|
2557
|
-
//
|
|
2557
|
+
// ../../node_modules/@noble/curves/nist.js
|
|
2558
2558
|
var p256_CURVE = /* @__PURE__ */ (() => ({
|
|
2559
2559
|
p: BigInt("0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff"),
|
|
2560
2560
|
n: BigInt("0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"),
|
|
@@ -2567,7 +2567,7 @@ var p256_CURVE = /* @__PURE__ */ (() => ({
|
|
|
2567
2567
|
var p256_Point = /* @__PURE__ */ weierstrass(p256_CURVE);
|
|
2568
2568
|
var p256 = /* @__PURE__ */ ecdsa(p256_Point, sha256);
|
|
2569
2569
|
|
|
2570
|
-
// ../src/identity/crypto-p256.ts
|
|
2570
|
+
// ../core/src/identity/crypto-p256.ts
|
|
2571
2571
|
var P256_SEED_BYTES = 48;
|
|
2572
2572
|
var P256_KEY_INFO = new TextEncoder().encode("weave/p256-identity-key/v1");
|
|
2573
2573
|
async function hkdf(ikm, info, length) {
|
|
@@ -2679,12 +2679,12 @@ function createP256Provider() {
|
|
|
2679
2679
|
});
|
|
2680
2680
|
}
|
|
2681
2681
|
|
|
2682
|
-
// ../src/utils/errors.ts
|
|
2682
|
+
// ../core/src/utils/errors.ts
|
|
2683
2683
|
function protocolError(code, message, hint) {
|
|
2684
2684
|
return Object.assign(new Error(message), { code, ...hint ? { hint } : {} });
|
|
2685
2685
|
}
|
|
2686
2686
|
|
|
2687
|
-
// ../src/identity/webauthn.ts
|
|
2687
|
+
// ../core/src/identity/webauthn.ts
|
|
2688
2688
|
var PRF_SALT = new TextEncoder().encode("weave-protocol-key-v1");
|
|
2689
2689
|
async function registerPasskey(options) {
|
|
2690
2690
|
if (!globalThis.navigator?.credentials) {
|
|
@@ -2780,10 +2780,10 @@ async function authenticatePasskey(credentialId, options) {
|
|
|
2780
2780
|
});
|
|
2781
2781
|
}
|
|
2782
2782
|
|
|
2783
|
-
// ../src/identity/passkey-diagnostics.ts
|
|
2783
|
+
// ../core/src/identity/passkey-diagnostics.ts
|
|
2784
2784
|
var PRF_SALT2 = new TextEncoder().encode("weave-protocol-key-v1");
|
|
2785
2785
|
|
|
2786
|
-
// ../src/identity/keys.ts
|
|
2786
|
+
// ../core/src/identity/keys.ts
|
|
2787
2787
|
async function deriveKeyPair(seed, provider) {
|
|
2788
2788
|
const keyPair = await provider.deriveKeyPairFromSeed(seed);
|
|
2789
2789
|
const publicKeyBytes = await provider.exportPublicKey(keyPair.publicKey);
|
|
@@ -2815,7 +2815,7 @@ async function deriveKeyFromPassword(password, salt, provider) {
|
|
|
2815
2815
|
return deriveKeyPair(new Uint8Array(derivedBits), provider);
|
|
2816
2816
|
}
|
|
2817
2817
|
|
|
2818
|
-
// ../src/identity/recovery-code.ts
|
|
2818
|
+
// ../core/src/identity/recovery-code.ts
|
|
2819
2819
|
var ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
2820
2820
|
var SUBSTITUTIONS = { O: "0", I: "1", L: "1", U: "V" };
|
|
2821
2821
|
var SEED_BYTES = 16;
|
|
@@ -2876,7 +2876,7 @@ function encodeBase32(bytes) {
|
|
|
2876
2876
|
return out;
|
|
2877
2877
|
}
|
|
2878
2878
|
|
|
2879
|
-
//
|
|
2879
|
+
// ../../node_modules/@scure/base/index.js
|
|
2880
2880
|
var freeze = (fn) => Object.freeze(fn());
|
|
2881
2881
|
function isBytes3(a) {
|
|
2882
2882
|
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
@@ -3082,7 +3082,7 @@ var radix58 = /* @__PURE__ */ radixBaseN(58, B58_GROUP);
|
|
|
3082
3082
|
var genBase58 = (abc) => genBaseN(radix58, abc);
|
|
3083
3083
|
var base58 = /* @__PURE__ */ freeze(() => genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"));
|
|
3084
3084
|
|
|
3085
|
-
// ../src/identity/did.ts
|
|
3085
|
+
// ../core/src/identity/did.ts
|
|
3086
3086
|
var P256_MULTICODEC = new Uint8Array([128, 36]);
|
|
3087
3087
|
function publicKeyToDid(publicKeyBytes, multicodecPrefix) {
|
|
3088
3088
|
const prefixedKey = concatBytes(multicodecPrefix, publicKeyBytes);
|
|
@@ -3103,7 +3103,7 @@ function didToPublicKey(did) {
|
|
|
3103
3103
|
return { multicodecPrefix, publicKeyBytes };
|
|
3104
3104
|
}
|
|
3105
3105
|
|
|
3106
|
-
// ../src/identity/identity-manager.ts
|
|
3106
|
+
// ../core/src/identity/identity-manager.ts
|
|
3107
3107
|
function prfUnsupported() {
|
|
3108
3108
|
return protocolError(
|
|
3109
3109
|
"PRF_UNSUPPORTED",
|
|
@@ -3194,7 +3194,7 @@ function createIdentityManager(config) {
|
|
|
3194
3194
|
});
|
|
3195
3195
|
}
|
|
3196
3196
|
|
|
3197
|
-
// ../src/storage/folder-adapter.ts
|
|
3197
|
+
// ../core/src/storage/folder-adapter.ts
|
|
3198
3198
|
var EXPRESSION_SUFFIX = ".json";
|
|
3199
3199
|
function encodeKey(key3) {
|
|
3200
3200
|
let out = "";
|
|
@@ -3365,7 +3365,7 @@ async function createFolderAdapter(root, path7) {
|
|
|
3365
3365
|
});
|
|
3366
3366
|
}
|
|
3367
3367
|
|
|
3368
|
-
// ../src/identity/folder-account.ts
|
|
3368
|
+
// ../core/src/identity/folder-account.ts
|
|
3369
3369
|
function createVault(params) {
|
|
3370
3370
|
return {
|
|
3371
3371
|
version: 2,
|
|
@@ -3376,7 +3376,7 @@ function createVault(params) {
|
|
|
3376
3376
|
};
|
|
3377
3377
|
}
|
|
3378
3378
|
|
|
3379
|
-
// ../src/identity/account-store.ts
|
|
3379
|
+
// ../core/src/identity/account-store.ts
|
|
3380
3380
|
var LIST_FILE = "accounts.json";
|
|
3381
3381
|
var ACCOUNTS_DIR = "accounts";
|
|
3382
3382
|
var VAULT_FILE = "account.json";
|
|
@@ -3491,7 +3491,7 @@ function createFolderAccountStore(dir) {
|
|
|
3491
3491
|
});
|
|
3492
3492
|
}
|
|
3493
3493
|
|
|
3494
|
-
// ../src/identity/account-vault.ts
|
|
3494
|
+
// ../core/src/identity/account-vault.ts
|
|
3495
3495
|
var IV_BYTES = 12;
|
|
3496
3496
|
var SALT_BYTES = 16;
|
|
3497
3497
|
var PASSPHRASE_ITERATIONS = 6e5;
|
|
@@ -3601,12 +3601,13 @@ async function deriveVaultKey(seed) {
|
|
|
3601
3601
|
["encrypt", "decrypt"]
|
|
3602
3602
|
);
|
|
3603
3603
|
}
|
|
3604
|
+
var CLI_PASSPHRASE_LABEL = "CLI passphrase";
|
|
3604
3605
|
function withWrap(vault, wrap) {
|
|
3605
3606
|
const superseded = (existing) => existing.kind === "device" && wrap.kind === "device" && existing.rpId === wrap.rpId;
|
|
3606
3607
|
return { ...vault, wraps: [...vault.wraps.filter((existing) => !superseded(existing)), wrap] };
|
|
3607
3608
|
}
|
|
3608
3609
|
|
|
3609
|
-
// ../src/identity/contact-key.ts
|
|
3610
|
+
// ../core/src/identity/contact-key.ts
|
|
3610
3611
|
var CONTACT_KEY_INFO = "weave/p256-contact-key/v1";
|
|
3611
3612
|
var SEAL_INFO = "weave/contact-seal/v1";
|
|
3612
3613
|
var MEMBER_KEY_INFO = "weave/p256-member-key/v1";
|
|
@@ -3749,7 +3750,7 @@ async function openSealed(privateKey, sealed, context) {
|
|
|
3749
3750
|
}
|
|
3750
3751
|
}
|
|
3751
3752
|
|
|
3752
|
-
// ../src/utils/hash.ts
|
|
3753
|
+
// ../core/src/utils/hash.ts
|
|
3753
3754
|
async function sha2562(data) {
|
|
3754
3755
|
const buffer = await globalThis.crypto.subtle.digest("SHA-256", data);
|
|
3755
3756
|
return new Uint8Array(buffer);
|
|
@@ -3800,7 +3801,7 @@ async function cidFromBytes(data) {
|
|
|
3800
3801
|
return "b" + base32Encode(hashBytes);
|
|
3801
3802
|
}
|
|
3802
3803
|
|
|
3803
|
-
// ../src/records/links.ts
|
|
3804
|
+
// ../core/src/records/links.ts
|
|
3804
3805
|
var LINK_REL_PATTERN = /^[a-z][a-zA-Z0-9]{0,63}$/;
|
|
3805
3806
|
var MAX_LINKS = 32;
|
|
3806
3807
|
function checkLinks(links2) {
|
|
@@ -3818,7 +3819,7 @@ function checkLinks(links2) {
|
|
|
3818
3819
|
return null;
|
|
3819
3820
|
}
|
|
3820
3821
|
|
|
3821
|
-
// ../src/records/version.ts
|
|
3822
|
+
// ../core/src/records/version.ts
|
|
3822
3823
|
var MAX_SEEN = 64;
|
|
3823
3824
|
var RECORD_KEY_PATTERN = /^[a-z0-9:._-]{1,128}$/;
|
|
3824
3825
|
function newRecordKey() {
|
|
@@ -3859,7 +3860,7 @@ function checkVersionShape(expression) {
|
|
|
3859
3860
|
return null;
|
|
3860
3861
|
}
|
|
3861
3862
|
|
|
3862
|
-
// ../src/schema/expression.ts
|
|
3863
|
+
// ../core/src/schema/expression.ts
|
|
3863
3864
|
function canonicalize(obj) {
|
|
3864
3865
|
if (obj === null || typeof obj !== "object") {
|
|
3865
3866
|
return JSON.stringify(obj) ?? "null";
|
|
@@ -3904,7 +3905,7 @@ async function getExpressionId(expr) {
|
|
|
3904
3905
|
return await cidFromBytes(bytes);
|
|
3905
3906
|
}
|
|
3906
3907
|
|
|
3907
|
-
// ../src/identity/ucan.ts
|
|
3908
|
+
// ../core/src/identity/ucan.ts
|
|
3908
3909
|
var UCAN_CLOCK_SKEW_SECONDS = 300;
|
|
3909
3910
|
async function issueUCAN(options, provider) {
|
|
3910
3911
|
const header = { alg: "ES256", typ: "JWT", ucv: "0.10.0" };
|
|
@@ -4095,7 +4096,7 @@ async function resolveDelegationRoot(encoded, resolveProof, provider, options =
|
|
|
4095
4096
|
return { valid: false, rootDid: null, capabilities: [], audience: null, reason: `Delegation chain deeper than ${MAX_CHAIN_DEPTH} links` };
|
|
4096
4097
|
}
|
|
4097
4098
|
|
|
4098
|
-
// ../src/identity/root-signer.ts
|
|
4099
|
+
// ../core/src/identity/root-signer.ts
|
|
4099
4100
|
function createLocalRootSigner(identity, provider) {
|
|
4100
4101
|
return Object.freeze({
|
|
4101
4102
|
did: identity.did,
|
|
@@ -4115,7 +4116,7 @@ function createLocalRootSigner(identity, provider) {
|
|
|
4115
4116
|
});
|
|
4116
4117
|
}
|
|
4117
4118
|
|
|
4118
|
-
// ../src/identity/pairing.ts
|
|
4119
|
+
// ../core/src/identity/pairing.ts
|
|
4119
4120
|
var ROOM_PREFIX = utf8Encode("weave-pairing-room-v1");
|
|
4120
4121
|
var PAIRING_KEY_INFO = utf8Encode("weave-pairing-key-v1");
|
|
4121
4122
|
var IV_BYTES3 = 12;
|
|
@@ -4147,7 +4148,7 @@ async function openPairingPayload(sealed, key3) {
|
|
|
4147
4148
|
}
|
|
4148
4149
|
}
|
|
4149
4150
|
|
|
4150
|
-
// ../src/identity/agent-note.ts
|
|
4151
|
+
// ../core/src/identity/agent-note.ts
|
|
4151
4152
|
var AGENT_FACT = Object.freeze({ weave: "agent" });
|
|
4152
4153
|
function isAgentNote(encoded) {
|
|
4153
4154
|
if (!encoded) return false;
|
|
@@ -4159,7 +4160,7 @@ function isAgentNote(encoded) {
|
|
|
4159
4160
|
}
|
|
4160
4161
|
}
|
|
4161
4162
|
|
|
4162
|
-
// ../src/schema/schema-engine.ts
|
|
4163
|
+
// ../core/src/schema/schema-engine.ts
|
|
4163
4164
|
function createSchemaEngine() {
|
|
4164
4165
|
const collections = /* @__PURE__ */ new Map();
|
|
4165
4166
|
return Object.freeze({
|
|
@@ -4192,7 +4193,7 @@ function createSchemaEngine() {
|
|
|
4192
4193
|
});
|
|
4193
4194
|
}
|
|
4194
4195
|
|
|
4195
|
-
// ../src/schema/signer.ts
|
|
4196
|
+
// ../core/src/schema/signer.ts
|
|
4196
4197
|
function createSigner(provider) {
|
|
4197
4198
|
return Object.freeze({
|
|
4198
4199
|
async sign(payload, privateKey) {
|
|
@@ -4218,7 +4219,7 @@ function createSigner(provider) {
|
|
|
4218
4219
|
});
|
|
4219
4220
|
}
|
|
4220
4221
|
|
|
4221
|
-
// ../src/sync/negentropy.ts
|
|
4222
|
+
// ../core/src/sync/negentropy.ts
|
|
4222
4223
|
var NEGENTROPY_VERSION = 97;
|
|
4223
4224
|
var ID_SIZE = 32;
|
|
4224
4225
|
var FINGERPRINT_SIZE = 16;
|
|
@@ -4508,7 +4509,7 @@ function createReconciler(set, options) {
|
|
|
4508
4509
|
}
|
|
4509
4510
|
var key = (id) => String.fromCharCode(...id);
|
|
4510
4511
|
|
|
4511
|
-
// ../src/storage/storage-provider.ts
|
|
4512
|
+
// ../core/src/storage/storage-provider.ts
|
|
4512
4513
|
var CURRENT_PREFIX = "r/";
|
|
4513
4514
|
var GENESIS_PREFIX = "g/";
|
|
4514
4515
|
var HISTORY_PREFIX = "h/";
|
|
@@ -4733,7 +4734,7 @@ function createStorageProvider(adapter) {
|
|
|
4733
4734
|
});
|
|
4734
4735
|
}
|
|
4735
4736
|
|
|
4736
|
-
// ../src/storage/encrypted-adapter.ts
|
|
4737
|
+
// ../core/src/storage/encrypted-adapter.ts
|
|
4737
4738
|
var MAGIC = new Uint8Array([119, 101, 97, 118, 101, 101, 2, 0]);
|
|
4738
4739
|
var IV_BYTES4 = 12;
|
|
4739
4740
|
var DEFAULT_ENCRYPTED_PREFIXES = ["space:", "spacekey:", "spaceinvite:", "spacerole:"];
|
|
@@ -4797,7 +4798,7 @@ function createEncryptedAdapter(inner, key3, options) {
|
|
|
4797
4798
|
});
|
|
4798
4799
|
}
|
|
4799
4800
|
|
|
4800
|
-
// ../src/storage/folder-reconcile.ts
|
|
4801
|
+
// ../core/src/storage/folder-reconcile.ts
|
|
4801
4802
|
async function reconcileFolder(storage, adapter, accept = async () => true) {
|
|
4802
4803
|
const disk = await adapter.reload();
|
|
4803
4804
|
if (disk.added.length > 0 || disk.removed.length > 0) storage.invalidate();
|
|
@@ -4826,7 +4827,7 @@ async function reconcileFolder(storage, adapter, accept = async () => true) {
|
|
|
4826
4827
|
};
|
|
4827
4828
|
}
|
|
4828
4829
|
|
|
4829
|
-
// ../src/privacy/space-encryption.ts
|
|
4830
|
+
// ../core/src/privacy/space-encryption.ts
|
|
4830
4831
|
async function generateSpaceKey() {
|
|
4831
4832
|
const key3 = await globalThis.crypto.subtle.generateKey(
|
|
4832
4833
|
{ name: "AES-GCM", length: 256 },
|
|
@@ -4912,7 +4913,7 @@ async function openWith(spaceKey, sealed, context) {
|
|
|
4912
4913
|
}
|
|
4913
4914
|
}
|
|
4914
4915
|
|
|
4915
|
-
// ../src/space/roles.ts
|
|
4916
|
+
// ../core/src/space/roles.ts
|
|
4916
4917
|
var MANAGE = "manage";
|
|
4917
4918
|
var INVITE = "invite";
|
|
4918
4919
|
var DEFINE = "define";
|
|
@@ -5331,7 +5332,7 @@ function replayAccess(genesis, events) {
|
|
|
5331
5332
|
}
|
|
5332
5333
|
}
|
|
5333
5334
|
|
|
5334
|
-
// ../src/space/space-access.ts
|
|
5335
|
+
// ../core/src/space/space-access.ts
|
|
5335
5336
|
var READ_INFO = "weave/space-read/v1";
|
|
5336
5337
|
var INVITE_INFO = "weave/space-invite/v1";
|
|
5337
5338
|
function generateInviteSecret() {
|
|
@@ -5435,7 +5436,7 @@ async function verifyInvite(spaceId, did, inviteDid, signature, provider) {
|
|
|
5435
5436
|
}
|
|
5436
5437
|
}
|
|
5437
5438
|
|
|
5438
|
-
// ../src/space/presets.ts
|
|
5439
|
+
// ../core/src/space/presets.ts
|
|
5439
5440
|
var solo = Object.freeze({
|
|
5440
5441
|
roles: Object.freeze([{ name: "owner", title: "Owner", rank: 100, permissions: ["*"] }]),
|
|
5441
5442
|
creatorRole: "owner"
|
|
@@ -5457,7 +5458,7 @@ var community = Object.freeze({
|
|
|
5457
5458
|
});
|
|
5458
5459
|
var rolePresets = Object.freeze({ solo, team, community });
|
|
5459
5460
|
|
|
5460
|
-
// ../src/space/space-manager.ts
|
|
5461
|
+
// ../core/src/space/space-manager.ts
|
|
5461
5462
|
var SPACE_PREFIX = "space:";
|
|
5462
5463
|
var KEY_PREFIX = "spacekey:";
|
|
5463
5464
|
var INVITE_PREFIX = "spaceinvite:";
|
|
@@ -5635,7 +5636,7 @@ function parseSpaceInvite(invite) {
|
|
|
5635
5636
|
}
|
|
5636
5637
|
}
|
|
5637
5638
|
|
|
5638
|
-
// ../src/space/account-registry.ts
|
|
5639
|
+
// ../core/src/space/account-registry.ts
|
|
5639
5640
|
var MEMBERSHIP_COLLECTION = "sys.joined";
|
|
5640
5641
|
var PROFILE_COLLECTION = "sys.profile";
|
|
5641
5642
|
var PROFILE_KEY = "profile";
|
|
@@ -5687,7 +5688,7 @@ async function deriveAccountSpace(accountKey, owner, label, name, provider) {
|
|
|
5687
5688
|
return { space: space2, key: key3, invite: null, role: solo.creatorRole };
|
|
5688
5689
|
}
|
|
5689
5690
|
|
|
5690
|
-
//
|
|
5691
|
+
// ../../node_modules/@cfworker/json-schema/dist/esm/deep-compare-strict.js
|
|
5691
5692
|
function deepCompareStrict(a, b) {
|
|
5692
5693
|
const typeofa = typeof a;
|
|
5693
5694
|
if (typeofa !== typeof b) {
|
|
@@ -5728,7 +5729,7 @@ function deepCompareStrict(a, b) {
|
|
|
5728
5729
|
return a === b;
|
|
5729
5730
|
}
|
|
5730
5731
|
|
|
5731
|
-
//
|
|
5732
|
+
// ../../node_modules/@cfworker/json-schema/dist/esm/pointer.js
|
|
5732
5733
|
function encodePointer(p) {
|
|
5733
5734
|
return encodeURI(escapePointer(p));
|
|
5734
5735
|
}
|
|
@@ -5736,7 +5737,7 @@ function escapePointer(p) {
|
|
|
5736
5737
|
return p.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
5737
5738
|
}
|
|
5738
5739
|
|
|
5739
|
-
//
|
|
5740
|
+
// ../../node_modules/@cfworker/json-schema/dist/esm/dereference.js
|
|
5740
5741
|
var schemaArrayKeyword = {
|
|
5741
5742
|
prefixItems: true,
|
|
5742
5743
|
items: true,
|
|
@@ -5857,7 +5858,7 @@ function dereference(schema, lookup = /* @__PURE__ */ Object.create(null), baseU
|
|
|
5857
5858
|
return lookup;
|
|
5858
5859
|
}
|
|
5859
5860
|
|
|
5860
|
-
//
|
|
5861
|
+
// ../../node_modules/@cfworker/json-schema/dist/esm/format.js
|
|
5861
5862
|
var DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
|
|
5862
5863
|
var DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
5863
5864
|
var TIME = /^(\d\d):(\d\d):(\d\d)(\.\d+)?(z|[+-]\d\d(?::?\d\d)?)?$/i;
|
|
@@ -5950,7 +5951,7 @@ function regex(str2) {
|
|
|
5950
5951
|
}
|
|
5951
5952
|
}
|
|
5952
5953
|
|
|
5953
|
-
//
|
|
5954
|
+
// ../../node_modules/@cfworker/json-schema/dist/esm/types.js
|
|
5954
5955
|
var OutputFormat;
|
|
5955
5956
|
(function(OutputFormat2) {
|
|
5956
5957
|
OutputFormat2[OutputFormat2["Flag"] = 1] = "Flag";
|
|
@@ -5958,7 +5959,7 @@ var OutputFormat;
|
|
|
5958
5959
|
OutputFormat2[OutputFormat2["Detailed"] = 4] = "Detailed";
|
|
5959
5960
|
})(OutputFormat || (OutputFormat = {}));
|
|
5960
5961
|
|
|
5961
|
-
//
|
|
5962
|
+
// ../../node_modules/@cfworker/json-schema/dist/esm/ucs2-length.js
|
|
5962
5963
|
function ucs2length(s) {
|
|
5963
5964
|
let result = 0;
|
|
5964
5965
|
let length = s.length;
|
|
@@ -5977,7 +5978,7 @@ function ucs2length(s) {
|
|
|
5977
5978
|
return result;
|
|
5978
5979
|
}
|
|
5979
5980
|
|
|
5980
|
-
//
|
|
5981
|
+
// ../../node_modules/@cfworker/json-schema/dist/esm/validate.js
|
|
5981
5982
|
function validate(instance, schema, draft = "2019-09", lookup = dereference(schema), shortCircuit = true, recursiveAnchor = null, instanceLocation = "#", schemaLocation = "#", evaluated = /* @__PURE__ */ Object.create(null)) {
|
|
5982
5983
|
if (schema === true) {
|
|
5983
5984
|
return { valid: true, errors: [] };
|
|
@@ -6735,7 +6736,7 @@ Known schemas:
|
|
|
6735
6736
|
return { valid: errors.length === 0, errors };
|
|
6736
6737
|
}
|
|
6737
6738
|
|
|
6738
|
-
//
|
|
6739
|
+
// ../../node_modules/@cfworker/json-schema/dist/esm/validator.js
|
|
6739
6740
|
var Validator = class {
|
|
6740
6741
|
schema;
|
|
6741
6742
|
draft;
|
|
@@ -6758,7 +6759,7 @@ var Validator = class {
|
|
|
6758
6759
|
}
|
|
6759
6760
|
};
|
|
6760
6761
|
|
|
6761
|
-
// ../src/records/rules.ts
|
|
6762
|
+
// ../core/src/records/rules.ts
|
|
6762
6763
|
var PERMISSION_PATTERN = /^[a-z][a-zA-Z0-9]{0,39}$/;
|
|
6763
6764
|
var permissionName = (collection2, permission) => `${collection2}/${permission}`;
|
|
6764
6765
|
var isWho = (w) => w === "member" || w === "creator" || typeof w === "string" && w.startsWith("can:") && PERMISSION_PATTERN.test(w.slice(4));
|
|
@@ -6828,7 +6829,7 @@ function changedFixedField(fixed, first, next) {
|
|
|
6828
6829
|
return null;
|
|
6829
6830
|
}
|
|
6830
6831
|
|
|
6831
|
-
// ../src/records/topics.ts
|
|
6832
|
+
// ../core/src/records/topics.ts
|
|
6832
6833
|
var MAX_TOPICS = 8;
|
|
6833
6834
|
var MAX_TAGS = 64;
|
|
6834
6835
|
var TAG_BYTES = 16;
|
|
@@ -6880,7 +6881,7 @@ function sameTags(a, b) {
|
|
|
6880
6881
|
return left.length === right.length && left.every((tag, i) => tag === right[i]);
|
|
6881
6882
|
}
|
|
6882
6883
|
|
|
6883
|
-
// ../src/schema/collection-def.ts
|
|
6884
|
+
// ../core/src/schema/collection-def.ts
|
|
6884
6885
|
function toJsonSchema(schema) {
|
|
6885
6886
|
const standard = schema["~standard"];
|
|
6886
6887
|
if (!standard) return schema;
|
|
@@ -6893,6 +6894,21 @@ function toJsonSchema(schema) {
|
|
|
6893
6894
|
return json;
|
|
6894
6895
|
}
|
|
6895
6896
|
var MAX_SCREEN_BYTES = 48 * 1024;
|
|
6897
|
+
var MAX_SCREEN_ORIGINS = 8;
|
|
6898
|
+
var SCREEN_ORIGIN = /^(https|wss):\/\/[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+(:[0-9]{1,5})?$/;
|
|
6899
|
+
function checkScreenNetwork(network, hasScreen) {
|
|
6900
|
+
if (network === void 0) return null;
|
|
6901
|
+
if (!Array.isArray(network)) return 'network must be a list of origins, like ["https://api.example.com"]';
|
|
6902
|
+
if (!hasScreen && network.length) return "network is where a screen may connect; this definition has no screen";
|
|
6903
|
+
if (network.length > MAX_SCREEN_ORIGINS) return `network may name at most ${MAX_SCREEN_ORIGINS} origins`;
|
|
6904
|
+
for (const origin of network) {
|
|
6905
|
+
if (typeof origin !== "string" || !SCREEN_ORIGIN.test(origin)) {
|
|
6906
|
+
return `"${String(origin)}" is not an origin a screen may reach: give https:// or wss:// and a host, lower case, no path \u2014 like "https://api.example.com"`;
|
|
6907
|
+
}
|
|
6908
|
+
}
|
|
6909
|
+
if (new Set(network).size !== network.length) return "network names an origin twice";
|
|
6910
|
+
return null;
|
|
6911
|
+
}
|
|
6896
6912
|
var CATALOG_COLLECTION = "sys.collection";
|
|
6897
6913
|
var KEYWORDS = /* @__PURE__ */ new Set([
|
|
6898
6914
|
"type",
|
|
@@ -7029,6 +7045,8 @@ function checkStoredCollection(definition) {
|
|
|
7029
7045
|
const bytes = new TextEncoder().encode(d.screen).length;
|
|
7030
7046
|
if (bytes > MAX_SCREEN_BYTES) return `screen is ${Math.ceil(bytes / 1024)} KB; at most ${MAX_SCREEN_BYTES / 1024} KB`;
|
|
7031
7047
|
}
|
|
7048
|
+
const network = checkScreenNetwork(d.network, typeof d.screen === "string");
|
|
7049
|
+
if (network) return network;
|
|
7032
7050
|
return checkPublishableSchema(d.schema);
|
|
7033
7051
|
}
|
|
7034
7052
|
function validateJsonSchema(schema, value) {
|
|
@@ -7041,7 +7059,7 @@ function validateJsonSchema(schema, value) {
|
|
|
7041
7059
|
}));
|
|
7042
7060
|
}
|
|
7043
7061
|
|
|
7044
|
-
// ../src/utils/events.ts
|
|
7062
|
+
// ../core/src/utils/events.ts
|
|
7045
7063
|
function createEmitter() {
|
|
7046
7064
|
const listeners = /* @__PURE__ */ new Map();
|
|
7047
7065
|
return {
|
|
@@ -7063,7 +7081,7 @@ function createEmitter() {
|
|
|
7063
7081
|
};
|
|
7064
7082
|
}
|
|
7065
7083
|
|
|
7066
|
-
// ../src/network/signaling.ts
|
|
7084
|
+
// ../core/src/network/signaling.ts
|
|
7067
7085
|
var SIGNAL_KINDS = /* @__PURE__ */ new Set(["offer", "answer", "candidate"]);
|
|
7068
7086
|
function iceFrom(payload) {
|
|
7069
7087
|
const { servers, expiresAt } = payload ?? {};
|
|
@@ -7180,7 +7198,7 @@ function createSignalingClient(url, did) {
|
|
|
7180
7198
|
});
|
|
7181
7199
|
}
|
|
7182
7200
|
|
|
7183
|
-
// ../src/network/multi-signaling.ts
|
|
7201
|
+
// ../core/src/network/multi-signaling.ts
|
|
7184
7202
|
function createMultiSignalingClient(urls, did) {
|
|
7185
7203
|
if (urls.length === 0) {
|
|
7186
7204
|
throw new Error("At least one relay is needed to introduce peers.");
|
|
@@ -7314,7 +7332,7 @@ function createMultiSignalingClient(urls, did) {
|
|
|
7314
7332
|
});
|
|
7315
7333
|
}
|
|
7316
7334
|
|
|
7317
|
-
// ../src/network/introductions.ts
|
|
7335
|
+
// ../core/src/network/introductions.ts
|
|
7318
7336
|
var PEERS_MESSAGE = "__peers";
|
|
7319
7337
|
var SIGNAL_MESSAGE = "__signal";
|
|
7320
7338
|
var AUTH_HELLO_MESSAGE = "__auth-hello";
|
|
@@ -7353,7 +7371,7 @@ function signalId() {
|
|
|
7353
7371
|
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
7354
7372
|
}
|
|
7355
7373
|
|
|
7356
|
-
// ../src/network/rtc-transport.ts
|
|
7374
|
+
// ../core/src/network/rtc-transport.ts
|
|
7357
7375
|
function fingerprintOf2(description) {
|
|
7358
7376
|
const match = description?.sdp?.match(/^a=fingerprint:\s*(\S+)\s+(\S+)/im);
|
|
7359
7377
|
return match ? `${match[1].toLowerCase()} ${match[2].toUpperCase()}` : null;
|
|
@@ -7489,7 +7507,8 @@ function createRTCTransport(config) {
|
|
|
7489
7507
|
});
|
|
7490
7508
|
}
|
|
7491
7509
|
|
|
7492
|
-
// ../src/network/peer-auth.ts
|
|
7510
|
+
// ../core/src/network/peer-auth.ts
|
|
7511
|
+
var MAX_EARLIER_READ_KEYS = 4;
|
|
7493
7512
|
function readAccessOf(read) {
|
|
7494
7513
|
if (!read) return null;
|
|
7495
7514
|
if ("current" in read) return read;
|
|
@@ -7500,16 +7519,22 @@ async function proveRead(access, label, provider) {
|
|
|
7500
7519
|
const key3 = await access.key();
|
|
7501
7520
|
if (!key3) return null;
|
|
7502
7521
|
const read = base64UrlEncode(await provider.sign(key3.privateKey, label));
|
|
7503
|
-
if (key3.did
|
|
7522
|
+
if (!key3.did) return { read };
|
|
7504
7523
|
const member = await access.membership?.() ?? null;
|
|
7505
|
-
|
|
7524
|
+
const older = (await access.earlier?.() ?? []).filter((held) => held.did !== key3.did).slice(0, MAX_EARLIER_READ_KEYS);
|
|
7525
|
+
const earlier = await Promise.all(older.map(async (held) => ({ readKey: held.did, read: base64UrlEncode(await provider.sign(held.privateKey, label)) })));
|
|
7526
|
+
return { read, readKey: key3.did, ...member ? { member } : {}, ...earlier.length ? { earlier } : {} };
|
|
7506
7527
|
}
|
|
7507
7528
|
async function checkRead(access, peerDid, label, proof, provider) {
|
|
7508
7529
|
const current = access.current();
|
|
7509
7530
|
const claimed = typeof proof.readKey === "string" ? proof.readKey : current;
|
|
7510
|
-
if (
|
|
7511
|
-
|
|
7512
|
-
|
|
7531
|
+
if (claimed.startsWith("did:key:") && await verifyBy(provider, claimed, proof.read, label)) {
|
|
7532
|
+
if (claimed === current) return true;
|
|
7533
|
+
if (access.admits && await access.admits(peerDid, claimed, proof.member)) return true;
|
|
7534
|
+
}
|
|
7535
|
+
const earlier = Array.isArray(proof.earlier) ? proof.earlier.slice(0, MAX_EARLIER_READ_KEYS) : [];
|
|
7536
|
+
const ours = earlier.find((item) => item?.readKey === current);
|
|
7537
|
+
return ours !== void 0 && current.startsWith("did:key:") && verifyBy(provider, current, ours.read, label);
|
|
7513
7538
|
}
|
|
7514
7539
|
function peerNonce() {
|
|
7515
7540
|
return base64UrlEncode(globalThis.crypto.getRandomValues(new Uint8Array(16)));
|
|
@@ -7575,7 +7600,7 @@ function createMeshAuth(spaceId, session, read, provider) {
|
|
|
7575
7600
|
});
|
|
7576
7601
|
}
|
|
7577
7602
|
|
|
7578
|
-
// ../src/network/ws-transport.ts
|
|
7603
|
+
// ../core/src/network/ws-transport.ts
|
|
7579
7604
|
function parseFrame(data, type) {
|
|
7580
7605
|
if (typeof data !== "string") return null;
|
|
7581
7606
|
try {
|
|
@@ -7721,7 +7746,7 @@ function createWebSocketTransport(config) {
|
|
|
7721
7746
|
});
|
|
7722
7747
|
}
|
|
7723
7748
|
|
|
7724
|
-
// ../src/network/mesh.ts
|
|
7749
|
+
// ../core/src/network/mesh.ts
|
|
7725
7750
|
var ICE_REFRESH_MS = 10 * 6e4;
|
|
7726
7751
|
var ICE_WAIT_MS = 1500;
|
|
7727
7752
|
function createMesh(config) {
|
|
@@ -8002,7 +8027,7 @@ function createMesh(config) {
|
|
|
8002
8027
|
};
|
|
8003
8028
|
}
|
|
8004
8029
|
|
|
8005
|
-
// ../src/network/network-manager.ts
|
|
8030
|
+
// ../core/src/network/network-manager.ts
|
|
8006
8031
|
function createNetworkManager(config) {
|
|
8007
8032
|
const transport = config.createTransport();
|
|
8008
8033
|
const peers = /* @__PURE__ */ new Map();
|
|
@@ -8048,7 +8073,7 @@ function createNetworkManager(config) {
|
|
|
8048
8073
|
});
|
|
8049
8074
|
}
|
|
8050
8075
|
|
|
8051
|
-
// ../src/sync/sync-messages.ts
|
|
8076
|
+
// ../core/src/sync/sync-messages.ts
|
|
8052
8077
|
var SYNC_PROTOCOL_VERSION = 4;
|
|
8053
8078
|
function parseSyncMessage(value) {
|
|
8054
8079
|
const message = value;
|
|
@@ -8056,7 +8081,7 @@ function parseSyncMessage(value) {
|
|
|
8056
8081
|
return message;
|
|
8057
8082
|
}
|
|
8058
8083
|
|
|
8059
|
-
// ../src/sync/sync-engine.ts
|
|
8084
|
+
// ../core/src/sync/sync-engine.ts
|
|
8060
8085
|
var MAX_WAITING = 1e3;
|
|
8061
8086
|
var MAX_REFUSED = 1e4;
|
|
8062
8087
|
var holdsCollection = (holds2, collection2) => collection2.startsWith("sys.") || holds2 === "all" || holds2.has(collection2);
|
|
@@ -8344,7 +8369,7 @@ ${id}`;
|
|
|
8344
8369
|
};
|
|
8345
8370
|
}
|
|
8346
8371
|
|
|
8347
|
-
// ../src/validation/crypto-gate.ts
|
|
8372
|
+
// ../core/src/validation/crypto-gate.ts
|
|
8348
8373
|
function createCryptoGate(provider) {
|
|
8349
8374
|
return {
|
|
8350
8375
|
async validate(expression, resolvePublicKey) {
|
|
@@ -8371,7 +8396,7 @@ function createCryptoGate(provider) {
|
|
|
8371
8396
|
};
|
|
8372
8397
|
}
|
|
8373
8398
|
|
|
8374
|
-
// ../src/validation/structural-gate.ts
|
|
8399
|
+
// ../core/src/validation/structural-gate.ts
|
|
8375
8400
|
function isEncryptedBody(body) {
|
|
8376
8401
|
if (!body || typeof body !== "object") return false;
|
|
8377
8402
|
const envelope = body;
|
|
@@ -8405,7 +8430,7 @@ function createStructuralGate(schemaEngine, options = {}) {
|
|
|
8405
8430
|
};
|
|
8406
8431
|
}
|
|
8407
8432
|
|
|
8408
|
-
// ../src/validation/stateful-gate.ts
|
|
8433
|
+
// ../core/src/validation/stateful-gate.ts
|
|
8409
8434
|
function createStatefulGate() {
|
|
8410
8435
|
const rules = /* @__PURE__ */ new Map();
|
|
8411
8436
|
return {
|
|
@@ -8451,7 +8476,7 @@ function createStatefulGate() {
|
|
|
8451
8476
|
};
|
|
8452
8477
|
}
|
|
8453
8478
|
|
|
8454
|
-
// ../src/validation/capability-gate.ts
|
|
8479
|
+
// ../core/src/validation/capability-gate.ts
|
|
8455
8480
|
var fail = (reason) => ({ passed: false, gate: "capability", reason });
|
|
8456
8481
|
var MAX_CLOCK_SKEW_SECONDS = 300;
|
|
8457
8482
|
function createCapabilityGate(config) {
|
|
@@ -8494,7 +8519,7 @@ function createCapabilityGate(config) {
|
|
|
8494
8519
|
};
|
|
8495
8520
|
}
|
|
8496
8521
|
|
|
8497
|
-
// ../src/validation/validation-engine.ts
|
|
8522
|
+
// ../core/src/validation/validation-engine.ts
|
|
8498
8523
|
function createValidationEngine(config) {
|
|
8499
8524
|
const { cryptoGate, structuralGate, statefulGate, capabilityGate, resolvePublicKey, getExpression } = config;
|
|
8500
8525
|
return {
|
|
@@ -8520,7 +8545,7 @@ function createValidationEngine(config) {
|
|
|
8520
8545
|
};
|
|
8521
8546
|
}
|
|
8522
8547
|
|
|
8523
|
-
// ../src/query/filter.ts
|
|
8548
|
+
// ../core/src/query/filter.ts
|
|
8524
8549
|
var MAX_INCLUDE_DEPTH = 3;
|
|
8525
8550
|
var META = {
|
|
8526
8551
|
"@key": (r) => r.key,
|
|
@@ -8684,7 +8709,7 @@ function checkQuery(query) {
|
|
|
8684
8709
|
return null;
|
|
8685
8710
|
}
|
|
8686
8711
|
|
|
8687
|
-
// ../src/query/types.ts
|
|
8712
|
+
// ../core/src/query/types.ts
|
|
8688
8713
|
var nameOf = (ref) => typeof ref === "object" && ref !== null && typeof ref.name === "string" ? ref.name : ref;
|
|
8689
8714
|
function plainQuery(query) {
|
|
8690
8715
|
const isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
@@ -8698,7 +8723,7 @@ function plainQuery(query) {
|
|
|
8698
8723
|
return { ...query, collection: nameOf(query.collection), ...query.include !== void 0 ? { include: includes(query.include) } : {} };
|
|
8699
8724
|
}
|
|
8700
8725
|
|
|
8701
|
-
// ../src/query/engine.ts
|
|
8726
|
+
// ../core/src/query/engine.ts
|
|
8702
8727
|
function compareValues(a, b) {
|
|
8703
8728
|
if (a === b) return 0;
|
|
8704
8729
|
if (a === void 0 || a === null) return -1;
|
|
@@ -8758,7 +8783,7 @@ async function runQuery(source, given) {
|
|
|
8758
8783
|
return { records, cursor: more ? page[page.length - 1].key : null, complete: true };
|
|
8759
8784
|
}
|
|
8760
8785
|
|
|
8761
|
-
// ../src/storage/segment.ts
|
|
8786
|
+
// ../core/src/storage/segment.ts
|
|
8762
8787
|
var SEGMENT_SUFFIX = ".seg";
|
|
8763
8788
|
function packSegment(versions) {
|
|
8764
8789
|
return utf8Encode(JSON.stringify({ v: 1, versions }));
|
|
@@ -8778,7 +8803,7 @@ async function segmentName(counter, bytes) {
|
|
|
8778
8803
|
}
|
|
8779
8804
|
var versionSize = (version) => utf8Encode(JSON.stringify(version)).length;
|
|
8780
8805
|
|
|
8781
|
-
// ../src/storage/mirror.ts
|
|
8806
|
+
// ../core/src/storage/mirror.ts
|
|
8782
8807
|
var WRITER_KEY = "mirror:writer";
|
|
8783
8808
|
var COUNTER_KEY = "mirror:counter";
|
|
8784
8809
|
var readKey = (name) => `mirror:read:${name}`;
|
|
@@ -8924,7 +8949,7 @@ async function createMirror(config) {
|
|
|
8924
8949
|
});
|
|
8925
8950
|
}
|
|
8926
8951
|
|
|
8927
|
-
// ../src/space/pass.ts
|
|
8952
|
+
// ../core/src/space/pass.ts
|
|
8928
8953
|
var PASS_COLLECTION = "sys.pass";
|
|
8929
8954
|
var CARRY_CLOSED_KEY = "carry:closed";
|
|
8930
8955
|
async function passKey(spaceId) {
|
|
@@ -8955,7 +8980,7 @@ function carriedRecord(pass) {
|
|
|
8955
8980
|
return { space: pass.space, key: null, invite: null, role: null, read: pass.read };
|
|
8956
8981
|
}
|
|
8957
8982
|
|
|
8958
|
-
// ../src/node/space-runtime.ts
|
|
8983
|
+
// ../core/src/node/space-runtime.ts
|
|
8959
8984
|
var MANAGED = /* @__PURE__ */ new Set([MEMBERSHIP_COLLECTION, PROFILE_COLLECTION, CARRIER_COLLECTION, PASS_COLLECTION, BOX_COLLECTION, MEMBER_KEY_COLLECTION, ...ACCESS_COLLECTIONS]);
|
|
8960
8985
|
var IN_THE_CLEAR = /* @__PURE__ */ new Set([ROLE_COLLECTION, MEMBER_COLLECTION, INVITE_COLLECTION, REVOKE_COLLECTION, KEY_COLLECTION, BOX_COLLECTION, MEMBER_KEY_COLLECTION, RELAYS_COLLECTION, KEEPERS_COLLECTION]);
|
|
8961
8986
|
var ACCESS_KEYS = [
|
|
@@ -9462,6 +9487,7 @@ async function openSpaceRuntime(deps) {
|
|
|
9462
9487
|
rules: definition?.rules ?? {},
|
|
9463
9488
|
topics: definition?.topics ?? [],
|
|
9464
9489
|
...definition?.screen !== void 0 ? { screen: definition.screen } : {},
|
|
9490
|
+
...definition?.network?.length ? { network: definition.network } : {},
|
|
9465
9491
|
records
|
|
9466
9492
|
});
|
|
9467
9493
|
}
|
|
@@ -9701,6 +9727,12 @@ async function openSpaceRuntime(deps) {
|
|
|
9701
9727
|
return held ? deriveReadKey(held, provider) : record.read ?? null;
|
|
9702
9728
|
},
|
|
9703
9729
|
current: () => currentReadKey,
|
|
9730
|
+
async earlier() {
|
|
9731
|
+
const { current } = (await access()).history;
|
|
9732
|
+
const newest = newestKey(current);
|
|
9733
|
+
const older = [...current.keys].reverse().map((epoch) => keyring.get(epoch.keyId)).filter((held) => held !== void 0 && held !== newest);
|
|
9734
|
+
return Promise.all(older.slice(0, MAX_EARLIER_READ_KEYS).map((held) => deriveReadKey(held, provider)));
|
|
9735
|
+
},
|
|
9704
9736
|
async membership() {
|
|
9705
9737
|
const held = newestKey((await access()).history.current);
|
|
9706
9738
|
return held ? sealWith(held, session.proof(), membershipContext(space2.id)) : null;
|
|
@@ -9898,7 +9930,7 @@ async function openSpaceRuntime(deps) {
|
|
|
9898
9930
|
channel.unref?.();
|
|
9899
9931
|
}
|
|
9900
9932
|
const HOUR = 36e5;
|
|
9901
|
-
const
|
|
9933
|
+
const DAY3 = 24 * HOUR;
|
|
9902
9934
|
const declared = new Set((cache?.collections ?? []).filter((c) => !c.startsWith("sys.")));
|
|
9903
9935
|
let cacheTimer = null;
|
|
9904
9936
|
const saveCache = () => {
|
|
@@ -9986,7 +10018,7 @@ async function openSpaceRuntime(deps) {
|
|
|
9986
10018
|
});
|
|
9987
10019
|
async function dropUnused() {
|
|
9988
10020
|
if (!cache || !partial || closed) return;
|
|
9989
|
-
const cutoff = Date.now() - (cache.unusedAfterDays ?? 30) *
|
|
10021
|
+
const cutoff = Date.now() - (cache.unusedAfterDays ?? 30) * DAY3;
|
|
9990
10022
|
const waiting = /* @__PURE__ */ new Set();
|
|
9991
10023
|
for (const name of await adapter.list(PENDING_PREFIX)) {
|
|
9992
10024
|
const bytes = await adapter.get(name);
|
|
@@ -10266,7 +10298,8 @@ async function openSpaceRuntime(deps) {
|
|
|
10266
10298
|
...input.permissions !== void 0 ? { permissions: input.permissions } : {},
|
|
10267
10299
|
...input.rules !== void 0 ? { rules: input.rules } : {},
|
|
10268
10300
|
...input.topics !== void 0 ? { topics: input.topics } : {},
|
|
10269
|
-
...input.screen !== void 0 ? { screen: input.screen } : {}
|
|
10301
|
+
...input.screen !== void 0 ? { screen: input.screen } : {},
|
|
10302
|
+
...input.network?.length ? { network: input.network } : {}
|
|
10270
10303
|
};
|
|
10271
10304
|
const problem = checkStoredCollection(definition);
|
|
10272
10305
|
if (problem) throw new Error(problem);
|
|
@@ -10414,7 +10447,7 @@ async function openSpaceRuntime(deps) {
|
|
|
10414
10447
|
});
|
|
10415
10448
|
}
|
|
10416
10449
|
|
|
10417
|
-
// ../src/schemas/contacts.ts
|
|
10450
|
+
// ../core/src/schemas/contacts.ts
|
|
10418
10451
|
var typed = () => (definition) => definition;
|
|
10419
10452
|
var contact = typed()({
|
|
10420
10453
|
name: "std.contact",
|
|
@@ -10495,7 +10528,7 @@ var knockAnswer = typed()({
|
|
|
10495
10528
|
rules: { edit: "creator", delete: "creator" }
|
|
10496
10529
|
});
|
|
10497
10530
|
|
|
10498
|
-
// ../src/doors/doors.ts
|
|
10531
|
+
// ../core/src/doors/doors.ts
|
|
10499
10532
|
var MAX_DOOR_RELAYS = 3;
|
|
10500
10533
|
var KNOCK_TTL_SECONDS = 14 * 24 * 3600;
|
|
10501
10534
|
var KNOCK_DROP_WINDOW_SECONDS = 600;
|
|
@@ -10622,7 +10655,7 @@ async function openKnock(doorKey, blob, receivedAt, provider) {
|
|
|
10622
10655
|
});
|
|
10623
10656
|
}
|
|
10624
10657
|
|
|
10625
|
-
// ../src/network/mailbox.ts
|
|
10658
|
+
// ../core/src/network/mailbox.ts
|
|
10626
10659
|
var MAX_PAGES = 8;
|
|
10627
10660
|
function createMailboxClient(options = {}) {
|
|
10628
10661
|
const timeoutMs = options.timeoutMs ?? 8e3;
|
|
@@ -10716,7 +10749,7 @@ function isMailItem(value) {
|
|
|
10716
10749
|
return !!item && Number.isSafeInteger(item.seq) && typeof item.id === "string" && typeof item.at === "number" && typeof item.blob === "string";
|
|
10717
10750
|
}
|
|
10718
10751
|
|
|
10719
|
-
// ../src/space/notify.ts
|
|
10752
|
+
// ../core/src/space/notify.ts
|
|
10720
10753
|
var NOTIFY_COLLECTION = "sys.notify";
|
|
10721
10754
|
var SUBSCRIPTION_COLLECTION = "sys.subscription";
|
|
10722
10755
|
var COLLECTION = /^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/;
|
|
@@ -10744,8 +10777,21 @@ function checkNotify(when) {
|
|
|
10744
10777
|
}
|
|
10745
10778
|
}
|
|
10746
10779
|
if (typeof w.since !== "string" || !Number.isFinite(Date.parse(w.since))) return "since must be a date";
|
|
10780
|
+
if (w.app !== void 0) {
|
|
10781
|
+
const a = w.app;
|
|
10782
|
+
if (typeof a !== "object" || a === null || typeof a.origin !== "string" || !isOrigin(a.origin)) return "app.origin must be a web origin";
|
|
10783
|
+
if (a.name !== void 0 && (typeof a.name !== "string" || a.name.length > 80)) return "app.name must be text, at most 80 characters";
|
|
10784
|
+
}
|
|
10747
10785
|
return null;
|
|
10748
10786
|
}
|
|
10787
|
+
function isOrigin(value) {
|
|
10788
|
+
if (/^(chrome|moz|safari-web)-extension:\/\/[a-z0-9-]{1,64}$/i.test(value)) return true;
|
|
10789
|
+
try {
|
|
10790
|
+
return new URL(value).origin === value;
|
|
10791
|
+
} catch {
|
|
10792
|
+
return false;
|
|
10793
|
+
}
|
|
10794
|
+
}
|
|
10749
10795
|
async function carriedFor(when, spaces) {
|
|
10750
10796
|
let tags;
|
|
10751
10797
|
if (when.topic) {
|
|
@@ -10803,7 +10849,7 @@ function matchesSubscription(sub, spaceId, version, account, now = Date.now()) {
|
|
|
10803
10849
|
return true;
|
|
10804
10850
|
}
|
|
10805
10851
|
|
|
10806
|
-
// ../src/session/hosting.ts
|
|
10852
|
+
// ../core/src/session/hosting.ts
|
|
10807
10853
|
var HOSTING_COLLECTION = "sys.hosting";
|
|
10808
10854
|
var REQUEST_WINDOW_SECONDS = 300;
|
|
10809
10855
|
function newSubscriptionSeed() {
|
|
@@ -10919,7 +10965,7 @@ function createHostClient(url, host, key3, provider = createP256Provider()) {
|
|
|
10919
10965
|
});
|
|
10920
10966
|
}
|
|
10921
10967
|
|
|
10922
|
-
// ../src/node/node.ts
|
|
10968
|
+
// ../core/src/node/node.ts
|
|
10923
10969
|
var SESSION_CAPABILITY = { with: "*", can: "expression/*" };
|
|
10924
10970
|
var DEFAULT_TTL_SECONDS = 3600;
|
|
10925
10971
|
var FORGET_CARRIER_AFTER_MS = 30 * 24 * 3600 * 1e3;
|
|
@@ -12344,7 +12390,7 @@ async function createNode(config) {
|
|
|
12344
12390
|
return node;
|
|
12345
12391
|
}
|
|
12346
12392
|
|
|
12347
|
-
// ../src/node/stores.ts
|
|
12393
|
+
// ../core/src/node/stores.ts
|
|
12348
12394
|
function folderStores(directory2, options = {}) {
|
|
12349
12395
|
return async (path7, storeOptions) => {
|
|
12350
12396
|
const full = options.basePath ? `${options.basePath}/${path7}` : path7;
|
|
@@ -12353,7 +12399,7 @@ function folderStores(directory2, options = {}) {
|
|
|
12353
12399
|
};
|
|
12354
12400
|
}
|
|
12355
12401
|
|
|
12356
|
-
// ../src/network/local-transport.ts
|
|
12402
|
+
// ../core/src/network/local-transport.ts
|
|
12357
12403
|
var later = (fn) => void setTimeout(fn, 0);
|
|
12358
12404
|
function createLocalHub() {
|
|
12359
12405
|
const connected = /* @__PURE__ */ new Map();
|
|
@@ -12399,7 +12445,7 @@ function createLocalHub() {
|
|
|
12399
12445
|
};
|
|
12400
12446
|
}
|
|
12401
12447
|
|
|
12402
|
-
// ../src/node/carrier.ts
|
|
12448
|
+
// ../core/src/node/carrier.ts
|
|
12403
12449
|
async function createCarryCore(config) {
|
|
12404
12450
|
const provider = config.provider ?? createP256Provider();
|
|
12405
12451
|
const signer = createSigner(provider);
|
|
@@ -12604,6 +12650,16 @@ async function createCarryCore(config) {
|
|
|
12604
12650
|
await refreshing;
|
|
12605
12651
|
return [...carries.values()].flatMap((entry) => [...entry.subscriptions].map(([id, sub]) => view(id, sub)));
|
|
12606
12652
|
},
|
|
12653
|
+
async collections(spaceId) {
|
|
12654
|
+
const entry = carried.get(spaceId);
|
|
12655
|
+
if (!entry || carries.has(spaceId)) return [];
|
|
12656
|
+
return (await entry.runtime.collections()).map((found) => ({
|
|
12657
|
+
name: found.name,
|
|
12658
|
+
...found.title ? { title: found.title } : {},
|
|
12659
|
+
topics: found.topics,
|
|
12660
|
+
records: found.records
|
|
12661
|
+
}));
|
|
12662
|
+
},
|
|
12607
12663
|
async spaces() {
|
|
12608
12664
|
const found = [];
|
|
12609
12665
|
for (const [spaceId, entry] of carried) {
|
|
@@ -12630,7 +12686,7 @@ async function createCarryCore(config) {
|
|
|
12630
12686
|
};
|
|
12631
12687
|
}
|
|
12632
12688
|
|
|
12633
|
-
// ../src/node/host.ts
|
|
12689
|
+
// ../core/src/node/host.ts
|
|
12634
12690
|
var SUBSCRIPTION_PREFIX = "subscription:";
|
|
12635
12691
|
var NotAllowedError = class extends Error {
|
|
12636
12692
|
constructor() {
|
|
@@ -12792,7 +12848,7 @@ async function createHostNode(config) {
|
|
|
12792
12848
|
return Object.freeze(host);
|
|
12793
12849
|
}
|
|
12794
12850
|
|
|
12795
|
-
// ../src/records/describe.ts
|
|
12851
|
+
// ../core/src/records/describe.ts
|
|
12796
12852
|
var KNOWN_RULES = ["create", "edit", "delete", "onePer", "fixed"];
|
|
12797
12853
|
var words = (name) => name.replace(/^.*\./, "").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").toLowerCase();
|
|
12798
12854
|
var article = (noun) => /^[aeiou]/.test(noun) ? `an ${noun}` : `a ${noun}`;
|
|
@@ -12867,10 +12923,14 @@ function describeCollection(definition) {
|
|
|
12867
12923
|
sentences.push(`Roles in the space can be given permission to ${list}.`);
|
|
12868
12924
|
}
|
|
12869
12925
|
if (definition.history === "all") sentences.push(`Every earlier version of ${a} is kept.`);
|
|
12926
|
+
if (definition.network?.length) {
|
|
12927
|
+
const hosts = joinAnd(definition.network.map((origin) => origin.replace(/^[a-z]+:\/\//, "")));
|
|
12928
|
+
sentences.push(`Its screen can connect to ${hosts}, and send there anything the person looking can see in it. Each person is asked first.`);
|
|
12929
|
+
}
|
|
12870
12930
|
return sentences;
|
|
12871
12931
|
}
|
|
12872
12932
|
|
|
12873
|
-
// ../src/schemas/apps.ts
|
|
12933
|
+
// ../core/src/schemas/apps.ts
|
|
12874
12934
|
var MAX_APP_COLLECTIONS = 10;
|
|
12875
12935
|
var app = {
|
|
12876
12936
|
name: "std.app",
|
|
@@ -12926,7 +12986,8 @@ function essence(definition) {
|
|
|
12926
12986
|
links: canonicalize(definition.links ?? {}),
|
|
12927
12987
|
permissions: canonicalize([...definition.permissions ?? []].sort()),
|
|
12928
12988
|
rules: canonicalize(definition.rules ?? {}),
|
|
12929
|
-
screen: definition.screen ?? ""
|
|
12989
|
+
screen: definition.screen ?? "",
|
|
12990
|
+
network: canonicalize([...definition.network ?? []].sort())
|
|
12930
12991
|
};
|
|
12931
12992
|
}
|
|
12932
12993
|
var fieldNames = (schema) => Object.keys(schema?.properties ?? {});
|
|
@@ -12945,12 +13006,17 @@ function differences(held, wanted) {
|
|
|
12945
13006
|
if (a.links !== b.links) out.push("changes what it points at");
|
|
12946
13007
|
if (a.history !== b.history) out.push(b.history === "all" ? "starts keeping every version" : "stops keeping old versions");
|
|
12947
13008
|
if (a.screen !== b.screen) out.push(!b.screen ? "takes its screen away" : !a.screen ? "gives it a screen" : "changes its screen");
|
|
13009
|
+
if (a.network !== b.network) {
|
|
13010
|
+
const before2 = new Set(held.network ?? []);
|
|
13011
|
+
const reached = (wanted.network ?? []).filter((origin) => !before2.has(origin));
|
|
13012
|
+
out.push(reached.length ? `lets its screen reach ${reached.join(", ")}` : "lets its screen reach fewer places");
|
|
13013
|
+
}
|
|
12948
13014
|
if (a.title !== b.title || a.description !== b.description) out.push("renames or redescribes it");
|
|
12949
13015
|
return out;
|
|
12950
13016
|
}
|
|
12951
13017
|
function appScreen(body) {
|
|
12952
13018
|
const found = body.needs.find((need) => typeof need.screen === "string" && need.screen.trim());
|
|
12953
|
-
return found ? { collection: found.name, screen: found.screen } : null;
|
|
13019
|
+
return found ? { collection: found.name, screen: found.screen, network: found.network ?? [] } : null;
|
|
12954
13020
|
}
|
|
12955
13021
|
function reviewApp(body, collections) {
|
|
12956
13022
|
const problem = checkApp(body);
|
|
@@ -12971,11 +13037,17 @@ async function proposeApp(node, spaceId, body) {
|
|
|
12971
13037
|
return node.records.put(spaceId, app.name, body);
|
|
12972
13038
|
}
|
|
12973
13039
|
|
|
12974
|
-
// ../src/schemas/screens.ts
|
|
13040
|
+
// ../core/src/schemas/screens.ts
|
|
12975
13041
|
var SCREEN_GUIDE = `A screen is one HTML document (scripts and styles inline, at most 48 KB) put on a collection definition as "screen".
|
|
12976
13042
|
When the app is added, apps in the space can show it instead of plain lists. It runs sealed: no network (no fetch, no
|
|
12977
13043
|
images from URLs, no fonts from URLs), no storage, no popups, no forms that submit. Keep state in records, never in the page.
|
|
12978
13044
|
|
|
13045
|
+
If it truly needs the network \u2014 weather, a map, a timetable \u2014 give its collection "network": the exact origins it may
|
|
13046
|
+
fetch from and load images from, like ["https://api.open-meteo.com"] (https:// or wss://, a host, no path; at most 8).
|
|
13047
|
+
Nothing else is reachable, and fonts never are. Each origin is named when people review the app, and each person is asked
|
|
13048
|
+
before a screen they open gets it: a person who says no gets the screen sealed, so it must still work without them.
|
|
13049
|
+
Ask for no more than it needs.
|
|
13050
|
+
|
|
12979
13051
|
Inside it, window.weave is:
|
|
12980
13052
|
weave.me { did, name } \u2014 who is looking
|
|
12981
13053
|
weave.collections the collection names this screen may use (its app's)
|
|
@@ -12997,7 +13069,7 @@ Draw everything from weave.list(...) and redraw on weave.onChange \u2014 other p
|
|
|
12997
13069
|
Two people can write at once: design collections so that clashes resolve by the rules (onePer, creator-only edits), not by the screen.
|
|
12998
13070
|
Use plain DOM; no libraries can be loaded. Prefer system fonts and simple, readable styling that works in light and dark.`;
|
|
12999
13071
|
|
|
13000
|
-
// ../src/node/actions.ts
|
|
13072
|
+
// ../core/src/node/actions.ts
|
|
13001
13073
|
var space = { type: "string", description: "Space id, from spaces_list" };
|
|
13002
13074
|
var key2 = { type: "string", description: "Record key \u2014 stays the same when the record is edited" };
|
|
13003
13075
|
var str = (input, key3) => input[key3];
|
|
@@ -13178,7 +13250,12 @@ var NODE_ACTIONS = Object.freeze([
|
|
|
13178
13250
|
type: "object",
|
|
13179
13251
|
description: 'What its records allow, enforced by every peer: { "create": "member", "edit": "creator", "delete": ["creator", "can:moderate"], "onePer": ["@author", "link:about"], "fixed": ["options"] }. Who is "member" (anyone holding a role here, the default), "creator" (whoever created that record) or "can:<permission>" (anyone whose role holds one of the permissions declared above). onePer makes at most one record per author + linked record (+ body field): writing again changes it. fixed fields keep their first value.'
|
|
13180
13252
|
},
|
|
13181
|
-
screen: { type: "string", description: "Optional: its own screen, one HTML document \u2014 read apps_screen_guide first" }
|
|
13253
|
+
screen: { type: "string", description: "Optional: its own screen, one HTML document \u2014 read apps_screen_guide first" },
|
|
13254
|
+
network: {
|
|
13255
|
+
type: "array",
|
|
13256
|
+
items: { type: "string" },
|
|
13257
|
+
description: 'Optional, with a screen: the exact origins it may connect to and load images from, like ["https://api.open-meteo.com"]. None keeps it sealed. Each is named when people review the app, and each person is asked before their screen gets them.'
|
|
13258
|
+
}
|
|
13182
13259
|
},
|
|
13183
13260
|
required: ["space", "name", "schema"]
|
|
13184
13261
|
},
|
|
@@ -13195,7 +13272,8 @@ var NODE_ACTIONS = Object.freeze([
|
|
|
13195
13272
|
...typeof input.links === "object" && input.links !== null ? { links: input.links } : {},
|
|
13196
13273
|
...Array.isArray(input.permissions) ? { permissions: input.permissions.filter((p) => typeof p === "string") } : {},
|
|
13197
13274
|
...typeof input.rules === "object" && input.rules !== null ? { rules: input.rules } : {},
|
|
13198
|
-
...typeof input.screen === "string" ? { screen: input.screen } : {}
|
|
13275
|
+
...typeof input.screen === "string" ? { screen: input.screen } : {},
|
|
13276
|
+
...Array.isArray(input.network) ? { network: input.network.filter((o) => typeof o === "string") } : {}
|
|
13199
13277
|
});
|
|
13200
13278
|
return { ...defined, summary: describeCollection({ ...defined, schema: defined.schema ?? void 0 }) };
|
|
13201
13279
|
}
|
|
@@ -13228,14 +13306,14 @@ var NODE_ACTIONS = Object.freeze([
|
|
|
13228
13306
|
},
|
|
13229
13307
|
{
|
|
13230
13308
|
name: "apps_screen_guide",
|
|
13231
|
-
description: `How to write a screen \u2014 an app's own HTML UI, kept on its main collection's definition as "screen" and run sealed in the app: what it can use (window.weave: list, put, update, remove, onChange, me) and what it can't (
|
|
13309
|
+
description: `How to write a screen \u2014 an app's own HTML UI, kept on its main collection's definition as "screen" and run sealed in the app: what it can use (window.weave: list, put, update, remove, onChange, me) and what it can't (storage, and the network beyond the origins it names).`,
|
|
13232
13310
|
input: { type: "object", properties: {} },
|
|
13233
13311
|
readOnly: true,
|
|
13234
13312
|
run: async () => SCREEN_GUIDE
|
|
13235
13313
|
},
|
|
13236
13314
|
{
|
|
13237
13315
|
name: "apps_propose",
|
|
13238
|
-
description: `Propose an app in a space: a new way for its people to work together \u2014 a carpool, a sign-up sheet, a decision log. Give it a title, a line on what it is for, and the collections it needs, each exactly as collections_define takes it (name, title, description, schema, links, permissions, rules \u2014 no version). Nothing is defined yet: everyone in the space sees the proposal, with what it allows worked out from its rules, and a person who may define collections adds it. Read collections_list first and reuse what the space already has (std.poll, std.task\u2026) rather than inventing a twin. For anything plain lists and forms can't show \u2014 a game board, a calendar, a whiteboard \u2014 give the main collection a "screen": its own HTML UI (one document, inline scripts and styles, no network). Inside it, use exactly: weave.me ({ did, name }), await weave.list("<collection>", { where: { "link:<rel>": key } }), await weave.put("<collection>", body, { links: [{ rel, to: key }] }), await weave.update(key, body), await weave.remove(key), weave.onChange(redraw). Records are { key, body, links, createdBy, mine }. Read apps_screen_guide for the rest. Returns what each collection will allow; tell the person that, not your own description.`,
|
|
13316
|
+
description: `Propose an app in a space: a new way for its people to work together \u2014 a carpool, a sign-up sheet, a decision log. Give it a title, a line on what it is for, and the collections it needs, each exactly as collections_define takes it (name, title, description, schema, links, permissions, rules \u2014 no version). Nothing is defined yet: everyone in the space sees the proposal, with what it allows worked out from its rules, and a person who may define collections adds it. Read collections_list first and reuse what the space already has (std.poll, std.task\u2026) rather than inventing a twin. For anything plain lists and forms can't show \u2014 a game board, a calendar, a whiteboard \u2014 give the main collection a "screen": its own HTML UI (one document, inline scripts and styles, no network unless the collection names exact origins in "network"). Inside it, use exactly: weave.me ({ did, name }), await weave.list("<collection>", { where: { "link:<rel>": key } }), await weave.put("<collection>", body, { links: [{ rel, to: key }] }), await weave.update(key, body), await weave.remove(key), weave.onChange(redraw). Records are { key, body, links, createdBy, mine }. Read apps_screen_guide for the rest. Returns what each collection will allow; tell the person that, not your own description.`,
|
|
13239
13317
|
input: {
|
|
13240
13318
|
type: "object",
|
|
13241
13319
|
properties: {
|
|
@@ -13438,7 +13516,7 @@ async function runAction(node, name, input = {}) {
|
|
|
13438
13516
|
return action.run(node, input);
|
|
13439
13517
|
}
|
|
13440
13518
|
|
|
13441
|
-
//
|
|
13519
|
+
// ../../node_modules/aws4fetch/dist/aws4fetch.esm.mjs
|
|
13442
13520
|
var encoder2 = new TextEncoder();
|
|
13443
13521
|
var HOST_SERVICES = {
|
|
13444
13522
|
appstream2: "appstream",
|
|
@@ -13717,7 +13795,7 @@ function guessServiceRegion(url, headers) {
|
|
|
13717
13795
|
return [HOST_SERVICES[service] || service, region || ""];
|
|
13718
13796
|
}
|
|
13719
13797
|
|
|
13720
|
-
// ../src/storage/blob/s3.ts
|
|
13798
|
+
// ../core/src/storage/blob/s3.ts
|
|
13721
13799
|
var ATTEMPTS = 5;
|
|
13722
13800
|
function createS3BlobStore(config) {
|
|
13723
13801
|
const client = new AwsClient({
|
|
@@ -13893,7 +13971,7 @@ async function createAccount(home, options) {
|
|
|
13893
13971
|
throw new Error(`This home already has an account for ${did}`);
|
|
13894
13972
|
}
|
|
13895
13973
|
let vault = createVault({ did, label: options.name, wraps: [] });
|
|
13896
|
-
if (options.passphrase) vault = withWrap(vault, await wrapSeedWithPassphrase(seed, options.passphrase,
|
|
13974
|
+
if (options.passphrase) vault = withWrap(vault, await wrapSeedWithPassphrase(seed, options.passphrase, CLI_PASSPHRASE_LABEL));
|
|
13897
13975
|
const id = newAccountId();
|
|
13898
13976
|
const account = {
|
|
13899
13977
|
id,
|
|
@@ -13954,7 +14032,7 @@ async function unlock(home, account, secret) {
|
|
|
13954
14032
|
import { createServer } from "node:http";
|
|
13955
14033
|
import { WebSocketServer } from "ws";
|
|
13956
14034
|
|
|
13957
|
-
// ../
|
|
14035
|
+
// ../relay/relay.mjs
|
|
13958
14036
|
import { createHash, createHmac, createPublicKey, randomBytes as randomBytes4, verify } from "node:crypto";
|
|
13959
14037
|
var MAX_MESSAGE_BYTES = 64 * 1024;
|
|
13960
14038
|
var MAX_CONNECTIONS = 5e3;
|
|
@@ -15541,7 +15619,11 @@ import { mkdir as mkdir2, readFile as readFile3, rm, writeFile as writeFile2 } f
|
|
|
15541
15619
|
import os3 from "node:os";
|
|
15542
15620
|
import path4 from "node:path";
|
|
15543
15621
|
|
|
15544
|
-
// ../src/session/
|
|
15622
|
+
// ../core/src/session/stay-signed-in.ts
|
|
15623
|
+
var DAY2 = 24 * 60 * 60 * 1e3;
|
|
15624
|
+
var DURATION2 = { never: 0, "1d": DAY2, "7d": 7 * DAY2, "30d": 30 * DAY2 };
|
|
15625
|
+
|
|
15626
|
+
// ../core/src/session/connect.ts
|
|
15545
15627
|
function grantSigner(grant) {
|
|
15546
15628
|
let token = null;
|
|
15547
15629
|
return {
|
|
@@ -15557,7 +15639,7 @@ function grantSigner(grant) {
|
|
|
15557
15639
|
};
|
|
15558
15640
|
}
|
|
15559
15641
|
|
|
15560
|
-
// ../src/session/agent-link.ts
|
|
15642
|
+
// ../core/src/session/agent-link.ts
|
|
15561
15643
|
var SECRET_BYTES = 16;
|
|
15562
15644
|
var ROOM_PREFIX2 = utf8Encode("weave-agent-link-room-v1");
|
|
15563
15645
|
var KEY_INFO = utf8Encode("weave-agent-link-key-v1");
|
package/package.json
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weaveprotocol/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "The Weave protocol from a terminal: manage spaces, run an always-on node, serve MCP to agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"weave": "dist/weave.mjs"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"start": "node --import tsx src/main.ts",
|
|
11
|
-
"
|
|
10
|
+
"start": "node --conditions=@weaveprotocol/source --import tsx src/main.ts",
|
|
11
|
+
"test": "node --conditions=@weaveprotocol/source --import tsx --test tests/*.test.ts",
|
|
12
|
+
"typecheck": "tsc --noEmit",
|
|
13
|
+
"bundle": "esbuild src/main.ts --bundle --platform=node --format=esm --target=node22 --conditions=@weaveprotocol/source --outfile=dist/weave.mjs --external:ws --external:node-datachannel --banner:js='#!/usr/bin/env node'",
|
|
14
|
+
"bundle:pay": "esbuild pay/walletconnect.ts --bundle --format=esm --minify --platform=browser --target=es2022 --outfile=pay/dist/walletconnect.js --define:process.env.NODE_ENV='\"production\"'",
|
|
12
15
|
"build": "bun build.ts",
|
|
13
|
-
"prepublishOnly": "npm run bundle && npm run bundle:pay"
|
|
14
|
-
"bundle:pay": "esbuild pay/walletconnect.ts --bundle --format=esm --minify --platform=browser --target=es2022 --outfile=pay/dist/walletconnect.js --define:process.env.NODE_ENV='\"production\"'"
|
|
16
|
+
"prepublishOnly": "npm run bundle && npm run bundle:pay"
|
|
15
17
|
},
|
|
16
18
|
"dependencies": {
|
|
17
19
|
"node-datachannel": "^0.33.4",
|
|
@@ -24,7 +26,7 @@
|
|
|
24
26
|
"repository": {
|
|
25
27
|
"type": "git",
|
|
26
28
|
"url": "git+https://github.com/leifriksheim/weave.git",
|
|
27
|
-
"directory": "cli"
|
|
29
|
+
"directory": "packages/cli"
|
|
28
30
|
},
|
|
29
31
|
"files": [
|
|
30
32
|
"dist/weave.mjs",
|
|
@@ -33,6 +35,9 @@
|
|
|
33
35
|
],
|
|
34
36
|
"devDependencies": {
|
|
35
37
|
"@reown/appkit": "^1.8.24",
|
|
38
|
+
"@types/node": "^26.6.3",
|
|
39
|
+
"@weaveprotocol/core": "*",
|
|
40
|
+
"@weaveprotocol/relay": "*",
|
|
36
41
|
"esbuild": "^0.28.0",
|
|
37
42
|
"tsx": "^4.19.0"
|
|
38
43
|
},
|