@evolu/common 6.0.1-preview.3 → 6.0.1-preview.31
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/src/Array.d.ts +69 -5
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +64 -5
- package/dist/src/Assert.d.ts +6 -16
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +6 -18
- package/dist/src/Brand.d.ts +75 -0
- package/dist/src/Brand.d.ts.map +1 -0
- package/dist/src/Brand.js +1 -0
- package/dist/src/Buffer.d.ts +1 -1
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Buffer.js +8 -7
- package/dist/src/Cache.d.ts +44 -0
- package/dist/src/Cache.d.ts.map +1 -0
- package/dist/src/Cache.js +52 -0
- package/dist/src/Callbacks.d.ts +45 -12
- package/dist/src/Callbacks.d.ts.map +1 -1
- package/dist/src/Callbacks.js +14 -7
- package/dist/src/Console.d.ts +31 -6
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +72 -9
- package/dist/src/Crypto.d.ts +61 -34
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +32 -45
- package/dist/src/Evolu/Db.d.ts +161 -65
- package/dist/src/Evolu/Db.d.ts.map +1 -1
- package/dist/src/Evolu/Db.js +286 -694
- package/dist/src/Evolu/Diff.d.ts +3 -3
- package/dist/src/Evolu/Diff.d.ts.map +1 -1
- package/dist/src/Evolu/Diff.js +7 -5
- package/dist/src/Evolu/Evolu.d.ts +208 -133
- package/dist/src/Evolu/Evolu.d.ts.map +1 -1
- package/dist/src/Evolu/Evolu.js +188 -183
- package/dist/src/Evolu/Internal.d.ts +0 -2
- package/dist/src/Evolu/Internal.d.ts.map +1 -1
- package/dist/src/Evolu/Internal.js +0 -2
- package/dist/src/Evolu/LocalAuth.d.ts +150 -0
- package/dist/src/Evolu/LocalAuth.d.ts.map +1 -0
- package/dist/src/Evolu/LocalAuth.js +174 -0
- package/dist/src/Evolu/Owner.d.ts +273 -120
- package/dist/src/Evolu/Owner.d.ts.map +1 -1
- package/dist/src/Evolu/Owner.js +130 -104
- package/dist/src/Evolu/Platform.d.ts +9 -7
- package/dist/src/Evolu/Platform.d.ts.map +1 -1
- package/dist/src/Evolu/Protocol.d.ts +277 -232
- package/dist/src/Evolu/Protocol.d.ts.map +1 -1
- package/dist/src/Evolu/Protocol.js +603 -378
- package/dist/src/Evolu/Public.d.ts +6 -8
- package/dist/src/Evolu/Public.d.ts.map +1 -1
- package/dist/src/Evolu/Public.js +2 -3
- package/dist/src/Evolu/PublicKysely.js +3 -3
- package/dist/src/Evolu/Query.d.ts +2 -1
- package/dist/src/Evolu/Query.d.ts.map +1 -1
- package/dist/src/Evolu/Relay.d.ts +92 -7
- package/dist/src/Evolu/Relay.d.ts.map +1 -1
- package/dist/src/Evolu/Relay.js +238 -76
- package/dist/src/Evolu/Schema.d.ts +129 -73
- package/dist/src/Evolu/Schema.d.ts.map +1 -1
- package/dist/src/Evolu/Schema.js +169 -89
- package/dist/src/Evolu/Storage.d.ts +240 -26
- package/dist/src/Evolu/Storage.d.ts.map +1 -1
- package/dist/src/Evolu/Storage.js +189 -91
- package/dist/src/Evolu/Sync.d.ts +67 -13
- package/dist/src/Evolu/Sync.d.ts.map +1 -1
- package/dist/src/Evolu/Sync.js +441 -20
- package/dist/src/Evolu/Timestamp.d.ts +85 -27
- package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
- package/dist/src/Evolu/Timestamp.js +77 -18
- package/dist/src/Identicon.d.ts +35 -0
- package/dist/src/Identicon.d.ts.map +1 -0
- package/dist/src/Identicon.js +143 -0
- package/dist/src/Instances.d.ts +34 -0
- package/dist/src/Instances.d.ts.map +1 -0
- package/dist/src/Instances.js +44 -0
- package/dist/src/ManyToManyMap.d.ts +71 -10
- package/dist/src/ManyToManyMap.d.ts.map +1 -1
- package/dist/src/ManyToManyMap.js +41 -6
- package/dist/src/Number.d.ts +4 -3
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Number.js +5 -4
- package/dist/src/Platform.d.ts +20 -0
- package/dist/src/Platform.d.ts.map +1 -0
- package/dist/src/Platform.js +22 -0
- package/dist/src/Random.d.ts +3 -2
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/Resources.d.ts +118 -0
- package/dist/src/Resources.d.ts.map +1 -0
- package/dist/src/Resources.js +197 -0
- package/dist/src/Result.d.ts +184 -52
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +30 -241
- package/dist/src/Skiplist.js +2 -1
- package/dist/src/Sqlite.d.ts +63 -5
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +110 -9
- package/dist/src/Task.d.ts +586 -0
- package/dist/src/Task.d.ts.map +1 -0
- package/dist/src/Task.js +469 -0
- package/dist/src/Time.d.ts +66 -1
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +99 -5
- package/dist/src/Type.d.ts +622 -340
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +666 -464
- package/dist/src/Types.d.ts +1 -75
- package/dist/src/Types.d.ts.map +1 -1
- package/dist/src/WebSocket.d.ts +5 -2
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +12 -18
- package/dist/src/Worker.d.ts +39 -11
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +22 -4
- package/dist/src/index.d.ts +7 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -2
- package/package.json +14 -13
- package/src/Array.ts +90 -11
- package/src/Assert.ts +6 -24
- package/src/Brand.ts +75 -0
- package/src/Buffer.ts +7 -7
- package/src/Cache.ts +85 -0
- package/src/Callbacks.ts +62 -22
- package/src/Console.ts +91 -11
- package/src/Crypto.ts +97 -82
- package/src/Evolu/Db.ts +517 -1020
- package/src/Evolu/Diff.ts +7 -5
- package/src/Evolu/Evolu.ts +464 -355
- package/src/Evolu/Internal.ts +0 -2
- package/src/Evolu/LocalAuth.ts +463 -0
- package/src/Evolu/Owner.ts +355 -228
- package/src/Evolu/Platform.ts +9 -9
- package/src/Evolu/Protocol.ts +859 -676
- package/src/Evolu/Public.ts +7 -14
- package/src/Evolu/PublicKysely.ts +3 -3
- package/src/Evolu/Query.ts +2 -1
- package/src/Evolu/Relay.ts +437 -93
- package/src/Evolu/Schema.ts +391 -191
- package/src/Evolu/Storage.ts +532 -135
- package/src/Evolu/Sync.ts +766 -37
- package/src/Evolu/Timestamp.ts +88 -35
- package/src/Identicon.ts +197 -0
- package/src/Instances.ts +90 -0
- package/src/ManyToManyMap.ts +124 -24
- package/src/Number.ts +6 -10
- package/src/Platform.ts +26 -0
- package/src/Random.ts +3 -2
- package/src/Resources.ts +367 -0
- package/src/Result.ts +191 -54
- package/src/Skiplist.ts +1 -1
- package/src/Sqlite.ts +122 -17
- package/src/Task.ts +901 -0
- package/src/Time.ts +180 -5
- package/src/Type.ts +1084 -727
- package/src/Types.ts +1 -77
- package/src/WebSocket.ts +27 -25
- package/src/Worker.ts +72 -23
- package/src/index.ts +7 -2
- package/dist/src/Evolu/Config.d.ts +0 -69
- package/dist/src/Evolu/Config.d.ts.map +0 -1
- package/dist/src/Evolu/Config.js +0 -9
- package/dist/src/Evolu/Kysely.d.ts +0 -6
- package/dist/src/Evolu/Kysely.d.ts.map +0 -1
- package/dist/src/Evolu/Kysely.js +0 -21
- package/dist/src/NanoId.d.ts +0 -27
- package/dist/src/NanoId.d.ts.map +0 -1
- package/dist/src/NanoId.js +0 -6
- package/dist/src/Promise.d.ts +0 -180
- package/dist/src/Promise.d.ts.map +0 -1
- package/dist/src/Promise.js +0 -176
- package/src/Evolu/Config.ts +0 -83
- package/src/Evolu/Kysely.ts +0 -38
- package/src/NanoId.ts +0 -39
- package/src/Promise.ts +0 -295
package/src/Crypto.ts
CHANGED
|
@@ -3,51 +3,65 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
6
|
+
import { xchacha20poly1305 } from "@noble/ciphers/chacha.js";
|
|
7
|
+
import { hmac } from "@noble/hashes/hmac.js";
|
|
8
|
+
import { sha512 } from "@noble/hashes/sha2.js";
|
|
9
|
+
import { randomBytes, utf8ToBytes } from "@noble/hashes/utils.js";
|
|
10
|
+
import { Result, trySync } from "./Result.js";
|
|
11
|
+
import { brand, length, NonNegativeInt, Uint8Array } from "./Type.js";
|
|
12
|
+
|
|
13
|
+
export interface RandomBytes {
|
|
14
|
+
/**
|
|
15
|
+
* Creates cryptographically secure random bytes with type-safe length
|
|
16
|
+
* branding.
|
|
17
|
+
*
|
|
18
|
+
* Uses the operating system's cryptographically secure random number
|
|
19
|
+
* generator (crypto.getRandomValues) to generate high-quality entropy
|
|
20
|
+
* suitable for cryptographic operations.
|
|
21
|
+
*
|
|
22
|
+
* ### Type Safety
|
|
23
|
+
*
|
|
24
|
+
* Returns specific branded types for common sizes:
|
|
25
|
+
*
|
|
26
|
+
* - `Random16` for 16-byte values (128 bits)
|
|
27
|
+
* - `Random32` for 32-byte values (256 bits)
|
|
28
|
+
* - `Random64` for 64-byte values (512 bits)
|
|
29
|
+
* - `Random` for any other size
|
|
30
|
+
*
|
|
31
|
+
* ### Example
|
|
32
|
+
*
|
|
33
|
+
* ```ts
|
|
34
|
+
* const nonce = randomBytes.create(16); // Type: Random16
|
|
35
|
+
* const key = randomBytes.create(32); // Type: Random32
|
|
36
|
+
* const seed = randomBytes.create(64); // Type: Random64
|
|
37
|
+
* const custom = randomBytes.create(48); // Type: Random
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
create(bytesLength: 16): Entropy16;
|
|
41
|
+
create(bytesLength: 32): Entropy32;
|
|
42
|
+
create(bytesLength: 64): Entropy64;
|
|
43
|
+
create(bytesLength: number): Entropy;
|
|
32
44
|
}
|
|
33
45
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
46
|
+
export interface RandomBytesDep {
|
|
47
|
+
readonly randomBytes: RandomBytes;
|
|
48
|
+
}
|
|
37
49
|
|
|
38
|
-
|
|
50
|
+
const Entropy = brand("Entropy", Uint8Array);
|
|
51
|
+
type Entropy = typeof Entropy.Type;
|
|
39
52
|
|
|
40
|
-
export
|
|
41
|
-
|
|
42
|
-
}
|
|
53
|
+
export const Entropy16 = length(16)(Entropy);
|
|
54
|
+
export type Entropy16 = typeof Entropy16.Type;
|
|
43
55
|
|
|
44
|
-
export const
|
|
45
|
-
|
|
56
|
+
export const Entropy32 = length(32)(Entropy);
|
|
57
|
+
export type Entropy32 = typeof Entropy32.Type;
|
|
46
58
|
|
|
47
|
-
export
|
|
59
|
+
export const Entropy64 = length(64)(Entropy);
|
|
60
|
+
export type Entropy64 = typeof Entropy64.Type;
|
|
48
61
|
|
|
49
|
-
export const
|
|
50
|
-
|
|
62
|
+
export const createRandomBytes = (): RandomBytes => ({
|
|
63
|
+
create: randomBytes as RandomBytes["create"],
|
|
64
|
+
});
|
|
51
65
|
|
|
52
66
|
/**
|
|
53
67
|
* SLIP21.
|
|
@@ -55,54 +69,43 @@ export const mnemonicToMnemonicSeed = (mnemonic: Mnemonic): MnemonicSeed =>
|
|
|
55
69
|
* https://github.com/satoshilabs/slips/blob/master/slip-0021.md
|
|
56
70
|
*/
|
|
57
71
|
export const createSlip21 = (
|
|
58
|
-
seed:
|
|
59
|
-
path: ReadonlyArray<string>,
|
|
60
|
-
):
|
|
61
|
-
let
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
seed: Entropy16 | Entropy32 | Entropy64,
|
|
73
|
+
path: ReadonlyArray<string | number>,
|
|
74
|
+
): Entropy32 => {
|
|
75
|
+
let currentNode = hmac(
|
|
76
|
+
sha512,
|
|
77
|
+
utf8ToBytes("Symmetric key seed"),
|
|
78
|
+
seed,
|
|
79
|
+
) as Entropy64;
|
|
80
|
+
|
|
81
|
+
for (const element of path) {
|
|
82
|
+
const label = typeof element === "number" ? element.toString() : element;
|
|
83
|
+
currentNode = deriveSlip21Node(label, currentNode);
|
|
68
84
|
}
|
|
69
|
-
|
|
85
|
+
|
|
86
|
+
return currentNode.slice(32, 64) as Entropy32;
|
|
70
87
|
};
|
|
71
88
|
|
|
72
89
|
/**
|
|
73
|
-
*
|
|
74
|
-
* derived key.
|
|
90
|
+
* Derives a single node in the SLIP-21 hierarchical key derivation.
|
|
75
91
|
*
|
|
76
|
-
*
|
|
77
|
-
* compact, human-readable, and shareable identifier suitable for UI display or
|
|
78
|
-
* URL use. While this lowers entropy, 126 bits remains cryptographically secure
|
|
79
|
-
* for uniqueness and unpredictability in most applications (comparable to
|
|
80
|
-
* UUIDv4's 122 bits).
|
|
81
|
-
*
|
|
82
|
-
* See https://github.com/satoshilabs/slips/blob/master/slip-0021.md
|
|
92
|
+
* @see {@link createSlip21}
|
|
83
93
|
*/
|
|
84
|
-
export const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
):
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
id = (id + urlAlphabet[slip21[i] & 63]) as Id;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return id;
|
|
94
|
+
export const deriveSlip21Node = (
|
|
95
|
+
label: string,
|
|
96
|
+
parentNode: Entropy64,
|
|
97
|
+
): Entropy64 => {
|
|
98
|
+
const labelBytes = utf8ToBytes(label);
|
|
99
|
+
const message = new globalThis.Uint8Array(labelBytes.byteLength + 1);
|
|
100
|
+
message[0] = 0;
|
|
101
|
+
message.set(labelBytes, 1);
|
|
102
|
+
return hmac(sha512, parentNode.slice(0, 32), message) as Entropy64;
|
|
97
103
|
};
|
|
98
104
|
|
|
99
105
|
/** The encryption key for {@link SymmetricCrypto}. */
|
|
100
|
-
export const EncryptionKey = brand("EncryptionKey",
|
|
106
|
+
export const EncryptionKey = brand("EncryptionKey", Entropy32);
|
|
101
107
|
export type EncryptionKey = typeof EncryptionKey.Type;
|
|
102
108
|
|
|
103
|
-
export const createEncryptionKey = (seed: MnemonicSeed): EncryptionKey =>
|
|
104
|
-
createSlip21(seed, ["Evolu", "Encryption Key"]) as EncryptionKey;
|
|
105
|
-
|
|
106
109
|
/** Symmetric cryptography. */
|
|
107
110
|
export interface SymmetricCrypto {
|
|
108
111
|
readonly nonceLength: NonNegativeInt;
|
|
@@ -137,15 +140,15 @@ export interface SymmetricCryptoDecryptError {
|
|
|
137
140
|
* https://github.com/paulmillr/noble-ciphers?tab=readme-ov-file#which-cipher-should-i-pick
|
|
138
141
|
*/
|
|
139
142
|
export const createSymmetricCrypto = (
|
|
140
|
-
deps:
|
|
143
|
+
deps: RandomBytesDep,
|
|
141
144
|
): SymmetricCrypto => {
|
|
142
|
-
const nonceLength =
|
|
145
|
+
const nonceLength = NonNegativeInt.orThrow(24);
|
|
143
146
|
|
|
144
147
|
const symmetricCrypto: SymmetricCrypto = {
|
|
145
148
|
nonceLength,
|
|
146
149
|
|
|
147
150
|
encrypt: (plaintext, encryptionKey) => {
|
|
148
|
-
const nonce = deps.
|
|
151
|
+
const nonce = deps.randomBytes.create(nonceLength);
|
|
149
152
|
const ciphertext = xchacha20poly1305(encryptionKey, nonce).encrypt(
|
|
150
153
|
plaintext,
|
|
151
154
|
);
|
|
@@ -173,19 +176,31 @@ export const createSymmetricCrypto = (
|
|
|
173
176
|
* https://bford.info/pub/sec/purb.pdf
|
|
174
177
|
*/
|
|
175
178
|
export const padmePaddedLength = (length: NonNegativeInt): NonNegativeInt => {
|
|
176
|
-
if (length <= 0) return 0
|
|
179
|
+
if (length <= 0) return NonNegativeInt.orThrow(0);
|
|
177
180
|
const e = 31 - Math.clz32(length >>> 0);
|
|
178
181
|
const s = 32 - Math.clz32(e >>> 0);
|
|
179
182
|
const z = Math.max(0, e - s);
|
|
180
183
|
const mask = (1 << z) - 1;
|
|
181
|
-
return ((length + mask) & ~mask)
|
|
184
|
+
return NonNegativeInt.orThrow((length + mask) & ~mask);
|
|
182
185
|
};
|
|
183
186
|
|
|
184
187
|
/**
|
|
185
188
|
* Returns the PADMÉ padding length for a given input length. Uses
|
|
186
189
|
* {@link padmePaddedLength}.
|
|
187
190
|
*/
|
|
188
|
-
|
|
189
191
|
export const padmePaddingLength = (length: NonNegativeInt): NonNegativeInt => {
|
|
190
|
-
return (padmePaddedLength(length) - length)
|
|
192
|
+
return NonNegativeInt.orThrow(padmePaddedLength(length) - length);
|
|
191
193
|
};
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Performs a timing-safe comparison of two Uint8Arrays. Returns true if they
|
|
197
|
+
* are equal, false otherwise. Takes constant time regardless of where the
|
|
198
|
+
* arrays differ.
|
|
199
|
+
*
|
|
200
|
+
* @see https://nodejs.org/api/crypto.html#cryptotimingsafeequala-b
|
|
201
|
+
*/
|
|
202
|
+
export type TimingSafeEqual = (a: Uint8Array, b: Uint8Array) => boolean;
|
|
203
|
+
|
|
204
|
+
export interface TimingSafeEqualDep {
|
|
205
|
+
readonly timingSafeEqual: TimingSafeEqual;
|
|
206
|
+
}
|