cojson 0.8.12 → 0.8.16
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/CHANGELOG.md +89 -83
- package/dist/native/PeerKnownStates.js +1 -1
- package/dist/native/PeerKnownStates.js.map +1 -1
- package/dist/native/PeerState.js +1 -1
- package/dist/native/PeerState.js.map +1 -1
- package/dist/native/PriorityBasedMessageQueue.js +1 -10
- package/dist/native/PriorityBasedMessageQueue.js.map +1 -1
- package/dist/native/base64url.js.map +1 -1
- package/dist/native/base64url.test.js +1 -1
- package/dist/native/base64url.test.js.map +1 -1
- package/dist/native/coValue.js.map +1 -1
- package/dist/native/coValueCore.js +141 -149
- package/dist/native/coValueCore.js.map +1 -1
- package/dist/native/coValueState.js.map +1 -1
- package/dist/native/coValues/account.js +6 -6
- package/dist/native/coValues/account.js.map +1 -1
- package/dist/native/coValues/coList.js +2 -3
- package/dist/native/coValues/coList.js.map +1 -1
- package/dist/native/coValues/coMap.js +1 -1
- package/dist/native/coValues/coMap.js.map +1 -1
- package/dist/native/coValues/coStream.js +3 -5
- package/dist/native/coValues/coStream.js.map +1 -1
- package/dist/native/coValues/group.js +11 -11
- package/dist/native/coValues/group.js.map +1 -1
- package/dist/native/coreToCoValue.js +2 -2
- package/dist/native/coreToCoValue.js.map +1 -1
- package/dist/native/crypto/PureJSCrypto.js +4 -4
- package/dist/native/crypto/PureJSCrypto.js.map +1 -1
- package/dist/native/crypto/crypto.js.map +1 -1
- package/dist/native/exports.js +12 -12
- package/dist/native/exports.js.map +1 -1
- package/dist/native/ids.js.map +1 -1
- package/dist/native/jsonStringify.js.map +1 -1
- package/dist/native/localNode.js +5 -7
- package/dist/native/localNode.js.map +1 -1
- package/dist/native/permissions.js +4 -7
- package/dist/native/permissions.js.map +1 -1
- package/dist/native/priority.js.map +1 -1
- package/dist/native/storage/FileSystem.js.map +1 -1
- package/dist/native/storage/chunksAndKnownStates.js +2 -4
- package/dist/native/storage/chunksAndKnownStates.js.map +1 -1
- package/dist/native/storage/index.js +6 -15
- package/dist/native/storage/index.js.map +1 -1
- package/dist/native/streamUtils.js.map +1 -1
- package/dist/native/sync.js +2 -4
- package/dist/native/sync.js.map +1 -1
- package/dist/native/typeUtils/accountOrAgentIDfromSessionID.js.map +1 -1
- package/dist/native/typeUtils/expectGroup.js.map +1 -1
- package/dist/native/typeUtils/isAccountID.js.map +1 -1
- package/dist/native/typeUtils/isCoValue.js +1 -1
- package/dist/native/typeUtils/isCoValue.js.map +1 -1
- package/dist/web/PeerKnownStates.js +1 -1
- package/dist/web/PeerKnownStates.js.map +1 -1
- package/dist/web/PeerState.js +1 -1
- package/dist/web/PeerState.js.map +1 -1
- package/dist/web/PriorityBasedMessageQueue.js +1 -10
- package/dist/web/PriorityBasedMessageQueue.js.map +1 -1
- package/dist/web/base64url.js.map +1 -1
- package/dist/web/base64url.test.js +1 -1
- package/dist/web/base64url.test.js.map +1 -1
- package/dist/web/coValue.js.map +1 -1
- package/dist/web/coValueCore.js +141 -149
- package/dist/web/coValueCore.js.map +1 -1
- package/dist/web/coValueState.js.map +1 -1
- package/dist/web/coValues/account.js +6 -6
- package/dist/web/coValues/account.js.map +1 -1
- package/dist/web/coValues/coList.js +2 -3
- package/dist/web/coValues/coList.js.map +1 -1
- package/dist/web/coValues/coMap.js +1 -1
- package/dist/web/coValues/coMap.js.map +1 -1
- package/dist/web/coValues/coStream.js +3 -5
- package/dist/web/coValues/coStream.js.map +1 -1
- package/dist/web/coValues/group.js +11 -11
- package/dist/web/coValues/group.js.map +1 -1
- package/dist/web/coreToCoValue.js +2 -2
- package/dist/web/coreToCoValue.js.map +1 -1
- package/dist/web/crypto/PureJSCrypto.js +4 -4
- package/dist/web/crypto/PureJSCrypto.js.map +1 -1
- package/dist/web/crypto/WasmCrypto.js +5 -5
- package/dist/web/crypto/WasmCrypto.js.map +1 -1
- package/dist/web/crypto/crypto.js.map +1 -1
- package/dist/web/exports.js +12 -12
- package/dist/web/exports.js.map +1 -1
- package/dist/web/ids.js.map +1 -1
- package/dist/web/jsonStringify.js.map +1 -1
- package/dist/web/localNode.js +5 -7
- package/dist/web/localNode.js.map +1 -1
- package/dist/web/permissions.js +4 -7
- package/dist/web/permissions.js.map +1 -1
- package/dist/web/priority.js.map +1 -1
- package/dist/web/storage/FileSystem.js.map +1 -1
- package/dist/web/storage/chunksAndKnownStates.js +2 -4
- package/dist/web/storage/chunksAndKnownStates.js.map +1 -1
- package/dist/web/storage/index.js +6 -15
- package/dist/web/storage/index.js.map +1 -1
- package/dist/web/streamUtils.js.map +1 -1
- package/dist/web/sync.js +2 -4
- package/dist/web/sync.js.map +1 -1
- package/dist/web/typeUtils/accountOrAgentIDfromSessionID.js.map +1 -1
- package/dist/web/typeUtils/expectGroup.js.map +1 -1
- package/dist/web/typeUtils/isAccountID.js.map +1 -1
- package/dist/web/typeUtils/isCoValue.js +1 -1
- package/dist/web/typeUtils/isCoValue.js.map +1 -1
- package/package.json +4 -14
- package/src/PeerKnownStates.ts +91 -89
- package/src/PeerState.ts +72 -73
- package/src/PriorityBasedMessageQueue.ts +42 -49
- package/src/base64url.test.ts +24 -24
- package/src/base64url.ts +44 -45
- package/src/coValue.ts +45 -45
- package/src/coValueCore.ts +746 -785
- package/src/coValueState.ts +82 -72
- package/src/coValues/account.ts +143 -150
- package/src/coValues/coList.ts +520 -522
- package/src/coValues/coMap.ts +283 -285
- package/src/coValues/coStream.ts +320 -324
- package/src/coValues/group.ts +306 -305
- package/src/coreToCoValue.ts +28 -31
- package/src/crypto/PureJSCrypto.ts +188 -194
- package/src/crypto/WasmCrypto.ts +236 -254
- package/src/crypto/crypto.ts +302 -309
- package/src/exports.ts +116 -116
- package/src/ids.ts +9 -9
- package/src/jsonStringify.ts +46 -46
- package/src/jsonValue.ts +24 -10
- package/src/localNode.ts +635 -660
- package/src/media.ts +3 -3
- package/src/permissions.ts +272 -278
- package/src/priority.ts +21 -19
- package/src/storage/FileSystem.ts +91 -99
- package/src/storage/chunksAndKnownStates.ts +110 -115
- package/src/storage/index.ts +466 -497
- package/src/streamUtils.ts +60 -60
- package/src/sync.ts +593 -615
- package/src/tests/PeerKnownStates.test.ts +38 -34
- package/src/tests/PeerState.test.ts +101 -64
- package/src/tests/PriorityBasedMessageQueue.test.ts +91 -91
- package/src/tests/account.test.ts +59 -59
- package/src/tests/coList.test.ts +65 -65
- package/src/tests/coMap.test.ts +137 -137
- package/src/tests/coStream.test.ts +254 -257
- package/src/tests/coValueCore.test.ts +153 -156
- package/src/tests/crypto.test.ts +136 -144
- package/src/tests/cryptoImpl.test.ts +205 -197
- package/src/tests/group.test.ts +24 -24
- package/src/tests/permissions.test.ts +1306 -1371
- package/src/tests/priority.test.ts +65 -82
- package/src/tests/sync.test.ts +1300 -1291
- package/src/tests/testUtils.ts +52 -53
- package/src/typeUtils/accountOrAgentIDfromSessionID.ts +4 -4
- package/src/typeUtils/expectGroup.ts +9 -9
- package/src/typeUtils/isAccountID.ts +1 -1
- package/src/typeUtils/isCoValue.ts +9 -9
- package/tsconfig.json +4 -6
- package/tsconfig.native.json +9 -11
- package/tsconfig.web.json +4 -10
- package/.eslintrc.cjs +0 -25
- package/.prettierrc.js +0 -9
package/src/coValues/coStream.ts
CHANGED
|
@@ -1,397 +1,393 @@
|
|
|
1
|
+
import { base64URLtoBytes, bytesToBase64url } from "../base64url.js";
|
|
2
|
+
import { CoID, RawCoValue } from "../coValue.js";
|
|
3
|
+
import { CoValueCore } from "../coValueCore.js";
|
|
4
|
+
import { AgentID, SessionID, TransactionID } from "../ids.js";
|
|
1
5
|
import { JsonObject, JsonValue } from "../jsonValue.js";
|
|
2
|
-
import {
|
|
6
|
+
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
|
3
7
|
import { isAccountID } from "../typeUtils/isAccountID.js";
|
|
4
8
|
import { isCoValue } from "../typeUtils/isCoValue.js";
|
|
5
|
-
import { CoValueCore } from "../coValueCore.js";
|
|
6
|
-
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
|
7
|
-
import { RawGroup } from "./group.js";
|
|
8
|
-
import { AgentID, SessionID, TransactionID } from "../ids.js";
|
|
9
|
-
import { base64URLtoBytes, bytesToBase64url } from "../base64url.js";
|
|
10
9
|
import { RawAccountID } from "./account.js";
|
|
10
|
+
import { RawGroup } from "./group.js";
|
|
11
11
|
|
|
12
12
|
export type BinaryStreamInfo = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
mimeType: string;
|
|
14
|
+
fileName?: string;
|
|
15
|
+
totalSizeBytes?: number;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
export type BinaryStreamStart = {
|
|
19
|
-
|
|
19
|
+
type: "start";
|
|
20
20
|
} & BinaryStreamInfo;
|
|
21
21
|
|
|
22
22
|
export type BinaryStreamChunk = {
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
type: "chunk";
|
|
24
|
+
chunk: `binary_U${string}`;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
export type BinaryStreamEnd = {
|
|
28
|
-
|
|
28
|
+
type: "end";
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export type BinaryCoStreamMeta = JsonObject & { type: "binary" };
|
|
32
32
|
|
|
33
33
|
export type BinaryStreamItem =
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
| BinaryStreamStart
|
|
35
|
+
| BinaryStreamChunk
|
|
36
|
+
| BinaryStreamEnd;
|
|
37
37
|
|
|
38
38
|
export type CoStreamItem<Item extends JsonValue> = {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
value: Item;
|
|
40
|
+
tx: TransactionID;
|
|
41
|
+
madeAt: number;
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
export class RawCoStreamView<
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
Item extends JsonValue = JsonValue,
|
|
46
|
+
Meta extends JsonObject | null = JsonObject | null,
|
|
47
47
|
> implements RawCoValue
|
|
48
48
|
{
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
entries.push({ value: change, madeAt, tx: txID });
|
|
94
|
-
}
|
|
49
|
+
id: CoID<this>;
|
|
50
|
+
type = "costream" as const;
|
|
51
|
+
core: CoValueCore;
|
|
52
|
+
items: {
|
|
53
|
+
[key: SessionID]: CoStreamItem<Item>[];
|
|
54
|
+
};
|
|
55
|
+
readonly _item!: Item;
|
|
56
|
+
|
|
57
|
+
constructor(core: CoValueCore) {
|
|
58
|
+
this.id = core.id as CoID<this>;
|
|
59
|
+
this.core = core;
|
|
60
|
+
this.items = {};
|
|
61
|
+
this.fillFromCoValue();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get headerMeta(): Meta {
|
|
65
|
+
return this.core.header.meta as Meta;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get group(): RawGroup {
|
|
69
|
+
return this.core.getGroup();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Not yet implemented */
|
|
73
|
+
atTime(_time: number): this {
|
|
74
|
+
throw new Error("Not yet implemented");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** @internal */
|
|
78
|
+
protected fillFromCoValue() {
|
|
79
|
+
this.items = {};
|
|
80
|
+
|
|
81
|
+
for (const {
|
|
82
|
+
txID,
|
|
83
|
+
madeAt,
|
|
84
|
+
changes,
|
|
85
|
+
} of this.core.getValidSortedTransactions()) {
|
|
86
|
+
for (const changeUntyped of changes) {
|
|
87
|
+
const change = changeUntyped as Item;
|
|
88
|
+
let entries = this.items[txID.sessionID];
|
|
89
|
+
if (!entries) {
|
|
90
|
+
entries = [];
|
|
91
|
+
this.items[txID.sessionID] = entries;
|
|
95
92
|
}
|
|
93
|
+
entries.push({ value: change, madeAt, tx: txID });
|
|
94
|
+
}
|
|
96
95
|
}
|
|
96
|
+
}
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (!firstStream) {
|
|
103
|
-
return undefined;
|
|
104
|
-
}
|
|
98
|
+
getSingleStream(): Item[] | undefined {
|
|
99
|
+
const streams = Object.values(this.items);
|
|
100
|
+
const firstStream = streams[0];
|
|
105
101
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
"CoStream.getSingleStream() can only be called when there is exactly one stream",
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return firstStream.map((item) => item.value);
|
|
102
|
+
if (!firstStream) {
|
|
103
|
+
return undefined;
|
|
113
104
|
}
|
|
114
105
|
|
|
115
|
-
|
|
116
|
-
|
|
106
|
+
if (streams.length > 1) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
"CoStream.getSingleStream() can only be called when there is exactly one stream",
|
|
109
|
+
);
|
|
117
110
|
}
|
|
118
111
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
112
|
+
return firstStream.map((item) => item.value);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
sessions(): SessionID[] {
|
|
116
|
+
return Object.keys(this.items) as SessionID[];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
accounts(): Set<RawAccountID> {
|
|
120
|
+
return new Set(
|
|
121
|
+
this.sessions().map(accountOrAgentIDfromSessionID).filter(isAccountID),
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
nthItemIn(
|
|
126
|
+
sessionID: SessionID,
|
|
127
|
+
n: number,
|
|
128
|
+
):
|
|
129
|
+
| {
|
|
130
|
+
by: RawAccountID | AgentID;
|
|
131
|
+
tx: TransactionID;
|
|
132
|
+
at: Date;
|
|
133
|
+
value: Item;
|
|
134
|
+
}
|
|
135
|
+
| undefined {
|
|
136
|
+
const items = this.items[sessionID];
|
|
137
|
+
if (!items) return;
|
|
138
|
+
|
|
139
|
+
const item = items[n];
|
|
140
|
+
if (!item) return;
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
by: accountOrAgentIDfromSessionID(sessionID),
|
|
144
|
+
tx: item.tx,
|
|
145
|
+
at: new Date(item.madeAt),
|
|
146
|
+
value: item.value,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
lastItemIn(sessionID: SessionID):
|
|
151
|
+
| {
|
|
152
|
+
by: RawAccountID | AgentID;
|
|
153
|
+
tx: TransactionID;
|
|
154
|
+
at: Date;
|
|
155
|
+
value: Item;
|
|
156
|
+
}
|
|
157
|
+
| undefined {
|
|
158
|
+
const items = this.items[sessionID];
|
|
159
|
+
if (!items) return;
|
|
160
|
+
return this.nthItemIn(sessionID, items.length - 1);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
*itemsIn(sessionID: SessionID) {
|
|
164
|
+
const items = this.items[sessionID];
|
|
165
|
+
if (!items) return;
|
|
166
|
+
for (const item of items) {
|
|
167
|
+
yield {
|
|
168
|
+
by: accountOrAgentIDfromSessionID(sessionID),
|
|
169
|
+
tx: item.tx,
|
|
170
|
+
at: new Date(item.madeAt),
|
|
171
|
+
value: item.value as Item,
|
|
172
|
+
};
|
|
125
173
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
lastItemBy(account: RawAccountID | AgentID):
|
|
177
|
+
| {
|
|
178
|
+
by: RawAccountID | AgentID;
|
|
179
|
+
tx: TransactionID;
|
|
180
|
+
at: Date;
|
|
181
|
+
value: Item;
|
|
182
|
+
}
|
|
183
|
+
| undefined {
|
|
184
|
+
let latestItem:
|
|
185
|
+
| {
|
|
186
|
+
by: RawAccountID | AgentID;
|
|
187
|
+
tx: TransactionID;
|
|
188
|
+
at: Date;
|
|
189
|
+
value: Item;
|
|
190
|
+
}
|
|
191
|
+
| undefined;
|
|
192
|
+
|
|
193
|
+
for (const sessionID of Object.keys(this.items)) {
|
|
194
|
+
if (sessionID.startsWith(account)) {
|
|
195
|
+
const item = this.lastItemIn(sessionID as SessionID);
|
|
196
|
+
if (!item) continue;
|
|
197
|
+
if (!latestItem || item.at > latestItem.at) {
|
|
198
|
+
latestItem = {
|
|
199
|
+
by: item.by,
|
|
146
200
|
tx: item.tx,
|
|
147
|
-
at:
|
|
201
|
+
at: item.at,
|
|
148
202
|
value: item.value,
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
lastItemIn(sessionID: SessionID):
|
|
153
|
-
| {
|
|
154
|
-
by: RawAccountID | AgentID;
|
|
155
|
-
tx: TransactionID;
|
|
156
|
-
at: Date;
|
|
157
|
-
value: Item;
|
|
158
|
-
}
|
|
159
|
-
| undefined {
|
|
160
|
-
const items = this.items[sessionID];
|
|
161
|
-
if (!items) return;
|
|
162
|
-
return this.nthItemIn(sessionID, items.length - 1);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
*itemsIn(sessionID: SessionID) {
|
|
166
|
-
const items = this.items[sessionID];
|
|
167
|
-
if (!items) return;
|
|
168
|
-
for (const item of items) {
|
|
169
|
-
yield {
|
|
170
|
-
by: accountOrAgentIDfromSessionID(sessionID),
|
|
171
|
-
tx: item.tx,
|
|
172
|
-
at: new Date(item.madeAt),
|
|
173
|
-
value: item.value as Item,
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
lastItemBy(account: RawAccountID | AgentID):
|
|
179
|
-
| {
|
|
180
|
-
by: RawAccountID | AgentID;
|
|
181
|
-
tx: TransactionID;
|
|
182
|
-
at: Date;
|
|
183
|
-
value: Item;
|
|
184
|
-
}
|
|
185
|
-
| undefined {
|
|
186
|
-
let latestItem:
|
|
187
|
-
| {
|
|
188
|
-
by: RawAccountID | AgentID;
|
|
189
|
-
tx: TransactionID;
|
|
190
|
-
at: Date;
|
|
191
|
-
value: Item;
|
|
192
|
-
}
|
|
193
|
-
| undefined;
|
|
194
|
-
|
|
195
|
-
for (const sessionID of Object.keys(this.items)) {
|
|
196
|
-
if (sessionID.startsWith(account)) {
|
|
197
|
-
const item = this.lastItemIn(sessionID as SessionID);
|
|
198
|
-
if (!item) continue;
|
|
199
|
-
if (!latestItem || item.at > latestItem.at) {
|
|
200
|
-
latestItem = {
|
|
201
|
-
by: item.by,
|
|
202
|
-
tx: item.tx,
|
|
203
|
-
at: item.at,
|
|
204
|
-
value: item.value,
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
}
|
|
203
|
+
};
|
|
208
204
|
}
|
|
209
|
-
|
|
210
|
-
return latestItem;
|
|
205
|
+
}
|
|
211
206
|
}
|
|
212
207
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
toJSON(): {
|
|
234
|
-
[key: SessionID]: Item[];
|
|
235
|
-
} {
|
|
236
|
-
return Object.fromEntries(
|
|
237
|
-
Object.entries(this.items).map(([sessionID, items]) => [
|
|
238
|
-
sessionID,
|
|
239
|
-
items.map((item) => item.value),
|
|
240
|
-
]),
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
subscribe(listener: (coStream: this) => void): () => void {
|
|
245
|
-
return this.core.subscribe((content) => {
|
|
246
|
-
listener(content as this);
|
|
247
|
-
});
|
|
208
|
+
return latestItem;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
*itemsBy(account: RawAccountID | AgentID) {
|
|
212
|
+
// TODO: this can be made more lazy without a huge collect and sort
|
|
213
|
+
const items = [
|
|
214
|
+
...Object.keys(this.items).flatMap((sessionID) =>
|
|
215
|
+
sessionID.startsWith(account)
|
|
216
|
+
? [...this.itemsIn(sessionID as SessionID)].map((item) => ({
|
|
217
|
+
in: sessionID as SessionID,
|
|
218
|
+
...item,
|
|
219
|
+
}))
|
|
220
|
+
: [],
|
|
221
|
+
),
|
|
222
|
+
];
|
|
223
|
+
|
|
224
|
+
items.sort((a, b) => a.at.getTime() - b.at.getTime());
|
|
225
|
+
|
|
226
|
+
for (const item of items) {
|
|
227
|
+
yield item;
|
|
248
228
|
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
toJSON(): {
|
|
232
|
+
[key: SessionID]: Item[];
|
|
233
|
+
} {
|
|
234
|
+
return Object.fromEntries(
|
|
235
|
+
Object.entries(this.items).map(([sessionID, items]) => [
|
|
236
|
+
sessionID,
|
|
237
|
+
items.map((item) => item.value),
|
|
238
|
+
]),
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
subscribe(listener: (coStream: this) => void): () => void {
|
|
243
|
+
return this.core.subscribe((content) => {
|
|
244
|
+
listener(content as this);
|
|
245
|
+
});
|
|
246
|
+
}
|
|
249
247
|
}
|
|
250
248
|
|
|
251
249
|
export class RawCoStream<
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
250
|
+
Item extends JsonValue = JsonValue,
|
|
251
|
+
Meta extends JsonObject | null = JsonObject | null,
|
|
252
|
+
>
|
|
253
|
+
extends RawCoStreamView<Item, Meta>
|
|
254
|
+
implements RawCoValue
|
|
257
255
|
{
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
256
|
+
push(item: Item, privacy: "private" | "trusting" = "private"): void {
|
|
257
|
+
this.core.makeTransaction([isCoValue(item) ? item.id : item], privacy);
|
|
258
|
+
this.fillFromCoValue();
|
|
259
|
+
}
|
|
262
260
|
}
|
|
263
261
|
|
|
264
262
|
const binary_U_prefixLength = 8; // "binary_U".length;
|
|
265
263
|
|
|
266
264
|
export class RawBinaryCoStreamView<
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
265
|
+
Meta extends BinaryCoStreamMeta = { type: "binary" },
|
|
266
|
+
>
|
|
267
|
+
extends RawCoStreamView<BinaryStreamItem, Meta>
|
|
268
|
+
implements RawCoValue
|
|
271
269
|
{
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
if (!items || items.length === 0) {
|
|
276
|
-
return false;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const lastItem = items[items.length - 1];
|
|
270
|
+
isBinaryStreamEnded() {
|
|
271
|
+
const items = this.getSingleStream();
|
|
280
272
|
|
|
281
|
-
|
|
273
|
+
if (!items || items.length === 0) {
|
|
274
|
+
return false;
|
|
282
275
|
}
|
|
283
276
|
|
|
284
|
-
|
|
285
|
-
allowUnfinished?: boolean,
|
|
286
|
-
):
|
|
287
|
-
| (BinaryStreamInfo & { chunks: Uint8Array[]; finished: boolean })
|
|
288
|
-
| undefined {
|
|
289
|
-
const items = this.getSingleStream();
|
|
277
|
+
const lastItem = items[items.length - 1];
|
|
290
278
|
|
|
291
|
-
|
|
292
|
-
|
|
279
|
+
return lastItem?.type === "end";
|
|
280
|
+
}
|
|
293
281
|
|
|
294
|
-
|
|
282
|
+
getBinaryChunks(
|
|
283
|
+
allowUnfinished?: boolean,
|
|
284
|
+
):
|
|
285
|
+
| (BinaryStreamInfo & { chunks: Uint8Array[]; finished: boolean })
|
|
286
|
+
| undefined {
|
|
287
|
+
const items = this.getSingleStream();
|
|
295
288
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
289
|
+
// No active streams
|
|
290
|
+
if (!items) return;
|
|
291
|
+
|
|
292
|
+
const start = items[0];
|
|
300
293
|
|
|
301
|
-
|
|
294
|
+
if (start?.type !== "start") {
|
|
295
|
+
console.error("Invalid binary stream start", start);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
302
298
|
|
|
303
|
-
|
|
299
|
+
const end = items[items.length - 1];
|
|
304
300
|
|
|
305
|
-
|
|
301
|
+
if (end?.type !== "end" && !allowUnfinished) return;
|
|
306
302
|
|
|
307
|
-
|
|
303
|
+
const chunks: Uint8Array[] = [];
|
|
308
304
|
|
|
309
|
-
|
|
310
|
-
if (item.type === "end") {
|
|
311
|
-
finished = true;
|
|
312
|
-
break;
|
|
313
|
-
}
|
|
305
|
+
let finished = false;
|
|
314
306
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
307
|
+
for (const item of items.slice(1)) {
|
|
308
|
+
if (item.type === "end") {
|
|
309
|
+
finished = true;
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
319
312
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
313
|
+
if (item.type !== "chunk") {
|
|
314
|
+
console.error("Invalid binary stream chunk", item);
|
|
315
|
+
return undefined;
|
|
316
|
+
}
|
|
325
317
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
fileName: start.fileName,
|
|
329
|
-
totalSizeBytes: start.totalSizeBytes,
|
|
330
|
-
chunks,
|
|
331
|
-
finished,
|
|
332
|
-
};
|
|
318
|
+
const chunk = base64URLtoBytes(item.chunk.slice(binary_U_prefixLength));
|
|
319
|
+
chunks.push(chunk);
|
|
333
320
|
}
|
|
321
|
+
|
|
322
|
+
return {
|
|
323
|
+
mimeType: start.mimeType,
|
|
324
|
+
fileName: start.fileName,
|
|
325
|
+
totalSizeBytes: start.totalSizeBytes,
|
|
326
|
+
chunks,
|
|
327
|
+
finished,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
334
330
|
}
|
|
335
331
|
|
|
336
332
|
export class RawBinaryCoStream<
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
333
|
+
Meta extends BinaryCoStreamMeta = { type: "binary" },
|
|
334
|
+
>
|
|
335
|
+
extends RawBinaryCoStreamView<Meta>
|
|
336
|
+
implements RawCoValue
|
|
341
337
|
{
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
startBinaryStream(
|
|
355
|
-
settings: BinaryStreamInfo,
|
|
356
|
-
privacy: "private" | "trusting" = "private",
|
|
357
|
-
): void {
|
|
358
|
-
this.push(
|
|
359
|
-
{
|
|
360
|
-
type: "start",
|
|
361
|
-
...settings,
|
|
362
|
-
} satisfies BinaryStreamStart,
|
|
363
|
-
privacy,
|
|
364
|
-
false,
|
|
365
|
-
);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
pushBinaryStreamChunk(
|
|
369
|
-
chunk: Uint8Array,
|
|
370
|
-
privacy: "private" | "trusting" = "private",
|
|
371
|
-
): void {
|
|
372
|
-
// const before = performance.now();
|
|
373
|
-
this.push(
|
|
374
|
-
{
|
|
375
|
-
type: "chunk",
|
|
376
|
-
chunk: `binary_U${bytesToBase64url(chunk)}`,
|
|
377
|
-
} satisfies BinaryStreamChunk,
|
|
378
|
-
privacy,
|
|
379
|
-
false,
|
|
380
|
-
);
|
|
381
|
-
// const after = performance.now();
|
|
382
|
-
// console.log(
|
|
383
|
-
// "pushBinaryStreamChunk bandwidth in MB/s",
|
|
384
|
-
// (1000 * chunk.length) / (after - before) / (1024 * 1024)
|
|
385
|
-
// );
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
endBinaryStream(privacy: "private" | "trusting" = "private") {
|
|
389
|
-
this.push(
|
|
390
|
-
{
|
|
391
|
-
type: "end",
|
|
392
|
-
} satisfies BinaryStreamEnd,
|
|
393
|
-
privacy,
|
|
394
|
-
true,
|
|
395
|
-
);
|
|
338
|
+
/** @internal */
|
|
339
|
+
push(
|
|
340
|
+
item: BinaryStreamItem,
|
|
341
|
+
privacy: "private" | "trusting" = "private",
|
|
342
|
+
updateView: boolean = true,
|
|
343
|
+
): void {
|
|
344
|
+
this.core.makeTransaction([item], privacy);
|
|
345
|
+
if (updateView) {
|
|
346
|
+
this.fillFromCoValue();
|
|
396
347
|
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
startBinaryStream(
|
|
351
|
+
settings: BinaryStreamInfo,
|
|
352
|
+
privacy: "private" | "trusting" = "private",
|
|
353
|
+
): void {
|
|
354
|
+
this.push(
|
|
355
|
+
{
|
|
356
|
+
type: "start",
|
|
357
|
+
...settings,
|
|
358
|
+
} satisfies BinaryStreamStart,
|
|
359
|
+
privacy,
|
|
360
|
+
false,
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
pushBinaryStreamChunk(
|
|
365
|
+
chunk: Uint8Array,
|
|
366
|
+
privacy: "private" | "trusting" = "private",
|
|
367
|
+
): void {
|
|
368
|
+
// const before = performance.now();
|
|
369
|
+
this.push(
|
|
370
|
+
{
|
|
371
|
+
type: "chunk",
|
|
372
|
+
chunk: `binary_U${bytesToBase64url(chunk)}`,
|
|
373
|
+
} satisfies BinaryStreamChunk,
|
|
374
|
+
privacy,
|
|
375
|
+
false,
|
|
376
|
+
);
|
|
377
|
+
// const after = performance.now();
|
|
378
|
+
// console.log(
|
|
379
|
+
// "pushBinaryStreamChunk bandwidth in MB/s",
|
|
380
|
+
// (1000 * chunk.length) / (after - before) / (1024 * 1024)
|
|
381
|
+
// );
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
endBinaryStream(privacy: "private" | "trusting" = "private") {
|
|
385
|
+
this.push(
|
|
386
|
+
{
|
|
387
|
+
type: "end",
|
|
388
|
+
} satisfies BinaryStreamEnd,
|
|
389
|
+
privacy,
|
|
390
|
+
true,
|
|
391
|
+
);
|
|
392
|
+
}
|
|
397
393
|
}
|