cojson 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +1 -0
- package/dist/account.d.ts +7 -7
- package/dist/account.js +2 -2
- package/dist/account.js.map +1 -1
- package/dist/coValue.d.ts +26 -23
- package/dist/coValue.js +14 -0
- package/dist/coValue.js.map +1 -1
- package/dist/coValueCore.d.ts +6 -6
- package/dist/coValueCore.js.map +1 -1
- package/dist/coValues/coList.d.ts +22 -22
- package/dist/coValues/coList.js +3 -2
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.d.ts +29 -35
- package/dist/coValues/coMap.js +17 -8
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coStream.d.ts +28 -27
- package/dist/coValues/coStream.js +15 -6
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/coValues/static.d.ts +4 -4
- package/dist/coValues/static.js.map +1 -1
- package/dist/group.d.ts +8 -6
- package/dist/group.js +20 -4
- package/dist/group.js.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.js.map +1 -1
- package/dist/media.d.ts +1 -2
- package/dist/node.d.ts +7 -3
- package/dist/node.js +37 -7
- package/dist/node.js.map +1 -1
- package/dist/queries.d.ts +114 -0
- package/dist/queries.js +260 -0
- package/dist/queries.js.map +1 -0
- package/dist/{testUtils.d.ts → tests/testUtils.d.ts} +9 -9
- package/dist/{testUtils.js → tests/testUtils.js} +7 -5
- package/dist/tests/testUtils.js.map +1 -0
- package/package.json +2 -2
- package/src/account.ts +5 -5
- package/src/coValue.ts +54 -28
- package/src/coValueCore.ts +6 -6
- package/src/coValues/coList.ts +73 -37
- package/src/coValues/coMap.ts +134 -68
- package/src/coValues/coStream.ts +86 -55
- package/src/coValues/static.ts +5 -5
- package/src/group.ts +50 -11
- package/src/index.ts +10 -8
- package/src/media.ts +1 -2
- package/src/node.ts +70 -19
- package/src/queries.ts +519 -0
- package/src/{account.test.ts → tests/account.test.ts} +4 -4
- package/src/{coValue.test.ts → tests/coValue.test.ts} +5 -5
- package/src/{coValueCore.test.ts → tests/coValueCore.test.ts} +7 -7
- package/src/{crypto.test.ts → tests/crypto.test.ts} +3 -3
- package/src/{group.test.ts → tests/group.test.ts} +2 -2
- package/src/{permissions.test.ts → tests/permissions.test.ts} +5 -5
- package/src/tests/queries.test.ts +301 -0
- package/src/{sync.test.ts → tests/sync.test.ts} +10 -10
- package/src/{testUtils.ts → tests/testUtils.ts} +8 -6
- package/dist/testUtils.js.map +0 -1
package/src/queries.ts
ADDED
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
import { JsonValue } from "./jsonValue.js";
|
|
2
|
+
import { CoMap, WriteableCoMap } from "./coValues/coMap.js";
|
|
3
|
+
import {
|
|
4
|
+
BinaryCoStream,
|
|
5
|
+
BinaryStreamInfo,
|
|
6
|
+
CoStream,
|
|
7
|
+
WriteableBinaryCoStream,
|
|
8
|
+
WriteableCoStream,
|
|
9
|
+
} from "./coValues/coStream.js";
|
|
10
|
+
import { Static } from "./coValues/static.js";
|
|
11
|
+
import { CoList, WriteableCoList } from "./coValues/coList.js";
|
|
12
|
+
import { CoValueCore, accountOrAgentIDfromSessionID } from "./coValueCore.js";
|
|
13
|
+
import { Group } from "./group.js";
|
|
14
|
+
import { AccountID, Profile, isAccountID } from "./account.js";
|
|
15
|
+
import {
|
|
16
|
+
AnyBinaryCoStream,
|
|
17
|
+
AnyCoList,
|
|
18
|
+
AnyCoMap,
|
|
19
|
+
AnyCoStream,
|
|
20
|
+
AnyCoValue,
|
|
21
|
+
AnyStatic,
|
|
22
|
+
CoID,
|
|
23
|
+
CoValue,
|
|
24
|
+
} from "./coValue.js";
|
|
25
|
+
import { SessionID } from "./ids.js";
|
|
26
|
+
import { LocalNode } from "./node.js";
|
|
27
|
+
|
|
28
|
+
export const AllReservedQueryProps = [
|
|
29
|
+
"id",
|
|
30
|
+
"type",
|
|
31
|
+
"meta",
|
|
32
|
+
"core",
|
|
33
|
+
"group",
|
|
34
|
+
"shadowed",
|
|
35
|
+
"edit",
|
|
36
|
+
"edits",
|
|
37
|
+
] as const;
|
|
38
|
+
|
|
39
|
+
export type ReservedQueryProps = (typeof AllReservedQueryProps)[number];
|
|
40
|
+
|
|
41
|
+
export type QueriedCoMap<T extends AnyCoMap> = T extends CoMap<
|
|
42
|
+
infer M,
|
|
43
|
+
infer Meta
|
|
44
|
+
>
|
|
45
|
+
? Readonly<{
|
|
46
|
+
[K in keyof M as Exclude<K, ReservedQueryProps>]: ValueOrSubQueried<
|
|
47
|
+
M[K]
|
|
48
|
+
>;
|
|
49
|
+
}> &
|
|
50
|
+
(keyof M & ReservedQueryProps extends never
|
|
51
|
+
? // eslint-disable-next-line @typescript-eslint/ban-types
|
|
52
|
+
{}
|
|
53
|
+
: Readonly<{
|
|
54
|
+
shadowed: Readonly<{
|
|
55
|
+
[K in keyof M as Extract<
|
|
56
|
+
K,
|
|
57
|
+
ReservedQueryProps
|
|
58
|
+
>]: ValueOrSubQueried<M[K]>;
|
|
59
|
+
}>;
|
|
60
|
+
}>) &
|
|
61
|
+
Readonly<{
|
|
62
|
+
id: CoID<T>;
|
|
63
|
+
type: "comap";
|
|
64
|
+
edits: Readonly<{
|
|
65
|
+
[K in keyof M & string]: Readonly<{
|
|
66
|
+
by?: QueriedAccountAndProfile;
|
|
67
|
+
at: Date;
|
|
68
|
+
// all: TODO;
|
|
69
|
+
}>;
|
|
70
|
+
}>;
|
|
71
|
+
meta: Meta;
|
|
72
|
+
group: Group;
|
|
73
|
+
core: CoValueCore;
|
|
74
|
+
edit: (changer: (editable: WriteableCoMap<M, Meta>) => void) => T;
|
|
75
|
+
}>
|
|
76
|
+
: never;
|
|
77
|
+
|
|
78
|
+
export type QueriedAccountAndProfile = Readonly<{
|
|
79
|
+
id: AccountID;
|
|
80
|
+
profile?: Readonly<{ name?: string; id: CoID<Profile> }>;
|
|
81
|
+
isMe?: boolean;
|
|
82
|
+
}>;
|
|
83
|
+
|
|
84
|
+
export type QueriedCoList<T extends AnyCoList> = T extends CoList<
|
|
85
|
+
infer I,
|
|
86
|
+
infer Meta
|
|
87
|
+
>
|
|
88
|
+
? readonly ValueOrSubQueried<I>[] &
|
|
89
|
+
Readonly<{
|
|
90
|
+
id: CoID<T>;
|
|
91
|
+
type: "colist";
|
|
92
|
+
meta: Meta;
|
|
93
|
+
group: Group;
|
|
94
|
+
core: CoValueCore;
|
|
95
|
+
edit: (
|
|
96
|
+
changer: (editable: WriteableCoList<I, Meta>) => void
|
|
97
|
+
) => T;
|
|
98
|
+
edits: readonly Readonly<{
|
|
99
|
+
by?: QueriedAccountAndProfile;
|
|
100
|
+
at: Date;
|
|
101
|
+
}>[] & {
|
|
102
|
+
// deletions: TODO;
|
|
103
|
+
};
|
|
104
|
+
}>
|
|
105
|
+
: never;
|
|
106
|
+
|
|
107
|
+
export type QueriedCoStreamItems<I extends JsonValue | CoValue> = Readonly<{
|
|
108
|
+
last: ValueOrSubQueried<I> | undefined;
|
|
109
|
+
by?: QueriedAccountAndProfile;
|
|
110
|
+
at?: Date;
|
|
111
|
+
all: { value: ValueOrSubQueried<I>; at: Date }[];
|
|
112
|
+
}>;
|
|
113
|
+
|
|
114
|
+
export type QueriedCoStream<T extends AnyCoStream> = T extends CoStream<
|
|
115
|
+
infer I,
|
|
116
|
+
infer Meta
|
|
117
|
+
>
|
|
118
|
+
? Readonly<{
|
|
119
|
+
id: CoID<T>;
|
|
120
|
+
type: "costream";
|
|
121
|
+
me?: QueriedCoStreamItems<I>;
|
|
122
|
+
perAccount: Readonly<{
|
|
123
|
+
[account: AccountID]: QueriedCoStreamItems<I>;
|
|
124
|
+
}>;
|
|
125
|
+
perSession: Readonly<{
|
|
126
|
+
[session: SessionID]: QueriedCoStreamItems<I>;
|
|
127
|
+
}>;
|
|
128
|
+
meta: Meta;
|
|
129
|
+
group: Group;
|
|
130
|
+
core: CoValueCore;
|
|
131
|
+
edit: (changer: (editable: WriteableCoStream<I, Meta>) => void) => T;
|
|
132
|
+
}>
|
|
133
|
+
: never;
|
|
134
|
+
|
|
135
|
+
export type QueriedBinaryCoStreamItems = Readonly<{
|
|
136
|
+
last: Uint8Array | undefined;
|
|
137
|
+
by: QueriedAccountAndProfile;
|
|
138
|
+
at: Date;
|
|
139
|
+
all: { value: Uint8Array; at: Date }[];
|
|
140
|
+
}>;
|
|
141
|
+
|
|
142
|
+
export type QueriedBinaryCoStream<T extends AnyBinaryCoStream> =
|
|
143
|
+
T extends BinaryCoStream<infer Meta>
|
|
144
|
+
? Readonly<
|
|
145
|
+
{
|
|
146
|
+
id: CoID<T>;
|
|
147
|
+
type: "costream";
|
|
148
|
+
me?: QueriedBinaryCoStreamItems;
|
|
149
|
+
perAccount: Readonly<{
|
|
150
|
+
[account: AccountID]: QueriedBinaryCoStreamItems;
|
|
151
|
+
}>;
|
|
152
|
+
perSession: Readonly<{
|
|
153
|
+
[session: SessionID]: QueriedBinaryCoStreamItems;
|
|
154
|
+
}>;
|
|
155
|
+
meta: Meta;
|
|
156
|
+
group: Group;
|
|
157
|
+
core: CoValueCore;
|
|
158
|
+
edit: (
|
|
159
|
+
changer: (editable: WriteableBinaryCoStream<Meta>) => void
|
|
160
|
+
) => T;
|
|
161
|
+
}
|
|
162
|
+
> & Readonly<BinaryStreamInfo>
|
|
163
|
+
: never;
|
|
164
|
+
|
|
165
|
+
export type QueriedStatic<T extends AnyStatic> = T extends Static<infer Meta>
|
|
166
|
+
? Readonly<{
|
|
167
|
+
id: CoID<T>;
|
|
168
|
+
type: "colist";
|
|
169
|
+
meta: Meta;
|
|
170
|
+
group: Group;
|
|
171
|
+
core: CoValueCore;
|
|
172
|
+
}>
|
|
173
|
+
: never;
|
|
174
|
+
|
|
175
|
+
export type Queried<T extends CoValue> = T extends AnyCoMap
|
|
176
|
+
? QueriedCoMap<T>
|
|
177
|
+
: T extends AnyCoList
|
|
178
|
+
? QueriedCoList<T>
|
|
179
|
+
// : T extends BinaryCoStream<infer _>
|
|
180
|
+
// ? QueriedBinaryCoStream<T>
|
|
181
|
+
: T extends AnyCoStream
|
|
182
|
+
? QueriedCoStream<T>
|
|
183
|
+
: T extends AnyStatic
|
|
184
|
+
? QueriedStatic<T>
|
|
185
|
+
: never;
|
|
186
|
+
|
|
187
|
+
export type ValueOrSubQueried<
|
|
188
|
+
V extends JsonValue | CoValue | CoID<CoValue> | undefined
|
|
189
|
+
> = V extends CoID<infer C>
|
|
190
|
+
? Queried<C> | undefined
|
|
191
|
+
: V extends CoValue
|
|
192
|
+
? Queried<V> | undefined
|
|
193
|
+
: V;
|
|
194
|
+
|
|
195
|
+
export type QueryInclude<T extends CoValue> = T extends CoMap<
|
|
196
|
+
infer M,
|
|
197
|
+
infer _Meta
|
|
198
|
+
>
|
|
199
|
+
? {
|
|
200
|
+
[K in keyof M as M[K] extends AnyCoValue | CoID<AnyCoValue>
|
|
201
|
+
? K
|
|
202
|
+
: never]?: M[K] extends AnyCoValue
|
|
203
|
+
? true | QueryInclude<M[K]>
|
|
204
|
+
: M[K] extends CoID<infer S>
|
|
205
|
+
? true | QueryInclude<S>
|
|
206
|
+
: never;
|
|
207
|
+
}
|
|
208
|
+
: T extends CoList<infer I, infer _>
|
|
209
|
+
? I extends AnyCoValue
|
|
210
|
+
? [true] | [QueryInclude<I>]
|
|
211
|
+
: I extends CoID<infer S>
|
|
212
|
+
? [true] | [QueryInclude<S>]
|
|
213
|
+
: never
|
|
214
|
+
: never; // TODO add CoStream;
|
|
215
|
+
|
|
216
|
+
export function query<T extends CoValue>(
|
|
217
|
+
id: CoID<T>,
|
|
218
|
+
node: LocalNode,
|
|
219
|
+
callback: (queried: Queried<T> | undefined) => void
|
|
220
|
+
): () => void {
|
|
221
|
+
console.log("querying", id);
|
|
222
|
+
|
|
223
|
+
const children: {
|
|
224
|
+
[id: CoID<CoValue>]: {
|
|
225
|
+
lastQueried: { [key: string]: any } | undefined;
|
|
226
|
+
unsubscribe: () => void;
|
|
227
|
+
};
|
|
228
|
+
} = {};
|
|
229
|
+
|
|
230
|
+
const unsubscribe = node.subscribe(id, (update) => {
|
|
231
|
+
lastRootValue = update;
|
|
232
|
+
onUpdate();
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
function getChildLastQueriedOrSubscribe<T extends CoValue>(
|
|
236
|
+
childID: CoID<T>
|
|
237
|
+
) {
|
|
238
|
+
let child = children[childID];
|
|
239
|
+
if (!child) {
|
|
240
|
+
child = {
|
|
241
|
+
lastQueried: undefined,
|
|
242
|
+
unsubscribe: query(childID, node, (childQueried) => {
|
|
243
|
+
child!.lastQueried = childQueried;
|
|
244
|
+
onUpdate();
|
|
245
|
+
}),
|
|
246
|
+
};
|
|
247
|
+
children[childID] = child;
|
|
248
|
+
}
|
|
249
|
+
return child.lastQueried as Queried<T> | undefined;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function resolveValue<T extends JsonValue>(
|
|
253
|
+
value: T
|
|
254
|
+
): T extends CoID<CoValue> ? Queried<CoValue> | undefined : T {
|
|
255
|
+
return (
|
|
256
|
+
typeof value === "string" && value.startsWith("co_")
|
|
257
|
+
? getChildLastQueriedOrSubscribe(value as CoID<CoValue>)
|
|
258
|
+
: value
|
|
259
|
+
) as T extends CoID<CoValue> ? Queried<CoValue> | undefined : T;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
let lastRootValue: T | undefined;
|
|
263
|
+
|
|
264
|
+
function onUpdate() {
|
|
265
|
+
const rootValue = lastRootValue;
|
|
266
|
+
|
|
267
|
+
if (rootValue === undefined) {
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (rootValue instanceof CoMap) {
|
|
272
|
+
callback(queryMap(rootValue) as Queried<T>);
|
|
273
|
+
} else if (rootValue instanceof CoList) {
|
|
274
|
+
callback(queryList(rootValue) as unknown as Queried<T>);
|
|
275
|
+
} else if (rootValue instanceof CoStream) {
|
|
276
|
+
if (rootValue.meta?.type === "binary") {
|
|
277
|
+
// Querying binary string not yet implemented
|
|
278
|
+
return {}
|
|
279
|
+
} else {
|
|
280
|
+
callback(queryStream(rootValue) as unknown as Queried<T>);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return function cleanup() {
|
|
286
|
+
for (const child of Object.values(children)) {
|
|
287
|
+
child.unsubscribe();
|
|
288
|
+
}
|
|
289
|
+
unsubscribe();
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
function queryMap(rootValue: T & CoMap<any, any>) {
|
|
293
|
+
const mapResult: {
|
|
294
|
+
[key: string]: any;
|
|
295
|
+
} = {};
|
|
296
|
+
// let allChildrenAvailable = true;
|
|
297
|
+
for (const key of rootValue.keys()) {
|
|
298
|
+
const value = rootValue.get(key);
|
|
299
|
+
|
|
300
|
+
if (value === undefined) continue;
|
|
301
|
+
|
|
302
|
+
if (AllReservedQueryProps.includes(key as ReservedQueryProps)) {
|
|
303
|
+
mapResult.shadowed = mapResult.shadowed || {};
|
|
304
|
+
mapResult.shadowed[key] = resolveValue(value);
|
|
305
|
+
} else {
|
|
306
|
+
mapResult[key] = resolveValue(value);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
Object.defineProperties(mapResult, {
|
|
311
|
+
id: { value: rootValue.id },
|
|
312
|
+
type: { value: "comap" },
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
if (
|
|
316
|
+
rootValue.meta?.type !== "account" &&
|
|
317
|
+
rootValue.meta?.type !== "profile"
|
|
318
|
+
) {
|
|
319
|
+
Object.defineProperties(mapResult, {
|
|
320
|
+
edit: {
|
|
321
|
+
value: (
|
|
322
|
+
changer: (editable: WriteableCoMap<any, any>) => void
|
|
323
|
+
) => {
|
|
324
|
+
rootValue.edit(changer);
|
|
325
|
+
return rootValue;
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
edits: {
|
|
329
|
+
value: {},
|
|
330
|
+
},
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
for (const key of rootValue.keys()) {
|
|
334
|
+
const editorID = rootValue.whoEdited(key);
|
|
335
|
+
const editor =
|
|
336
|
+
editorID && getChildLastQueriedOrSubscribe(editorID);
|
|
337
|
+
mapResult.edits[key] = {
|
|
338
|
+
by: editor && {
|
|
339
|
+
id: editorID,
|
|
340
|
+
isMe: editorID === node.account.id ? true : undefined,
|
|
341
|
+
profile: editor.profile && {
|
|
342
|
+
id: editor.profile.id,
|
|
343
|
+
name: editor.profile.name,
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
at: new Date(rootValue.getLastEntry(key)!.at),
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
Object.defineProperties(mapResult, {
|
|
352
|
+
meta: { value: rootValue.meta },
|
|
353
|
+
group: {
|
|
354
|
+
get() {
|
|
355
|
+
return rootValue.group;
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
core: {
|
|
359
|
+
get() {
|
|
360
|
+
return rootValue.core;
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
return mapResult;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function queryList(rootValue: T & CoList<any, any>) {
|
|
368
|
+
const arr: any[] & { [key: string]: any } = rootValue
|
|
369
|
+
.asArray()
|
|
370
|
+
.map(resolveValue);
|
|
371
|
+
|
|
372
|
+
Object.defineProperties(arr, {
|
|
373
|
+
type: { value: "colist" },
|
|
374
|
+
id: { value: rootValue.id },
|
|
375
|
+
edit: {
|
|
376
|
+
value: (
|
|
377
|
+
changer: (editable: WriteableCoList<any, any>) => void
|
|
378
|
+
) => {
|
|
379
|
+
rootValue.edit(changer);
|
|
380
|
+
return rootValue;
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
edits: {
|
|
384
|
+
value: [],
|
|
385
|
+
},
|
|
386
|
+
meta: { value: rootValue.meta },
|
|
387
|
+
group: {
|
|
388
|
+
get() {
|
|
389
|
+
return rootValue.group;
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
core: {
|
|
393
|
+
get() {
|
|
394
|
+
return rootValue.core;
|
|
395
|
+
},
|
|
396
|
+
},
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
for (let i = 0; i < arr.length; i++) {
|
|
400
|
+
const editorID = rootValue.whoInserted(i);
|
|
401
|
+
const editor = editorID && getChildLastQueriedOrSubscribe(editorID);
|
|
402
|
+
arr.edits[i] = {
|
|
403
|
+
by: editor && {
|
|
404
|
+
id: editorID,
|
|
405
|
+
isMe: editorID === node.account.id ? true : undefined,
|
|
406
|
+
profile: editor.profile && {
|
|
407
|
+
id: editor.profile.id,
|
|
408
|
+
name: editor.profile.name,
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
at: new Date(rootValue.entries()[i]!.madeAt),
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
return arr;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function queryStream(rootValue: T & CoStream<any, any>) {
|
|
418
|
+
const seenAccounts = new Set<AccountID>();
|
|
419
|
+
|
|
420
|
+
const perSession = Object.fromEntries(
|
|
421
|
+
Object.entries(rootValue.items).map(([sessionID, items]) => {
|
|
422
|
+
const editorID = accountOrAgentIDfromSessionID(
|
|
423
|
+
sessionID as SessionID
|
|
424
|
+
);
|
|
425
|
+
if (isAccountID(editorID)) seenAccounts.add(editorID);
|
|
426
|
+
const editor =
|
|
427
|
+
editorID &&
|
|
428
|
+
(isAccountID(editorID)
|
|
429
|
+
? getChildLastQueriedOrSubscribe(editorID)
|
|
430
|
+
: undefined);
|
|
431
|
+
const lastItem = items[items.length - 1];
|
|
432
|
+
return [
|
|
433
|
+
sessionID as SessionID,
|
|
434
|
+
{
|
|
435
|
+
last: lastItem && resolveValue(lastItem.item),
|
|
436
|
+
by: editor && {
|
|
437
|
+
id: editorID as AccountID,
|
|
438
|
+
isMe:
|
|
439
|
+
editorID === node.account.id ? true : undefined,
|
|
440
|
+
profile: editor.profile && {
|
|
441
|
+
id: editor.profile.id,
|
|
442
|
+
name: editor.profile.name,
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
at: lastItem && new Date(lastItem.madeAt),
|
|
446
|
+
all: items.map((item) => ({
|
|
447
|
+
value: item.item && resolveValue(item.item),
|
|
448
|
+
at: new Date(item.madeAt),
|
|
449
|
+
})),
|
|
450
|
+
} satisfies QueriedCoStreamItems<JsonValue>,
|
|
451
|
+
];
|
|
452
|
+
})
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
const perAccount = Object.fromEntries(
|
|
456
|
+
[...seenAccounts.values()].map((accountID) => {
|
|
457
|
+
const itemsFromAllMatchingSessions = Object.entries(perSession)
|
|
458
|
+
.flatMap(([sessionID, sessionItems]) =>
|
|
459
|
+
sessionID.startsWith(accountID) ? sessionItems.all : []
|
|
460
|
+
)
|
|
461
|
+
.sort((a, b) => {
|
|
462
|
+
return a.at.getTime() - b.at.getTime();
|
|
463
|
+
});
|
|
464
|
+
const editor = getChildLastQueriedOrSubscribe(accountID);
|
|
465
|
+
const lastItem =
|
|
466
|
+
itemsFromAllMatchingSessions[
|
|
467
|
+
itemsFromAllMatchingSessions.length - 1
|
|
468
|
+
];
|
|
469
|
+
|
|
470
|
+
return [
|
|
471
|
+
accountID,
|
|
472
|
+
{
|
|
473
|
+
last: lastItem?.value,
|
|
474
|
+
by: editor && {
|
|
475
|
+
id: accountID,
|
|
476
|
+
isMe:
|
|
477
|
+
accountID === node.account.id
|
|
478
|
+
? true
|
|
479
|
+
: undefined,
|
|
480
|
+
profile: editor.profile && {
|
|
481
|
+
id: editor.profile.id,
|
|
482
|
+
name: editor.profile.name,
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
at: lastItem && new Date(lastItem.at),
|
|
486
|
+
all: itemsFromAllMatchingSessions,
|
|
487
|
+
} satisfies QueriedCoStreamItems<JsonValue>,
|
|
488
|
+
];
|
|
489
|
+
})
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
const me = isAccountID(node.account.id)
|
|
493
|
+
? perAccount[node.account.id]
|
|
494
|
+
: undefined;
|
|
495
|
+
|
|
496
|
+
const streamResult: QueriedCoStream<AnyCoStream> = {
|
|
497
|
+
type: "costream",
|
|
498
|
+
id: rootValue.id,
|
|
499
|
+
perSession,
|
|
500
|
+
perAccount,
|
|
501
|
+
me,
|
|
502
|
+
meta: rootValue.meta,
|
|
503
|
+
get group() {
|
|
504
|
+
return rootValue.group;
|
|
505
|
+
},
|
|
506
|
+
get core() {
|
|
507
|
+
return rootValue.core;
|
|
508
|
+
},
|
|
509
|
+
edit: (
|
|
510
|
+
changer: (editable: WriteableCoStream<any, any>) => void
|
|
511
|
+
) => {
|
|
512
|
+
rootValue.edit(changer);
|
|
513
|
+
return rootValue;
|
|
514
|
+
},
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
return streamResult;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { newRandomSessionID } from "
|
|
2
|
-
import { cojsonReady } from "
|
|
3
|
-
import { LocalNode } from "
|
|
4
|
-
import { connectedPeers } from "
|
|
1
|
+
import { newRandomSessionID } from "../coValueCore.js";
|
|
2
|
+
import { cojsonReady } from "../index.js";
|
|
3
|
+
import { LocalNode } from "../node.js";
|
|
4
|
+
import { connectedPeers } from "../streamUtils.js";
|
|
5
5
|
|
|
6
6
|
beforeEach(async () => {
|
|
7
7
|
await cojsonReady;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { accountOrAgentIDfromSessionID } from "
|
|
2
|
-
import { BinaryCoStream } from "
|
|
3
|
-
import { createdNowUnique } from "
|
|
4
|
-
import { MAX_RECOMMENDED_TX_SIZE, cojsonReady } from "
|
|
5
|
-
import { LocalNode } from "
|
|
1
|
+
import { accountOrAgentIDfromSessionID } from "../coValueCore.js";
|
|
2
|
+
import { BinaryCoStream } from "../coValues/coStream.js";
|
|
3
|
+
import { createdNowUnique } from "../crypto.js";
|
|
4
|
+
import { MAX_RECOMMENDED_TX_SIZE, cojsonReady } from "../index.js";
|
|
5
|
+
import { LocalNode } from "../node.js";
|
|
6
6
|
import { randomAnonymousAccountAndSessionID } from "./testUtils.js";
|
|
7
7
|
|
|
8
8
|
beforeEach(async () => {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Transaction } from "
|
|
2
|
-
import { LocalNode } from "
|
|
3
|
-
import { createdNowUnique, getAgentSignerSecret, newRandomAgentSecret, sign } from "
|
|
1
|
+
import { Transaction } from "../coValueCore.js";
|
|
2
|
+
import { LocalNode } from "../node.js";
|
|
3
|
+
import { createdNowUnique, getAgentSignerSecret, newRandomAgentSecret, sign } from "../crypto.js";
|
|
4
4
|
import { randomAnonymousAccountAndSessionID } from "./testUtils.js";
|
|
5
|
-
import { MapOpPayload } from "
|
|
6
|
-
import { Role } from "
|
|
7
|
-
import { cojsonReady } from "
|
|
8
|
-
import { stableStringify } from "
|
|
5
|
+
import { MapOpPayload } from "../coValues/coMap.js";
|
|
6
|
+
import { Role } from "../permissions.js";
|
|
7
|
+
import { cojsonReady } from "../index.js";
|
|
8
|
+
import { stableStringify } from "../jsonStringify.js";
|
|
9
9
|
|
|
10
10
|
beforeEach(async () => {
|
|
11
11
|
await cojsonReady;
|
|
@@ -14,14 +14,14 @@ import {
|
|
|
14
14
|
decryptForTransaction,
|
|
15
15
|
encryptKeySecret,
|
|
16
16
|
decryptKeySecret,
|
|
17
|
-
} from '
|
|
17
|
+
} from '../crypto.js';
|
|
18
18
|
import { base58, base64url } from "@scure/base";
|
|
19
19
|
import { x25519 } from "@noble/curves/ed25519";
|
|
20
20
|
import { xsalsa20_poly1305 } from "@noble/ciphers/salsa";
|
|
21
21
|
import { blake3 } from "@noble/hashes/blake3";
|
|
22
22
|
import stableStringify from "fast-json-stable-stringify";
|
|
23
|
-
import { SessionID } from '
|
|
24
|
-
import { cojsonReady } from '
|
|
23
|
+
import { SessionID } from '../ids.js';
|
|
24
|
+
import { cojsonReady } from '../index.js';
|
|
25
25
|
|
|
26
26
|
beforeEach(async () => {
|
|
27
27
|
await cojsonReady;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { LocalNode, CoMap, CoList, CoStream, BinaryCoStream, cojsonReady } from "
|
|
2
|
-
import { randomAnonymousAccountAndSessionID } from "./testUtils";
|
|
1
|
+
import { LocalNode, CoMap, CoList, CoStream, BinaryCoStream, cojsonReady } from "../index";
|
|
2
|
+
import { randomAnonymousAccountAndSessionID } from "./testUtils.js";
|
|
3
3
|
|
|
4
4
|
beforeEach(async () => {
|
|
5
5
|
await cojsonReady;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { newRandomSessionID } from "
|
|
2
|
-
import { expectMap } from "
|
|
3
|
-
import { Group, expectGroupContent } from "
|
|
1
|
+
import { newRandomSessionID } from "../coValueCore.js";
|
|
2
|
+
import { expectMap } from "../coValue.js";
|
|
3
|
+
import { Group, expectGroupContent } from "../group.js";
|
|
4
4
|
import {
|
|
5
5
|
createdNowUnique,
|
|
6
6
|
newRandomKeySecret,
|
|
@@ -10,14 +10,14 @@ import {
|
|
|
10
10
|
getAgentID,
|
|
11
11
|
getAgentSealerSecret,
|
|
12
12
|
getAgentSealerID,
|
|
13
|
-
} from "
|
|
13
|
+
} from "../crypto.js";
|
|
14
14
|
import {
|
|
15
15
|
newGroup,
|
|
16
16
|
newGroupHighLevel,
|
|
17
17
|
groupWithTwoAdmins,
|
|
18
18
|
groupWithTwoAdminsHighLevel,
|
|
19
19
|
} from "./testUtils.js";
|
|
20
|
-
import { AnonymousControlledAccount, cojsonReady } from "
|
|
20
|
+
import { AnonymousControlledAccount, cojsonReady } from "../index.js";
|
|
21
21
|
|
|
22
22
|
beforeEach(async () => {
|
|
23
23
|
await cojsonReady;
|