cojson 0.20.7 → 0.20.8
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +18 -0
- package/dist/SyncStateManager.d.ts.map +1 -1
- package/dist/SyncStateManager.js +0 -2
- package/dist/SyncStateManager.js.map +1 -1
- package/dist/base64url.d.ts +15 -0
- package/dist/base64url.d.ts.map +1 -1
- package/dist/base64url.js +101 -5
- package/dist/base64url.js.map +1 -1
- package/dist/base64url.test.js +76 -1
- package/dist/base64url.test.js.map +1 -1
- package/dist/coValue.d.ts +2 -1
- package/dist/coValue.d.ts.map +1 -1
- package/dist/coValue.js.map +1 -1
- package/dist/coValueCore/coValueCore.d.ts +9 -11
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +92 -65
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts +38 -7
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValueCore/verifiedState.js +226 -30
- package/dist/coValueCore/verifiedState.js.map +1 -1
- package/dist/coValues/binaryCoStream.d.ts +63 -0
- package/dist/coValues/binaryCoStream.d.ts.map +1 -0
- package/dist/coValues/binaryCoStream.js +125 -0
- package/dist/coValues/binaryCoStream.js.map +1 -0
- package/dist/coValues/coList.d.ts +3 -1
- package/dist/coValues/coList.d.ts.map +1 -1
- package/dist/coValues/coList.js +15 -6
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.d.ts +1 -1
- package/dist/coValues/coMap.d.ts.map +1 -1
- package/dist/coValues/coMap.js +2 -2
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coStream.d.ts +0 -38
- package/dist/coValues/coStream.d.ts.map +1 -1
- package/dist/coValues/coStream.js +0 -86
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/coValues/group.d.ts +44 -6
- package/dist/coValues/group.d.ts.map +1 -1
- package/dist/coValues/group.js +198 -17
- package/dist/coValues/group.js.map +1 -1
- package/dist/coreToCoValue.d.ts +2 -1
- package/dist/coreToCoValue.d.ts.map +1 -1
- package/dist/coreToCoValue.js +2 -1
- package/dist/coreToCoValue.js.map +1 -1
- package/dist/crypto/NapiCrypto.d.ts +18 -24
- package/dist/crypto/NapiCrypto.d.ts.map +1 -1
- package/dist/crypto/NapiCrypto.js +98 -60
- package/dist/crypto/NapiCrypto.js.map +1 -1
- package/dist/crypto/RNCrypto.d.ts +16 -3
- package/dist/crypto/RNCrypto.d.ts.map +1 -1
- package/dist/crypto/RNCrypto.js +117 -54
- package/dist/crypto/RNCrypto.js.map +1 -1
- package/dist/crypto/WasmCrypto.d.ts +18 -24
- package/dist/crypto/WasmCrypto.d.ts.map +1 -1
- package/dist/crypto/WasmCrypto.js +100 -61
- package/dist/crypto/WasmCrypto.js.map +1 -1
- package/dist/crypto/crypto.d.ts +55 -19
- package/dist/crypto/crypto.d.ts.map +1 -1
- package/dist/crypto/crypto.js +14 -3
- package/dist/crypto/crypto.js.map +1 -1
- package/dist/exports.d.ts +7 -3
- package/dist/exports.d.ts.map +1 -1
- package/dist/exports.js +4 -2
- package/dist/exports.js.map +1 -1
- package/dist/localNode.d.ts +3 -1
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +10 -3
- package/dist/localNode.js.map +1 -1
- package/dist/media.d.ts +1 -1
- package/dist/media.d.ts.map +1 -1
- package/dist/permissions.d.ts +2 -1
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +19 -3
- package/dist/permissions.js.map +1 -1
- package/dist/storage/sqliteAsync/client.d.ts +24 -12
- package/dist/storage/sqliteAsync/client.d.ts.map +1 -1
- package/dist/storage/sqliteAsync/client.js +70 -58
- package/dist/storage/sqliteAsync/client.js.map +1 -1
- package/dist/storage/sqliteAsync/types.d.ts +1 -1
- package/dist/storage/sqliteAsync/types.d.ts.map +1 -1
- package/dist/storage/types.d.ts +1 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +7 -1
- package/dist/sync.js.map +1 -1
- package/dist/tests/CojsonMessageChannel.test.js +2 -2
- package/dist/tests/SQLiteClientAsync.test.d.ts +2 -0
- package/dist/tests/SQLiteClientAsync.test.d.ts.map +1 -0
- package/dist/tests/SQLiteClientAsync.test.js +64 -0
- package/dist/tests/SQLiteClientAsync.test.js.map +1 -0
- package/dist/tests/StorageApiAsync.test.js +2 -8
- package/dist/tests/StorageApiAsync.test.js.map +1 -1
- package/dist/tests/SyncStateManager.test.js +2 -2
- package/dist/tests/WasmCrypto.test.js +1 -15
- package/dist/tests/WasmCrypto.test.js.map +1 -1
- package/dist/tests/coList.test.js +24 -5
- package/dist/tests/coList.test.js.map +1 -1
- package/dist/tests/coStream.test.js +4 -3
- package/dist/tests/coStream.test.js.map +1 -1
- package/dist/tests/coValueCore.initTransaction.test.d.ts +2 -0
- package/dist/tests/coValueCore.initTransaction.test.d.ts.map +1 -0
- package/dist/tests/coValueCore.initTransaction.test.js +438 -0
- package/dist/tests/coValueCore.initTransaction.test.js.map +1 -0
- package/dist/tests/coValueCore.test.js +11 -19
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/crypto.test.js +83 -0
- package/dist/tests/crypto.test.js.map +1 -1
- package/dist/tests/deleteCoValue.test.js +5 -5
- package/dist/tests/deleteCoValue.test.js.map +1 -1
- package/dist/tests/group.inheritance.test.js +11 -0
- package/dist/tests/group.inheritance.test.js.map +1 -1
- package/dist/tests/group.test.js +24 -1
- package/dist/tests/group.test.js.map +1 -1
- package/dist/tests/groupSealer.test.d.ts +2 -0
- package/dist/tests/groupSealer.test.d.ts.map +1 -0
- package/dist/tests/groupSealer.test.js +913 -0
- package/dist/tests/groupSealer.test.js.map +1 -0
- package/dist/tests/setup.js +5 -0
- package/dist/tests/setup.js.map +1 -1
- package/dist/tests/sync.auth.test.js +10 -10
- package/dist/tests/sync.concurrentLoad.test.js +12 -12
- package/dist/tests/sync.deleted.test.js +8 -8
- package/dist/tests/sync.garbageCollection.test.js +10 -10
- package/dist/tests/sync.invite.test.js +12 -12
- package/dist/tests/sync.known.test.js +2 -2
- package/dist/tests/sync.load.test.js +107 -107
- package/dist/tests/sync.mesh.test.js +164 -46
- package/dist/tests/sync.mesh.test.js.map +1 -1
- package/dist/tests/sync.multipleServers.test.js +43 -43
- package/dist/tests/sync.peerReconciliation.test.js +29 -29
- package/dist/tests/sync.sharding.test.js +3 -3
- package/dist/tests/sync.storage.test.js +104 -104
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.storageAsync.test.js +56 -56
- package/dist/tests/sync.upload.test.js +22 -22
- package/dist/tests/testStorage.d.ts +2 -0
- package/dist/tests/testStorage.d.ts.map +1 -1
- package/dist/tests/testStorage.js +30 -6
- package/dist/tests/testStorage.js.map +1 -1
- package/dist/typeUtils/isCoValue.js +1 -1
- package/dist/typeUtils/isCoValue.js.map +1 -1
- package/package.json +4 -4
- package/src/SyncStateManager.ts +0 -2
- package/src/base64url.test.ts +89 -1
- package/src/base64url.ts +134 -6
- package/src/coValue.ts +2 -1
- package/src/coValueCore/coValueCore.ts +126 -84
- package/src/coValueCore/verifiedState.ts +335 -53
- package/src/coValues/binaryCoStream.ts +217 -0
- package/src/coValues/coList.ts +21 -8
- package/src/coValues/coMap.ts +3 -0
- package/src/coValues/coStream.ts +0 -170
- package/src/coValues/group.ts +270 -21
- package/src/coreToCoValue.ts +2 -1
- package/src/crypto/NapiCrypto.ts +198 -95
- package/src/crypto/RNCrypto.ts +229 -102
- package/src/crypto/WasmCrypto.ts +201 -95
- package/src/crypto/crypto.ts +118 -45
- package/src/exports.ts +11 -5
- package/src/localNode.ts +17 -1
- package/src/media.ts +1 -1
- package/src/permissions.ts +30 -7
- package/src/storage/sqliteAsync/client.ts +136 -115
- package/src/storage/sqliteAsync/types.ts +3 -1
- package/src/storage/types.ts +4 -0
- package/src/sync.ts +10 -1
- package/src/tests/CojsonMessageChannel.test.ts +2 -2
- package/src/tests/SQLiteClientAsync.test.ts +75 -0
- package/src/tests/StorageApiAsync.test.ts +4 -9
- package/src/tests/SyncStateManager.test.ts +2 -2
- package/src/tests/WasmCrypto.test.ts +1 -25
- package/src/tests/coList.test.ts +39 -5
- package/src/tests/coStream.test.ts +4 -5
- package/src/tests/coValueCore.initTransaction.test.ts +836 -0
- package/src/tests/coValueCore.test.ts +11 -22
- package/src/tests/crypto.test.ts +107 -0
- package/src/tests/deleteCoValue.test.ts +5 -5
- package/src/tests/group.inheritance.test.ts +16 -0
- package/src/tests/group.test.ts +29 -1
- package/src/tests/groupSealer.test.ts +1473 -0
- package/src/tests/setup.ts +6 -0
- package/src/tests/sync.auth.test.ts +10 -10
- package/src/tests/sync.concurrentLoad.test.ts +12 -12
- package/src/tests/sync.deleted.test.ts +8 -8
- package/src/tests/sync.garbageCollection.test.ts +10 -10
- package/src/tests/sync.invite.test.ts +12 -12
- package/src/tests/sync.known.test.ts +2 -2
- package/src/tests/sync.load.test.ts +107 -107
- package/src/tests/sync.mesh.test.ts +189 -46
- package/src/tests/sync.multipleServers.test.ts +43 -43
- package/src/tests/sync.peerReconciliation.test.ts +29 -29
- package/src/tests/sync.sharding.test.ts +3 -3
- package/src/tests/sync.storage.test.ts +104 -104
- package/src/tests/sync.storageAsync.test.ts +56 -56
- package/src/tests/sync.upload.test.ts +22 -22
- package/src/tests/testStorage.ts +39 -9
- package/src/typeUtils/isCoValue.ts +1 -1
- package/dist/coValueCore/SessionMap.d.ts +0 -55
- package/dist/coValueCore/SessionMap.d.ts.map +0 -1
- package/dist/coValueCore/SessionMap.js +0 -206
- package/dist/coValueCore/SessionMap.js.map +0 -1
- package/dist/tests/coreWasm.test.d.ts +0 -2
- package/dist/tests/coreWasm.test.d.ts.map +0 -1
- package/dist/tests/coreWasm.test.js +0 -203
- package/dist/tests/coreWasm.test.js.map +0 -1
- package/src/coValueCore/SessionMap.ts +0 -394
- package/src/tests/coreWasm.test.ts +0 -452
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { base64URLtoBytes, bytesToBase64url } from "../base64url.js";
|
|
2
|
+
import type { CoID, RawCoValue } from "../coValue.js";
|
|
3
|
+
import type { AvailableCoValueCore } from "../coValueCore/coValueCore.js";
|
|
4
|
+
import type { RawCoID } from "../ids.js";
|
|
5
|
+
import type { JsonObject } from "../jsonValue.js";
|
|
6
|
+
import type { RawGroup } from "./group.js";
|
|
7
|
+
|
|
8
|
+
export type BinaryStreamInfo = {
|
|
9
|
+
mimeType: string;
|
|
10
|
+
fileName?: string;
|
|
11
|
+
totalSizeBytes?: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type BinaryStreamStart = {
|
|
15
|
+
type: "start";
|
|
16
|
+
} & BinaryStreamInfo;
|
|
17
|
+
|
|
18
|
+
export type BinaryStreamChunk = {
|
|
19
|
+
type: "chunk";
|
|
20
|
+
chunk: `binary_U${string}`;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type BinaryStreamEnd = {
|
|
24
|
+
type: "end";
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type BinaryCoStreamMeta = JsonObject & { type: "binary" };
|
|
28
|
+
|
|
29
|
+
export type BinaryStreamItem =
|
|
30
|
+
| BinaryStreamStart
|
|
31
|
+
| BinaryStreamChunk
|
|
32
|
+
| BinaryStreamEnd;
|
|
33
|
+
|
|
34
|
+
const binary_U_prefixLength = 8; // "binary_U".length;
|
|
35
|
+
|
|
36
|
+
export class RawBinaryCoStreamView<
|
|
37
|
+
Meta extends BinaryCoStreamMeta = { type: "binary" },
|
|
38
|
+
> implements RawCoValue
|
|
39
|
+
{
|
|
40
|
+
id: CoID<this>;
|
|
41
|
+
type = "costream" as const;
|
|
42
|
+
core: AvailableCoValueCore;
|
|
43
|
+
knownTransactions: Record<RawCoID, number>;
|
|
44
|
+
totalValidTransactions: number = 0;
|
|
45
|
+
version: number = 0;
|
|
46
|
+
private chunks: string[];
|
|
47
|
+
private start: BinaryStreamStart | undefined;
|
|
48
|
+
private ended: boolean;
|
|
49
|
+
|
|
50
|
+
private resetInternalState() {
|
|
51
|
+
this.chunks = [];
|
|
52
|
+
this.start = undefined;
|
|
53
|
+
this.ended = false;
|
|
54
|
+
this.knownTransactions = { [this.core.id]: 0 };
|
|
55
|
+
this.totalValidTransactions = 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
constructor(core: AvailableCoValueCore) {
|
|
59
|
+
this.id = core.id as CoID<this>;
|
|
60
|
+
this.core = core;
|
|
61
|
+
this.ended = false;
|
|
62
|
+
this.chunks = [];
|
|
63
|
+
this.knownTransactions = { [core.id]: 0 };
|
|
64
|
+
this.processNewTransactions();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
rebuildFromCore() {
|
|
68
|
+
this.version++;
|
|
69
|
+
|
|
70
|
+
this.resetInternalState();
|
|
71
|
+
this.processNewTransactions();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
get headerMeta(): Meta {
|
|
75
|
+
return this.core.verified.header.meta as Meta;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
get group(): RawGroup {
|
|
79
|
+
return this.core.getGroup();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Not yet implemented */
|
|
83
|
+
atTime(_time: number): this {
|
|
84
|
+
throw new Error("Not yet implemented");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
processNewTransactions() {
|
|
88
|
+
if (this.ended) return;
|
|
89
|
+
|
|
90
|
+
const newValidTransactions = this.core.getValidTransactions({
|
|
91
|
+
ignorePrivateTransactions: false,
|
|
92
|
+
knownTransactions: this.knownTransactions,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (newValidTransactions.length === 0) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
for (const { txID, madeAt, changes } of newValidTransactions) {
|
|
100
|
+
for (const changeUntyped of changes) {
|
|
101
|
+
const change = changeUntyped as BinaryStreamItem;
|
|
102
|
+
|
|
103
|
+
if (change.type === "chunk") {
|
|
104
|
+
this.chunks.push(change.chunk.slice(binary_U_prefixLength));
|
|
105
|
+
} else if (change.type === "start") {
|
|
106
|
+
this.start = change;
|
|
107
|
+
} else if (change.type === "end") {
|
|
108
|
+
this.ended = true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
this.totalValidTransactions += newValidTransactions.length;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
isBinaryStreamEnded() {
|
|
117
|
+
return this.ended;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
getBinaryStreamInfo(): BinaryStreamInfo | undefined {
|
|
121
|
+
if (!this.start) return;
|
|
122
|
+
|
|
123
|
+
const start = this.start;
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
mimeType: start.mimeType,
|
|
127
|
+
fileName: start.fileName,
|
|
128
|
+
totalSizeBytes: start.totalSizeBytes,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
getBinaryChunks(
|
|
133
|
+
allowUnfinished?: boolean,
|
|
134
|
+
):
|
|
135
|
+
| (BinaryStreamInfo & { chunks: Uint8Array[]; finished: boolean })
|
|
136
|
+
| undefined {
|
|
137
|
+
if (!this.start) return;
|
|
138
|
+
if (!this.ended && !allowUnfinished) return;
|
|
139
|
+
|
|
140
|
+
const start = this.start;
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
mimeType: start.mimeType,
|
|
144
|
+
fileName: start.fileName,
|
|
145
|
+
totalSizeBytes: start.totalSizeBytes,
|
|
146
|
+
chunks: this.chunks.map(base64URLtoBytes),
|
|
147
|
+
finished: this.ended,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
toJSON() {
|
|
152
|
+
return {};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
subscribe(listener: (coStream: this) => void): () => void {
|
|
156
|
+
return this.core.subscribe((core) => {
|
|
157
|
+
listener(core.getCurrentContent() as this);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export class RawBinaryCoStream<
|
|
163
|
+
Meta extends BinaryCoStreamMeta = { type: "binary" },
|
|
164
|
+
>
|
|
165
|
+
extends RawBinaryCoStreamView<Meta>
|
|
166
|
+
implements RawCoValue
|
|
167
|
+
{
|
|
168
|
+
/** @internal */
|
|
169
|
+
push(
|
|
170
|
+
item: BinaryStreamItem,
|
|
171
|
+
privacy: "private" | "trusting" = "private",
|
|
172
|
+
updateView: boolean = true,
|
|
173
|
+
): void {
|
|
174
|
+
this.core.makeTransaction([item], privacy);
|
|
175
|
+
if (updateView) {
|
|
176
|
+
this.processNewTransactions();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
startBinaryStream(
|
|
181
|
+
settings: BinaryStreamInfo,
|
|
182
|
+
privacy: "private" | "trusting" = "private",
|
|
183
|
+
): void {
|
|
184
|
+
this.push(
|
|
185
|
+
{
|
|
186
|
+
type: "start",
|
|
187
|
+
...settings,
|
|
188
|
+
} satisfies BinaryStreamStart,
|
|
189
|
+
privacy,
|
|
190
|
+
false,
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
pushBinaryStreamChunk(
|
|
195
|
+
chunk: Uint8Array,
|
|
196
|
+
privacy: "private" | "trusting" = "private",
|
|
197
|
+
): void {
|
|
198
|
+
this.push(
|
|
199
|
+
{
|
|
200
|
+
type: "chunk",
|
|
201
|
+
chunk: `binary_U${bytesToBase64url(chunk)}`,
|
|
202
|
+
} satisfies BinaryStreamChunk,
|
|
203
|
+
privacy,
|
|
204
|
+
false,
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
endBinaryStream(privacy: "private" | "trusting" = "private") {
|
|
209
|
+
this.push(
|
|
210
|
+
{
|
|
211
|
+
type: "end",
|
|
212
|
+
} satisfies BinaryStreamEnd,
|
|
213
|
+
privacy,
|
|
214
|
+
true,
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
}
|
package/src/coValues/coList.ts
CHANGED
|
@@ -35,6 +35,8 @@ type InsertionEntry<T extends JsonValue> = {
|
|
|
35
35
|
predecessors: OpID[];
|
|
36
36
|
successors: OpID[];
|
|
37
37
|
change: InsertionOpPayload<T>;
|
|
38
|
+
/** Whether this entry comes from a valid transaction */
|
|
39
|
+
isValid: boolean;
|
|
38
40
|
};
|
|
39
41
|
|
|
40
42
|
type DeletionEntry = {
|
|
@@ -207,9 +209,12 @@ export class RawCoList<
|
|
|
207
209
|
}
|
|
208
210
|
|
|
209
211
|
private _processNewTransactions() {
|
|
212
|
+
// Get all transactions including invalid ones, so that items referencing
|
|
213
|
+
// entries from invalid init transactions can still find their references.
|
|
210
214
|
const transactions = this.core.getValidSortedTransactions({
|
|
211
215
|
ignorePrivateTransactions: false,
|
|
212
216
|
knownTransactions: this.knownTransactions,
|
|
217
|
+
includeInvalidMetaTransactions: true,
|
|
213
218
|
});
|
|
214
219
|
|
|
215
220
|
if (transactions.length === 0) {
|
|
@@ -220,15 +225,19 @@ export class RawCoList<
|
|
|
220
225
|
let oldestValidTransaction: number | undefined = undefined;
|
|
221
226
|
this._cachedEntries = undefined;
|
|
222
227
|
|
|
223
|
-
for (const { txID, changes, madeAt } of transactions) {
|
|
228
|
+
for (const { txID, changes, madeAt, isValid } of transactions) {
|
|
224
229
|
if (this.isFilteredOut(madeAt)) {
|
|
225
230
|
continue;
|
|
226
231
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
madeAt
|
|
231
|
-
|
|
232
|
+
|
|
233
|
+
// Only track valid transactions for the lastValidTransaction/oldestValidTransaction
|
|
234
|
+
if (isValid) {
|
|
235
|
+
lastValidTransaction = Math.max(lastValidTransaction ?? 0, madeAt);
|
|
236
|
+
oldestValidTransaction = Math.min(
|
|
237
|
+
oldestValidTransaction ?? Infinity,
|
|
238
|
+
madeAt,
|
|
239
|
+
);
|
|
240
|
+
}
|
|
232
241
|
|
|
233
242
|
for (const [changeIdx, changeUntyped] of changes.entries()) {
|
|
234
243
|
const change = changeUntyped as ListOpPayload<Item>;
|
|
@@ -246,6 +255,7 @@ export class RawCoList<
|
|
|
246
255
|
predecessors: [],
|
|
247
256
|
successors: [],
|
|
248
257
|
change,
|
|
258
|
+
isValid,
|
|
249
259
|
});
|
|
250
260
|
|
|
251
261
|
// If the change index already exists, we don't need to process it again
|
|
@@ -438,7 +448,9 @@ export class RawCoList<
|
|
|
438
448
|
|
|
439
449
|
const deleted = this.isDeleted(currentOpID);
|
|
440
450
|
|
|
441
|
-
|
|
451
|
+
// Skip entries that are deleted or from invalid transactions
|
|
452
|
+
// (e.g., losing init transactions in firstComesWins scenarios)
|
|
453
|
+
if (!deleted && entry.isValid) {
|
|
442
454
|
arr.push({
|
|
443
455
|
value: entry.change.value,
|
|
444
456
|
madeAt: entry.madeAt,
|
|
@@ -563,6 +575,7 @@ export class RawCoList<
|
|
|
563
575
|
items: Item[],
|
|
564
576
|
after?: number,
|
|
565
577
|
privacy: "private" | "trusting" = "private",
|
|
578
|
+
meta?: JsonObject,
|
|
566
579
|
) {
|
|
567
580
|
const entries = this.entries();
|
|
568
581
|
after =
|
|
@@ -597,7 +610,7 @@ export class RawCoList<
|
|
|
597
610
|
changes.reverse();
|
|
598
611
|
}
|
|
599
612
|
|
|
600
|
-
this.core.makeTransaction(changes, privacy);
|
|
613
|
+
this.core.makeTransaction(changes, privacy, meta);
|
|
601
614
|
this.processNewTransactions();
|
|
602
615
|
}
|
|
603
616
|
|
package/src/coValues/coMap.ts
CHANGED
|
@@ -120,6 +120,7 @@ export class RawCoMap<
|
|
|
120
120
|
|
|
121
121
|
for (const transaction of newValidTransactions) {
|
|
122
122
|
const { txID, changes, madeAt, tx } = transaction;
|
|
123
|
+
|
|
123
124
|
for (let changeIdx = 0; changeIdx < changes.length; changeIdx++) {
|
|
124
125
|
const change = changes[changeIdx] as MapOpPayload<
|
|
125
126
|
keyof Shape & string,
|
|
@@ -400,6 +401,7 @@ export class RawCoMap<
|
|
|
400
401
|
assign(
|
|
401
402
|
entries: Partial<Shape>,
|
|
402
403
|
privacy: "private" | "trusting" = "private",
|
|
404
|
+
meta?: JsonObject,
|
|
403
405
|
): void {
|
|
404
406
|
if (this.isTimeTravelEntity()) {
|
|
405
407
|
throw new Error("Cannot set value on a time travel entity");
|
|
@@ -412,6 +414,7 @@ export class RawCoMap<
|
|
|
412
414
|
value: isCoValue(value) ? value.id : value,
|
|
413
415
|
})),
|
|
414
416
|
privacy,
|
|
417
|
+
meta,
|
|
415
418
|
);
|
|
416
419
|
|
|
417
420
|
this.processNewTransactions();
|
package/src/coValues/coStream.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { base64URLtoBytes, bytesToBase64url } from "../base64url.js";
|
|
2
1
|
import { CoID, RawCoValue } from "../coValue.js";
|
|
3
2
|
import { AvailableCoValueCore } from "../coValueCore/coValueCore.js";
|
|
4
3
|
import { AgentID, SessionID, TransactionID } from "../ids.js";
|
|
5
4
|
import { JsonObject, JsonValue } from "../jsonValue.js";
|
|
6
|
-
import { logger } from "../logger.js";
|
|
7
5
|
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
|
8
6
|
import { isAccountID } from "../typeUtils/isAccountID.js";
|
|
9
7
|
import { isCoValue } from "../typeUtils/isCoValue.js";
|
|
@@ -11,32 +9,6 @@ import { RawAccountID } from "./account.js";
|
|
|
11
9
|
import { RawGroup } from "./group.js";
|
|
12
10
|
import { RawCoID } from "../ids.js";
|
|
13
11
|
|
|
14
|
-
export type BinaryStreamInfo = {
|
|
15
|
-
mimeType: string;
|
|
16
|
-
fileName?: string;
|
|
17
|
-
totalSizeBytes?: number;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export type BinaryStreamStart = {
|
|
21
|
-
type: "start";
|
|
22
|
-
} & BinaryStreamInfo;
|
|
23
|
-
|
|
24
|
-
export type BinaryStreamChunk = {
|
|
25
|
-
type: "chunk";
|
|
26
|
-
chunk: `binary_U${string}`;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export type BinaryStreamEnd = {
|
|
30
|
-
type: "end";
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export type BinaryCoStreamMeta = JsonObject & { type: "binary" };
|
|
34
|
-
|
|
35
|
-
export type BinaryStreamItem =
|
|
36
|
-
| BinaryStreamStart
|
|
37
|
-
| BinaryStreamChunk
|
|
38
|
-
| BinaryStreamEnd;
|
|
39
|
-
|
|
40
12
|
export type CoStreamItem<Item extends JsonValue> = {
|
|
41
13
|
value: Item;
|
|
42
14
|
tx: TransactionID;
|
|
@@ -306,145 +278,3 @@ export class RawCoStream<
|
|
|
306
278
|
this.processNewTransactions();
|
|
307
279
|
}
|
|
308
280
|
}
|
|
309
|
-
|
|
310
|
-
const binary_U_prefixLength = 8; // "binary_U".length;
|
|
311
|
-
|
|
312
|
-
export class RawBinaryCoStreamView<
|
|
313
|
-
Meta extends BinaryCoStreamMeta = { type: "binary" },
|
|
314
|
-
>
|
|
315
|
-
extends RawCoStreamView<BinaryStreamItem, Meta>
|
|
316
|
-
implements RawCoValue
|
|
317
|
-
{
|
|
318
|
-
isBinaryStreamEnded() {
|
|
319
|
-
const items = this.getSingleStream();
|
|
320
|
-
|
|
321
|
-
if (!items || items.length === 0) {
|
|
322
|
-
return false;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
const lastItem = items[items.length - 1];
|
|
326
|
-
|
|
327
|
-
return lastItem?.type === "end";
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
getBinaryStreamInfo(): BinaryStreamInfo | undefined {
|
|
331
|
-
const items = this.getSingleStream();
|
|
332
|
-
|
|
333
|
-
// No active streams
|
|
334
|
-
if (!items) return;
|
|
335
|
-
|
|
336
|
-
const start = items[0];
|
|
337
|
-
|
|
338
|
-
if (start?.type !== "start") {
|
|
339
|
-
logger.error("Invalid binary stream start", start);
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
return {
|
|
344
|
-
mimeType: start.mimeType,
|
|
345
|
-
fileName: start.fileName,
|
|
346
|
-
totalSizeBytes: start.totalSizeBytes,
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
getBinaryChunks(
|
|
351
|
-
allowUnfinished?: boolean,
|
|
352
|
-
):
|
|
353
|
-
| (BinaryStreamInfo & { chunks: Uint8Array[]; finished: boolean })
|
|
354
|
-
| undefined {
|
|
355
|
-
const items = this.getSingleStream();
|
|
356
|
-
|
|
357
|
-
// No active streams
|
|
358
|
-
if (!items) return;
|
|
359
|
-
|
|
360
|
-
const info = this.getBinaryStreamInfo();
|
|
361
|
-
|
|
362
|
-
if (!info) return;
|
|
363
|
-
|
|
364
|
-
const end = items[items.length - 1];
|
|
365
|
-
|
|
366
|
-
if (end?.type !== "end" && !allowUnfinished) return;
|
|
367
|
-
|
|
368
|
-
const chunks: Uint8Array[] = [];
|
|
369
|
-
|
|
370
|
-
let finished = false;
|
|
371
|
-
|
|
372
|
-
for (const item of items.slice(1)) {
|
|
373
|
-
if (item.type === "end") {
|
|
374
|
-
finished = true;
|
|
375
|
-
break;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
if (item.type !== "chunk") {
|
|
379
|
-
logger.error("Invalid binary stream chunk", item);
|
|
380
|
-
return undefined;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
const chunk = base64URLtoBytes(item.chunk.slice(binary_U_prefixLength));
|
|
384
|
-
chunks.push(chunk);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
return {
|
|
388
|
-
...info,
|
|
389
|
-
chunks,
|
|
390
|
-
finished,
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
export class RawBinaryCoStream<
|
|
396
|
-
Meta extends BinaryCoStreamMeta = { type: "binary" },
|
|
397
|
-
>
|
|
398
|
-
extends RawBinaryCoStreamView<Meta>
|
|
399
|
-
implements RawCoValue
|
|
400
|
-
{
|
|
401
|
-
/** @internal */
|
|
402
|
-
push(
|
|
403
|
-
item: BinaryStreamItem,
|
|
404
|
-
privacy: "private" | "trusting" = "private",
|
|
405
|
-
updateView: boolean = true,
|
|
406
|
-
): void {
|
|
407
|
-
this.core.makeTransaction([item], privacy);
|
|
408
|
-
if (updateView) {
|
|
409
|
-
this.processNewTransactions();
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
startBinaryStream(
|
|
414
|
-
settings: BinaryStreamInfo,
|
|
415
|
-
privacy: "private" | "trusting" = "private",
|
|
416
|
-
): void {
|
|
417
|
-
this.push(
|
|
418
|
-
{
|
|
419
|
-
type: "start",
|
|
420
|
-
...settings,
|
|
421
|
-
} satisfies BinaryStreamStart,
|
|
422
|
-
privacy,
|
|
423
|
-
false,
|
|
424
|
-
);
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
pushBinaryStreamChunk(
|
|
428
|
-
chunk: Uint8Array,
|
|
429
|
-
privacy: "private" | "trusting" = "private",
|
|
430
|
-
): void {
|
|
431
|
-
this.push(
|
|
432
|
-
{
|
|
433
|
-
type: "chunk",
|
|
434
|
-
chunk: `binary_U${bytesToBase64url(chunk)}`,
|
|
435
|
-
} satisfies BinaryStreamChunk,
|
|
436
|
-
privacy,
|
|
437
|
-
false,
|
|
438
|
-
);
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
endBinaryStream(privacy: "private" | "trusting" = "private") {
|
|
442
|
-
this.push(
|
|
443
|
-
{
|
|
444
|
-
type: "end",
|
|
445
|
-
} satisfies BinaryStreamEnd,
|
|
446
|
-
privacy,
|
|
447
|
-
true,
|
|
448
|
-
);
|
|
449
|
-
}
|
|
450
|
-
}
|