cojson 0.8.0 → 0.8.5
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 +11 -3
- package/CHANGELOG.md +13 -0
- package/dist/native/PeerState.js.map +1 -0
- package/dist/native/PriorityBasedMessageQueue.js.map +1 -0
- package/dist/native/base64url.js.map +1 -0
- package/dist/native/base64url.test.js.map +1 -0
- package/dist/native/coValue.js.map +1 -0
- package/dist/native/coValueCore.js.map +1 -0
- package/dist/native/coValues/account.js.map +1 -0
- package/dist/native/coValues/coList.js.map +1 -0
- package/dist/native/coValues/coMap.js.map +1 -0
- package/dist/native/coValues/coStream.js.map +1 -0
- package/dist/native/coValues/group.js.map +1 -0
- package/dist/native/coreToCoValue.js.map +1 -0
- package/dist/{crypto → native/crypto}/PureJSCrypto.js +4 -0
- package/dist/native/crypto/PureJSCrypto.js.map +1 -0
- package/dist/{crypto → native/crypto}/crypto.js +1 -1
- package/dist/native/crypto/crypto.js.map +1 -0
- package/dist/native/ids.js.map +1 -0
- package/dist/{index.js → native/index.native.js} +3 -4
- package/dist/native/index.native.js.map +1 -0
- package/dist/native/jsonStringify.js.map +1 -0
- package/dist/{jsonValue.js.map → native/jsonValue.js.map} +1 -1
- package/dist/{localNode.js → native/localNode.js} +50 -33
- package/dist/native/localNode.js.map +1 -0
- package/dist/native/media.js.map +1 -0
- package/dist/native/permissions.js.map +1 -0
- package/dist/native/priority.js.map +1 -0
- package/dist/native/storage/FileSystem.js.map +1 -0
- package/dist/{storage → native/storage}/chunksAndKnownStates.js +1 -1
- package/dist/native/storage/chunksAndKnownStates.js.map +1 -0
- package/dist/native/storage/index.js.map +1 -0
- package/dist/native/streamUtils.js.map +1 -0
- package/dist/native/sync.js.map +1 -0
- package/dist/native/typeUtils/accountOrAgentIDfromSessionID.js.map +1 -0
- package/dist/native/typeUtils/expectGroup.js.map +1 -0
- package/dist/native/typeUtils/isAccountID.js.map +1 -0
- package/dist/native/typeUtils/isCoValue.js.map +1 -0
- package/dist/web/PeerState.js +66 -0
- package/dist/web/PeerState.js.map +1 -0
- package/dist/web/PriorityBasedMessageQueue.js +51 -0
- package/dist/web/PriorityBasedMessageQueue.js.map +1 -0
- package/dist/web/base64url.js +59 -0
- package/dist/web/base64url.js.map +1 -0
- package/dist/web/base64url.test.js +25 -0
- package/dist/web/base64url.test.js.map +1 -0
- package/dist/web/coValue.js +19 -0
- package/dist/web/coValue.js.map +1 -0
- package/dist/web/coValueCore.js +693 -0
- package/dist/web/coValueCore.js.map +1 -0
- package/dist/web/coValues/account.js +96 -0
- package/dist/web/coValues/account.js.map +1 -0
- package/dist/web/coValues/coList.js +393 -0
- package/dist/web/coValues/coList.js.map +1 -0
- package/dist/web/coValues/coMap.js +197 -0
- package/dist/web/coValues/coMap.js.map +1 -0
- package/dist/web/coValues/coStream.js +220 -0
- package/dist/web/coValues/coStream.js.map +1 -0
- package/dist/web/coValues/group.js +250 -0
- package/dist/web/coValues/group.js.map +1 -0
- package/dist/web/coreToCoValue.js +42 -0
- package/dist/web/coreToCoValue.js.map +1 -0
- package/dist/web/crypto/PureJSCrypto.js +93 -0
- package/dist/web/crypto/PureJSCrypto.js.map +1 -0
- package/dist/{crypto → web/crypto}/WasmCrypto.js +3 -0
- package/dist/web/crypto/WasmCrypto.js.map +1 -0
- package/dist/web/crypto/crypto.js +154 -0
- package/dist/web/crypto/crypto.js.map +1 -0
- package/dist/web/ids.js +17 -0
- package/dist/web/ids.js.map +1 -0
- package/dist/web/index.web.js +40 -0
- package/dist/web/index.web.js.map +1 -0
- package/dist/web/jsonStringify.js +57 -0
- package/dist/web/jsonStringify.js.map +1 -0
- package/dist/web/jsonValue.js +2 -0
- package/dist/web/jsonValue.js.map +1 -0
- package/dist/web/localNode.js +453 -0
- package/dist/web/localNode.js.map +1 -0
- package/dist/web/media.js +2 -0
- package/dist/web/media.js.map +1 -0
- package/dist/web/permissions.js +206 -0
- package/dist/web/permissions.js.map +1 -0
- package/dist/web/priority.js +31 -0
- package/dist/web/priority.js.map +1 -0
- package/dist/web/storage/FileSystem.js +58 -0
- package/dist/web/storage/FileSystem.js.map +1 -0
- package/dist/web/storage/chunksAndKnownStates.js +100 -0
- package/dist/web/storage/chunksAndKnownStates.js.map +1 -0
- package/dist/web/storage/index.js +348 -0
- package/dist/web/storage/index.js.map +1 -0
- package/dist/web/streamUtils.js +41 -0
- package/dist/web/streamUtils.js.map +1 -0
- package/dist/web/sync.js +504 -0
- package/dist/web/sync.js.map +1 -0
- package/dist/web/typeUtils/accountOrAgentIDfromSessionID.js +5 -0
- package/dist/web/typeUtils/accountOrAgentIDfromSessionID.js.map +1 -0
- package/dist/web/typeUtils/expectGroup.js +13 -0
- package/dist/web/typeUtils/expectGroup.js.map +1 -0
- package/dist/web/typeUtils/isAccountID.js +4 -0
- package/dist/web/typeUtils/isAccountID.js.map +1 -0
- package/dist/web/typeUtils/isCoValue.js +11 -0
- package/dist/web/typeUtils/isCoValue.js.map +1 -0
- package/package.json +25 -8
- package/src/coValue.ts +1 -1
- package/src/coValueCore.ts +4 -1
- package/src/coValues/account.ts +9 -3
- package/src/crypto/PureJSCrypto.ts +5 -0
- package/src/crypto/WasmCrypto.ts +4 -0
- package/src/crypto/crypto.ts +7 -2
- package/src/{index.ts → index.native.ts} +4 -5
- package/src/index.web.ts +152 -0
- package/src/jsonValue.ts +25 -0
- package/src/localNode.ts +74 -55
- package/src/storage/chunksAndKnownStates.ts +1 -1
- package/src/storage/index.ts +1 -1
- package/src/tests/coList.test.ts +1 -1
- package/src/tests/coMap.test.ts +1 -1
- package/src/tests/coStream.test.ts +2 -1
- package/src/tests/cryptoImpl.test.ts +24 -2
- package/src/tests/group.test.ts +6 -8
- package/src/tests/permissions.test.ts +66 -18
- package/src/tests/priority.test.ts +44 -15
- package/tsconfig.json +5 -4
- package/tsconfig.native.json +12 -0
- package/tsconfig.web.json +11 -0
- package/dist/PeerState.js.map +0 -1
- package/dist/PriorityBasedMessageQueue.js.map +0 -1
- package/dist/base64url.js.map +0 -1
- package/dist/base64url.test.js.map +0 -1
- package/dist/coValue.js.map +0 -1
- package/dist/coValueCore.js.map +0 -1
- package/dist/coValues/account.js.map +0 -1
- package/dist/coValues/coList.js.map +0 -1
- package/dist/coValues/coMap.js.map +0 -1
- package/dist/coValues/coStream.js.map +0 -1
- package/dist/coValues/group.js.map +0 -1
- package/dist/coreToCoValue.js.map +0 -1
- package/dist/crypto/PureJSCrypto.js.map +0 -1
- package/dist/crypto/WasmCrypto.js.map +0 -1
- package/dist/crypto/crypto.js.map +0 -1
- package/dist/ids.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/jsonStringify.js.map +0 -1
- package/dist/localNode.js.map +0 -1
- package/dist/media.js.map +0 -1
- package/dist/permissions.js.map +0 -1
- package/dist/priority.js.map +0 -1
- package/dist/storage/FileSystem.js.map +0 -1
- package/dist/storage/chunksAndKnownStates.js.map +0 -1
- package/dist/storage/index.js.map +0 -1
- package/dist/streamUtils.js.map +0 -1
- package/dist/sync.js.map +0 -1
- package/dist/tests/PeerState.test.js +0 -80
- package/dist/tests/PeerState.test.js.map +0 -1
- package/dist/tests/PriorityBasedMessageQueue.test.js +0 -97
- package/dist/tests/PriorityBasedMessageQueue.test.js.map +0 -1
- package/dist/tests/account.test.js +0 -58
- package/dist/tests/account.test.js.map +0 -1
- package/dist/tests/coList.test.js +0 -76
- package/dist/tests/coList.test.js.map +0 -1
- package/dist/tests/coMap.test.js +0 -136
- package/dist/tests/coMap.test.js.map +0 -1
- package/dist/tests/coStream.test.js +0 -205
- package/dist/tests/coStream.test.js.map +0 -1
- package/dist/tests/coValueCore.test.js +0 -124
- package/dist/tests/coValueCore.test.js.map +0 -1
- package/dist/tests/crypto.test.js +0 -118
- package/dist/tests/crypto.test.js.map +0 -1
- package/dist/tests/cryptoImpl.test.js +0 -113
- package/dist/tests/cryptoImpl.test.js.map +0 -1
- package/dist/tests/group.test.js +0 -34
- package/dist/tests/group.test.js.map +0 -1
- package/dist/tests/permissions.test.js +0 -1059
- package/dist/tests/permissions.test.js.map +0 -1
- package/dist/tests/priority.test.js +0 -61
- package/dist/tests/priority.test.js.map +0 -1
- package/dist/tests/sync.test.js +0 -1186
- package/dist/tests/sync.test.js.map +0 -1
- package/dist/tests/testUtils.js +0 -59
- package/dist/tests/testUtils.js.map +0 -1
- package/dist/typeUtils/accountOrAgentIDfromSessionID.js.map +0 -1
- package/dist/typeUtils/expectGroup.js.map +0 -1
- package/dist/typeUtils/isAccountID.js.map +0 -1
- package/dist/typeUtils/isCoValue.js.map +0 -1
- /package/dist/{PeerState.js → native/PeerState.js} +0 -0
- /package/dist/{PriorityBasedMessageQueue.js → native/PriorityBasedMessageQueue.js} +0 -0
- /package/dist/{base64url.js → native/base64url.js} +0 -0
- /package/dist/{base64url.test.js → native/base64url.test.js} +0 -0
- /package/dist/{coValue.js → native/coValue.js} +0 -0
- /package/dist/{coValueCore.js → native/coValueCore.js} +0 -0
- /package/dist/{coValues → native/coValues}/account.js +0 -0
- /package/dist/{coValues → native/coValues}/coList.js +0 -0
- /package/dist/{coValues → native/coValues}/coMap.js +0 -0
- /package/dist/{coValues → native/coValues}/coStream.js +0 -0
- /package/dist/{coValues → native/coValues}/group.js +0 -0
- /package/dist/{coreToCoValue.js → native/coreToCoValue.js} +0 -0
- /package/dist/{ids.js → native/ids.js} +0 -0
- /package/dist/{jsonStringify.js → native/jsonStringify.js} +0 -0
- /package/dist/{jsonValue.js → native/jsonValue.js} +0 -0
- /package/dist/{media.js → native/media.js} +0 -0
- /package/dist/{permissions.js → native/permissions.js} +0 -0
- /package/dist/{priority.js → native/priority.js} +0 -0
- /package/dist/{storage → native/storage}/FileSystem.js +0 -0
- /package/dist/{storage → native/storage}/index.js +0 -0
- /package/dist/{streamUtils.js → native/streamUtils.js} +0 -0
- /package/dist/{sync.js → native/sync.js} +0 -0
- /package/dist/{typeUtils → native/typeUtils}/accountOrAgentIDfromSessionID.js +0 -0
- /package/dist/{typeUtils → native/typeUtils}/expectGroup.js +0 -0
- /package/dist/{typeUtils → native/typeUtils}/isAccountID.js +0 -0
- /package/dist/{typeUtils → native/typeUtils}/isCoValue.js +0 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { isCoValue } from "../typeUtils/isCoValue.js";
|
|
2
|
+
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
|
3
|
+
export class RawCoMapView {
|
|
4
|
+
/** @internal */
|
|
5
|
+
constructor(core, options) {
|
|
6
|
+
/** @category 6. Meta */
|
|
7
|
+
this.type = "comap";
|
|
8
|
+
/** @internal */
|
|
9
|
+
this.atTimeFilter = undefined;
|
|
10
|
+
this.id = core.id;
|
|
11
|
+
this.core = core;
|
|
12
|
+
this.ops = {};
|
|
13
|
+
for (const { txID, changes, madeAt } of core.getValidSortedTransactions(options)) {
|
|
14
|
+
for (const [changeIdx, changeUntyped] of changes.entries()) {
|
|
15
|
+
const change = changeUntyped;
|
|
16
|
+
let entries = this.ops[change.key];
|
|
17
|
+
if (!entries) {
|
|
18
|
+
entries = [];
|
|
19
|
+
this.ops[change.key] = entries;
|
|
20
|
+
}
|
|
21
|
+
entries.push({
|
|
22
|
+
txID,
|
|
23
|
+
madeAt,
|
|
24
|
+
changeIdx,
|
|
25
|
+
...change,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** @category 6. Meta */
|
|
31
|
+
get headerMeta() {
|
|
32
|
+
return this.core.header.meta;
|
|
33
|
+
}
|
|
34
|
+
/** @category 6. Meta */
|
|
35
|
+
get group() {
|
|
36
|
+
return this.core.getGroup();
|
|
37
|
+
}
|
|
38
|
+
/** @category 4. Time travel */
|
|
39
|
+
atTime(time) {
|
|
40
|
+
const clone = Object.create(this);
|
|
41
|
+
clone.id = this.id;
|
|
42
|
+
clone.type = this.type;
|
|
43
|
+
clone.core = this.core;
|
|
44
|
+
clone.ops = this.ops;
|
|
45
|
+
clone.atTimeFilter = time;
|
|
46
|
+
return clone;
|
|
47
|
+
}
|
|
48
|
+
/** @internal */
|
|
49
|
+
timeFilteredOps(key) {
|
|
50
|
+
if (this.atTimeFilter) {
|
|
51
|
+
return this.ops[key]?.filter((op) => op.madeAt <= this.atTimeFilter);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
return this.ops[key];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get all keys currently in the map.
|
|
59
|
+
*
|
|
60
|
+
* @category 1. Reading */
|
|
61
|
+
keys() {
|
|
62
|
+
return Object.keys(this.ops).filter((key) => {
|
|
63
|
+
const ops = this.ops[key];
|
|
64
|
+
if (!ops) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
const includeUntil = this.atTimeFilter;
|
|
68
|
+
const lastEntry = includeUntil
|
|
69
|
+
? ops.findLast((entry) => entry.madeAt <= includeUntil)
|
|
70
|
+
: ops[ops.length - 1];
|
|
71
|
+
if (lastEntry?.op === "del") {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns the current value for the given key.
|
|
81
|
+
*
|
|
82
|
+
* @category 1. Reading
|
|
83
|
+
**/
|
|
84
|
+
get(key) {
|
|
85
|
+
const ops = this.ops[key];
|
|
86
|
+
if (!ops) {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
const includeUntil = this.atTimeFilter;
|
|
90
|
+
const lastEntry = includeUntil
|
|
91
|
+
? ops.findLast((entry) => entry.madeAt <= includeUntil)
|
|
92
|
+
: ops[ops.length - 1];
|
|
93
|
+
if (lastEntry?.op === "del") {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
return lastEntry?.value;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/** @category 1. Reading */
|
|
101
|
+
asObject() {
|
|
102
|
+
const object = {};
|
|
103
|
+
for (const key of this.keys()) {
|
|
104
|
+
const value = this.get(key);
|
|
105
|
+
if (value !== undefined) {
|
|
106
|
+
object[key] = value;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return object;
|
|
110
|
+
}
|
|
111
|
+
/** @category 1. Reading */
|
|
112
|
+
toJSON() {
|
|
113
|
+
return this.asObject();
|
|
114
|
+
}
|
|
115
|
+
/** @category 5. Edit history */
|
|
116
|
+
nthEditAt(key, n) {
|
|
117
|
+
const ops = this.timeFilteredOps(key);
|
|
118
|
+
if (!ops || ops.length <= n) {
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
const entry = ops[n];
|
|
122
|
+
if (this.atTimeFilter && entry.madeAt > this.atTimeFilter) {
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
by: accountOrAgentIDfromSessionID(entry.txID.sessionID),
|
|
127
|
+
tx: entry.txID,
|
|
128
|
+
at: new Date(entry.madeAt),
|
|
129
|
+
value: entry.op === "del" ? undefined : entry.value,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/** @category 5. Edit history */
|
|
133
|
+
lastEditAt(key) {
|
|
134
|
+
const ops = this.timeFilteredOps(key);
|
|
135
|
+
if (!ops || ops.length === 0) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
return this.nthEditAt(key, ops.length - 1);
|
|
139
|
+
}
|
|
140
|
+
/** @category 5. Edit history */
|
|
141
|
+
*editsAt(key) {
|
|
142
|
+
const ops = this.timeFilteredOps(key);
|
|
143
|
+
if (!ops) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
for (let i = 0; i < ops.length; i++) {
|
|
147
|
+
yield this.nthEditAt(key, i);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/** @category 3. Subscription */
|
|
151
|
+
subscribe(listener) {
|
|
152
|
+
return this.core.subscribe((content) => {
|
|
153
|
+
listener(content);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/** A collaborative map with precise shape `Shape` and optional static metadata `Meta` */
|
|
158
|
+
export class RawCoMap extends RawCoMapView {
|
|
159
|
+
/** Set a new value for the given key.
|
|
160
|
+
*
|
|
161
|
+
* If `privacy` is `"private"` **(default)**, both `key` and `value` are encrypted in the transaction, only readable by other members of the group this `CoMap` belongs to. Not even sync servers can see the content in plaintext.
|
|
162
|
+
*
|
|
163
|
+
* If `privacy` is `"trusting"`, both `key` and `value` are stored in plaintext in the transaction, visible to everyone who gets a hold of it, including sync servers.
|
|
164
|
+
*
|
|
165
|
+
* @category 2. Editing
|
|
166
|
+
**/
|
|
167
|
+
set(key, value, privacy = "private") {
|
|
168
|
+
this.core.makeTransaction([
|
|
169
|
+
{
|
|
170
|
+
op: "set",
|
|
171
|
+
key,
|
|
172
|
+
value: isCoValue(value) ? value.id : value,
|
|
173
|
+
},
|
|
174
|
+
], privacy);
|
|
175
|
+
const after = new RawCoMap(this.core);
|
|
176
|
+
this.ops = after.ops;
|
|
177
|
+
}
|
|
178
|
+
/** Delete the given key (setting it to undefined).
|
|
179
|
+
*
|
|
180
|
+
* If `privacy` is `"private"` **(default)**, `key` is encrypted in the transaction, only readable by other members of the group this `CoMap` belongs to. Not even sync servers can see the content in plaintext.
|
|
181
|
+
*
|
|
182
|
+
* If `privacy` is `"trusting"`, `key` is stored in plaintext in the transaction, visible to everyone who gets a hold of it, including sync servers.
|
|
183
|
+
*
|
|
184
|
+
* @category 2. Editing
|
|
185
|
+
**/
|
|
186
|
+
delete(key, privacy = "private") {
|
|
187
|
+
this.core.makeTransaction([
|
|
188
|
+
{
|
|
189
|
+
op: "del",
|
|
190
|
+
key,
|
|
191
|
+
},
|
|
192
|
+
], privacy);
|
|
193
|
+
const after = new RawCoMap(this.core);
|
|
194
|
+
this.ops = after.ops;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=coMap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coMap.js","sourceRoot":"","sources":["../../../src/coValues/coMap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { isAccountID } from "../typeUtils/isAccountID.js";
|
|
2
|
+
import { isCoValue } from "../typeUtils/isCoValue.js";
|
|
3
|
+
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
|
4
|
+
import { base64URLtoBytes, bytesToBase64url } from "../base64url.js";
|
|
5
|
+
export class RawCoStreamView {
|
|
6
|
+
constructor(core) {
|
|
7
|
+
this.type = "costream";
|
|
8
|
+
this.id = core.id;
|
|
9
|
+
this.core = core;
|
|
10
|
+
this.items = {};
|
|
11
|
+
this.fillFromCoValue();
|
|
12
|
+
}
|
|
13
|
+
get headerMeta() {
|
|
14
|
+
return this.core.header.meta;
|
|
15
|
+
}
|
|
16
|
+
get group() {
|
|
17
|
+
return this.core.getGroup();
|
|
18
|
+
}
|
|
19
|
+
/** Not yet implemented */
|
|
20
|
+
atTime(_time) {
|
|
21
|
+
throw new Error("Not yet implemented");
|
|
22
|
+
}
|
|
23
|
+
/** @internal */
|
|
24
|
+
fillFromCoValue() {
|
|
25
|
+
this.items = {};
|
|
26
|
+
for (const { txID, madeAt, changes, } of this.core.getValidSortedTransactions()) {
|
|
27
|
+
for (const changeUntyped of changes) {
|
|
28
|
+
const change = changeUntyped;
|
|
29
|
+
let entries = this.items[txID.sessionID];
|
|
30
|
+
if (!entries) {
|
|
31
|
+
entries = [];
|
|
32
|
+
this.items[txID.sessionID] = entries;
|
|
33
|
+
}
|
|
34
|
+
entries.push({ value: change, madeAt, tx: txID });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
getSingleStream() {
|
|
39
|
+
const streams = Object.values(this.items);
|
|
40
|
+
const firstStream = streams[0];
|
|
41
|
+
if (!firstStream) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
if (streams.length > 1) {
|
|
45
|
+
throw new Error("CoStream.getSingleStream() can only be called when there is exactly one stream");
|
|
46
|
+
}
|
|
47
|
+
return firstStream.map((item) => item.value);
|
|
48
|
+
}
|
|
49
|
+
sessions() {
|
|
50
|
+
return Object.keys(this.items);
|
|
51
|
+
}
|
|
52
|
+
accounts() {
|
|
53
|
+
return new Set(this.sessions()
|
|
54
|
+
.map(accountOrAgentIDfromSessionID)
|
|
55
|
+
.filter(isAccountID));
|
|
56
|
+
}
|
|
57
|
+
nthItemIn(sessionID, n) {
|
|
58
|
+
const items = this.items[sessionID];
|
|
59
|
+
if (!items)
|
|
60
|
+
return;
|
|
61
|
+
const item = items[n];
|
|
62
|
+
if (!item)
|
|
63
|
+
return;
|
|
64
|
+
return {
|
|
65
|
+
by: accountOrAgentIDfromSessionID(sessionID),
|
|
66
|
+
tx: item.tx,
|
|
67
|
+
at: new Date(item.madeAt),
|
|
68
|
+
value: item.value,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
lastItemIn(sessionID) {
|
|
72
|
+
const items = this.items[sessionID];
|
|
73
|
+
if (!items)
|
|
74
|
+
return;
|
|
75
|
+
return this.nthItemIn(sessionID, items.length - 1);
|
|
76
|
+
}
|
|
77
|
+
*itemsIn(sessionID) {
|
|
78
|
+
const items = this.items[sessionID];
|
|
79
|
+
if (!items)
|
|
80
|
+
return;
|
|
81
|
+
for (const item of items) {
|
|
82
|
+
yield {
|
|
83
|
+
by: accountOrAgentIDfromSessionID(sessionID),
|
|
84
|
+
tx: item.tx,
|
|
85
|
+
at: new Date(item.madeAt),
|
|
86
|
+
value: item.value,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
lastItemBy(account) {
|
|
91
|
+
let latestItem;
|
|
92
|
+
for (const sessionID of Object.keys(this.items)) {
|
|
93
|
+
if (sessionID.startsWith(account)) {
|
|
94
|
+
const item = this.lastItemIn(sessionID);
|
|
95
|
+
if (!item)
|
|
96
|
+
continue;
|
|
97
|
+
if (!latestItem || item.at > latestItem.at) {
|
|
98
|
+
latestItem = {
|
|
99
|
+
by: item.by,
|
|
100
|
+
tx: item.tx,
|
|
101
|
+
at: item.at,
|
|
102
|
+
value: item.value,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return latestItem;
|
|
108
|
+
}
|
|
109
|
+
*itemsBy(account) {
|
|
110
|
+
// TODO: this can be made more lazy without a huge collect and sort
|
|
111
|
+
const items = [
|
|
112
|
+
...Object.keys(this.items).flatMap((sessionID) => sessionID.startsWith(account)
|
|
113
|
+
? [...this.itemsIn(sessionID)].map((item) => ({
|
|
114
|
+
in: sessionID,
|
|
115
|
+
...item,
|
|
116
|
+
}))
|
|
117
|
+
: []),
|
|
118
|
+
];
|
|
119
|
+
items.sort((a, b) => a.at.getTime() - b.at.getTime());
|
|
120
|
+
for (const item of items) {
|
|
121
|
+
yield item;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
toJSON() {
|
|
125
|
+
return Object.fromEntries(Object.entries(this.items).map(([sessionID, items]) => [
|
|
126
|
+
sessionID,
|
|
127
|
+
items.map((item) => item.value),
|
|
128
|
+
]));
|
|
129
|
+
}
|
|
130
|
+
subscribe(listener) {
|
|
131
|
+
return this.core.subscribe((content) => {
|
|
132
|
+
listener(content);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export class RawCoStream extends RawCoStreamView {
|
|
137
|
+
push(item, privacy = "private") {
|
|
138
|
+
this.core.makeTransaction([isCoValue(item) ? item.id : item], privacy);
|
|
139
|
+
this.fillFromCoValue();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const binary_U_prefixLength = 8; // "binary_U".length;
|
|
143
|
+
export class RawBinaryCoStreamView extends RawCoStreamView {
|
|
144
|
+
isBinaryStreamEnded() {
|
|
145
|
+
const items = this.getSingleStream();
|
|
146
|
+
if (!items || items.length === 0) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
const lastItem = items[items.length - 1];
|
|
150
|
+
return lastItem?.type === "end";
|
|
151
|
+
}
|
|
152
|
+
getBinaryChunks(allowUnfinished) {
|
|
153
|
+
const items = this.getSingleStream();
|
|
154
|
+
// No active streams
|
|
155
|
+
if (!items)
|
|
156
|
+
return;
|
|
157
|
+
const start = items[0];
|
|
158
|
+
if (start?.type !== "start") {
|
|
159
|
+
console.error("Invalid binary stream start", start);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const end = items[items.length - 1];
|
|
163
|
+
if (end?.type !== "end" && !allowUnfinished)
|
|
164
|
+
return;
|
|
165
|
+
const chunks = [];
|
|
166
|
+
let finished = false;
|
|
167
|
+
for (const item of items.slice(1)) {
|
|
168
|
+
if (item.type === "end") {
|
|
169
|
+
finished = true;
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
if (item.type !== "chunk") {
|
|
173
|
+
console.error("Invalid binary stream chunk", item);
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
const chunk = base64URLtoBytes(item.chunk.slice(binary_U_prefixLength));
|
|
177
|
+
chunks.push(chunk);
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
mimeType: start.mimeType,
|
|
181
|
+
fileName: start.fileName,
|
|
182
|
+
totalSizeBytes: start.totalSizeBytes,
|
|
183
|
+
chunks,
|
|
184
|
+
finished,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
export class RawBinaryCoStream extends RawBinaryCoStreamView {
|
|
189
|
+
/** @internal */
|
|
190
|
+
push(item, privacy = "private", updateView = true) {
|
|
191
|
+
this.core.makeTransaction([item], privacy);
|
|
192
|
+
if (updateView) {
|
|
193
|
+
this.fillFromCoValue();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
startBinaryStream(settings, privacy = "private") {
|
|
197
|
+
this.push({
|
|
198
|
+
type: "start",
|
|
199
|
+
...settings,
|
|
200
|
+
}, privacy, false);
|
|
201
|
+
}
|
|
202
|
+
pushBinaryStreamChunk(chunk, privacy = "private") {
|
|
203
|
+
// const before = performance.now();
|
|
204
|
+
this.push({
|
|
205
|
+
type: "chunk",
|
|
206
|
+
chunk: `binary_U${bytesToBase64url(chunk)}`,
|
|
207
|
+
}, privacy, false);
|
|
208
|
+
// const after = performance.now();
|
|
209
|
+
// console.log(
|
|
210
|
+
// "pushBinaryStreamChunk bandwidth in MB/s",
|
|
211
|
+
// (1000 * chunk.length) / (after - before) / (1024 * 1024)
|
|
212
|
+
// );
|
|
213
|
+
}
|
|
214
|
+
endBinaryStream(privacy = "private") {
|
|
215
|
+
this.push({
|
|
216
|
+
type: "end",
|
|
217
|
+
}, privacy, true);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=coStream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coStream.js","sourceRoot":"","sources":["../../../src/coValues/coStream.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { RawCoMap } from "./coMap.js";
|
|
2
|
+
import { isAgentID } from "../ids.js";
|
|
3
|
+
import { base58 } from "@scure/base";
|
|
4
|
+
export const EVERYONE = "everyone";
|
|
5
|
+
/** A `Group` is a scope for permissions of its members (`"reader" | "writer" | "admin"`), applying to objects owned by that group.
|
|
6
|
+
*
|
|
7
|
+
* A `Group` object exposes methods for permission management and allows you to create new CoValues owned by that group.
|
|
8
|
+
*
|
|
9
|
+
* (Internally, a `Group` is also just a `CoMap`, mapping member accounts to roles and containing some
|
|
10
|
+
* state management for making cryptographic keys available to current members)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* You typically get a group from a CoValue that you already have loaded:
|
|
14
|
+
*
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const group = coMap.group;
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* Or, you can create a new group with a `LocalNode`:
|
|
21
|
+
*
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const localNode.createGroup();
|
|
24
|
+
* ```
|
|
25
|
+
* */
|
|
26
|
+
export class RawGroup extends RawCoMap {
|
|
27
|
+
/**
|
|
28
|
+
* Returns the current role of a given account.
|
|
29
|
+
*
|
|
30
|
+
* @category 1. Role reading
|
|
31
|
+
*/
|
|
32
|
+
roleOf(accountID) {
|
|
33
|
+
return this.roleOfInternal(accountID);
|
|
34
|
+
}
|
|
35
|
+
/** @internal */
|
|
36
|
+
roleOfInternal(accountID) {
|
|
37
|
+
return this.get(accountID);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Returns the role of the current account in the group.
|
|
41
|
+
*
|
|
42
|
+
* @category 1. Role reading
|
|
43
|
+
*/
|
|
44
|
+
myRole() {
|
|
45
|
+
return this.roleOfInternal(this.core.node.account.id);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Directly grants a new member a role in the group. The current account must be an
|
|
49
|
+
* admin to be able to do so. Throws otherwise.
|
|
50
|
+
*
|
|
51
|
+
* @category 2. Role changing
|
|
52
|
+
*/
|
|
53
|
+
addMember(account, role) {
|
|
54
|
+
this.addMemberInternal(account, role);
|
|
55
|
+
}
|
|
56
|
+
/** @internal */
|
|
57
|
+
addMemberInternal(account, role) {
|
|
58
|
+
const currentReadKey = this.core.getCurrentReadKey();
|
|
59
|
+
if (!currentReadKey.secret) {
|
|
60
|
+
throw new Error("Can't add member without read key secret");
|
|
61
|
+
}
|
|
62
|
+
if (account === EVERYONE) {
|
|
63
|
+
if (!(role === "reader" || role === "writer")) {
|
|
64
|
+
throw new Error("Can't make everyone something other than reader or writer");
|
|
65
|
+
}
|
|
66
|
+
this.set(account, role, "trusting");
|
|
67
|
+
if (this.get(account) !== role) {
|
|
68
|
+
throw new Error("Failed to set role");
|
|
69
|
+
}
|
|
70
|
+
this.set(`${currentReadKey.id}_for_${EVERYONE}`, currentReadKey.secret, "trusting");
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
const memberKey = typeof account === "string" ? account : account.id;
|
|
74
|
+
const agent = typeof account === "string"
|
|
75
|
+
? account
|
|
76
|
+
: account
|
|
77
|
+
.currentAgentID()
|
|
78
|
+
._unsafeUnwrap({ withStackTrace: true });
|
|
79
|
+
this.set(memberKey, role, "trusting");
|
|
80
|
+
if (this.get(memberKey) !== role) {
|
|
81
|
+
throw new Error("Failed to set role");
|
|
82
|
+
}
|
|
83
|
+
this.set(`${currentReadKey.id}_for_${memberKey}`, this.core.crypto.seal({
|
|
84
|
+
message: currentReadKey.secret,
|
|
85
|
+
from: this.core.node.account.currentSealerSecret(),
|
|
86
|
+
to: this.core.crypto.getAgentSealerID(agent),
|
|
87
|
+
nOnceMaterial: {
|
|
88
|
+
in: this.id,
|
|
89
|
+
tx: this.core.nextTransactionID(),
|
|
90
|
+
},
|
|
91
|
+
}), "trusting");
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/** @internal */
|
|
95
|
+
rotateReadKey() {
|
|
96
|
+
const currentlyPermittedReaders = this.keys().filter((key) => {
|
|
97
|
+
if (key.startsWith("co_") || isAgentID(key)) {
|
|
98
|
+
const role = this.get(key);
|
|
99
|
+
return (role === "admin" || role === "writer" || role === "reader");
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
const maybeCurrentReadKey = this.core.getCurrentReadKey();
|
|
106
|
+
if (!maybeCurrentReadKey.secret) {
|
|
107
|
+
throw new Error("Can't rotate read key secret we don't have access to");
|
|
108
|
+
}
|
|
109
|
+
const currentReadKey = {
|
|
110
|
+
id: maybeCurrentReadKey.id,
|
|
111
|
+
secret: maybeCurrentReadKey.secret,
|
|
112
|
+
};
|
|
113
|
+
const newReadKey = this.core.crypto.newRandomKeySecret();
|
|
114
|
+
for (const readerID of currentlyPermittedReaders) {
|
|
115
|
+
const reader = this.core.node.resolveAccountAgent(readerID, "Expected to know currently permitted reader")._unsafeUnwrap({ withStackTrace: true });
|
|
116
|
+
this.set(`${newReadKey.id}_for_${readerID}`, this.core.crypto.seal({
|
|
117
|
+
message: newReadKey.secret,
|
|
118
|
+
from: this.core.node.account.currentSealerSecret(),
|
|
119
|
+
to: this.core.crypto.getAgentSealerID(reader),
|
|
120
|
+
nOnceMaterial: {
|
|
121
|
+
in: this.id,
|
|
122
|
+
tx: this.core.nextTransactionID(),
|
|
123
|
+
},
|
|
124
|
+
}), "trusting");
|
|
125
|
+
}
|
|
126
|
+
this.set(`${currentReadKey.id}_for_${newReadKey.id}`, this.core.crypto.encryptKeySecret({
|
|
127
|
+
encrypting: newReadKey,
|
|
128
|
+
toEncrypt: currentReadKey,
|
|
129
|
+
}).encrypted, "trusting");
|
|
130
|
+
this.set("readKey", newReadKey.id, "trusting");
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Strips the specified member of all roles (preventing future writes in
|
|
134
|
+
* the group and owned values) and rotates the read encryption key for that group
|
|
135
|
+
* (preventing reads of new content in the group and owned values)
|
|
136
|
+
*
|
|
137
|
+
* @category 2. Role changing
|
|
138
|
+
*/
|
|
139
|
+
removeMember(account) {
|
|
140
|
+
this.removeMemberInternal(account);
|
|
141
|
+
}
|
|
142
|
+
/** @internal */
|
|
143
|
+
removeMemberInternal(account) {
|
|
144
|
+
const memberKey = typeof account === "string" ? account : account.id;
|
|
145
|
+
this.set(memberKey, "revoked", "trusting");
|
|
146
|
+
this.rotateReadKey();
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Creates an invite for new members to indirectly join the group,
|
|
150
|
+
* allowing them to grant themselves the specified role with the InviteSecret
|
|
151
|
+
* (a string starting with "inviteSecret_") - use `LocalNode.acceptInvite()` for this purpose.
|
|
152
|
+
*
|
|
153
|
+
* @category 2. Role changing
|
|
154
|
+
*/
|
|
155
|
+
createInvite(role) {
|
|
156
|
+
const secretSeed = this.core.crypto.newRandomSecretSeed();
|
|
157
|
+
const inviteSecret = this.core.crypto.agentSecretFromSecretSeed(secretSeed);
|
|
158
|
+
const inviteID = this.core.crypto.getAgentID(inviteSecret);
|
|
159
|
+
this.addMemberInternal(inviteID, `${role}Invite`);
|
|
160
|
+
return inviteSecretFromSecretSeed(secretSeed);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Creates a new `CoMap` within this group, with the specified specialized
|
|
164
|
+
* `CoMap` type `M` and optional static metadata.
|
|
165
|
+
*
|
|
166
|
+
* @category 3. Value creation
|
|
167
|
+
*/
|
|
168
|
+
createMap(init, meta, initPrivacy = "private", uniqueness = this.core.crypto.createdNowUnique()) {
|
|
169
|
+
const map = this.core.node
|
|
170
|
+
.createCoValue({
|
|
171
|
+
type: "comap",
|
|
172
|
+
ruleset: {
|
|
173
|
+
type: "ownedByGroup",
|
|
174
|
+
group: this.id,
|
|
175
|
+
},
|
|
176
|
+
meta: meta || null,
|
|
177
|
+
...uniqueness
|
|
178
|
+
})
|
|
179
|
+
.getCurrentContent();
|
|
180
|
+
if (init) {
|
|
181
|
+
for (const [key, value] of Object.entries(init)) {
|
|
182
|
+
map.set(key, value, initPrivacy);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return map;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Creates a new `CoList` within this group, with the specified specialized
|
|
189
|
+
* `CoList` type `L` and optional static metadata.
|
|
190
|
+
*
|
|
191
|
+
* @category 3. Value creation
|
|
192
|
+
*/
|
|
193
|
+
createList(init, meta, initPrivacy = "private", uniqueness = this.core.crypto.createdNowUnique()) {
|
|
194
|
+
const list = this.core.node
|
|
195
|
+
.createCoValue({
|
|
196
|
+
type: "colist",
|
|
197
|
+
ruleset: {
|
|
198
|
+
type: "ownedByGroup",
|
|
199
|
+
group: this.id,
|
|
200
|
+
},
|
|
201
|
+
meta: meta || null,
|
|
202
|
+
...uniqueness
|
|
203
|
+
})
|
|
204
|
+
.getCurrentContent();
|
|
205
|
+
if (init) {
|
|
206
|
+
for (const item of init) {
|
|
207
|
+
list.append(item, undefined, initPrivacy);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return list;
|
|
211
|
+
}
|
|
212
|
+
/** @category 3. Value creation */
|
|
213
|
+
createStream(meta, uniqueness = this.core.crypto.createdNowUnique()) {
|
|
214
|
+
return this.core.node
|
|
215
|
+
.createCoValue({
|
|
216
|
+
type: "costream",
|
|
217
|
+
ruleset: {
|
|
218
|
+
type: "ownedByGroup",
|
|
219
|
+
group: this.id,
|
|
220
|
+
},
|
|
221
|
+
meta: meta || null,
|
|
222
|
+
...uniqueness
|
|
223
|
+
})
|
|
224
|
+
.getCurrentContent();
|
|
225
|
+
}
|
|
226
|
+
/** @category 3. Value creation */
|
|
227
|
+
createBinaryStream(meta = { type: "binary" }, uniqueness = this.core.crypto.createdNowUnique()) {
|
|
228
|
+
return this.core.node
|
|
229
|
+
.createCoValue({
|
|
230
|
+
type: "costream",
|
|
231
|
+
ruleset: {
|
|
232
|
+
type: "ownedByGroup",
|
|
233
|
+
group: this.id,
|
|
234
|
+
},
|
|
235
|
+
meta: meta,
|
|
236
|
+
...uniqueness
|
|
237
|
+
})
|
|
238
|
+
.getCurrentContent();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function inviteSecretFromSecretSeed(secretSeed) {
|
|
242
|
+
return `inviteSecret_z${base58.encode(secretSeed)}`;
|
|
243
|
+
}
|
|
244
|
+
export function secretSeedFromInviteSecret(inviteSecret) {
|
|
245
|
+
if (!inviteSecret.startsWith("inviteSecret_z")) {
|
|
246
|
+
throw new Error("Invalid invite secret");
|
|
247
|
+
}
|
|
248
|
+
return base58.decode(inviteSecret.slice("inviteSecret_z".length));
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=group.js.map
|