cojson 0.2.3 → 0.3.0-alpha.0

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.
Files changed (78) hide show
  1. package/dist/account.d.ts +1 -1
  2. package/dist/coValue.d.ts +5 -13
  3. package/dist/coValue.js +14 -7
  4. package/dist/coValue.js.map +1 -1
  5. package/dist/coValueCore.d.ts +6 -6
  6. package/dist/coValueCore.js +11 -14
  7. package/dist/coValueCore.js.map +1 -1
  8. package/dist/coValues/coList.d.ts +99 -34
  9. package/dist/coValues/coList.js +162 -72
  10. package/dist/coValues/coList.js.map +1 -1
  11. package/dist/coValues/coMap.d.ts +96 -31
  12. package/dist/coValues/coMap.js +157 -114
  13. package/dist/coValues/coMap.js.map +1 -1
  14. package/dist/coValues/coStream.d.ts +67 -23
  15. package/dist/coValues/coStream.js +131 -59
  16. package/dist/coValues/coStream.js.map +1 -1
  17. package/dist/crypto.d.ts +8 -3
  18. package/dist/crypto.js +6 -6
  19. package/dist/crypto.js.map +1 -1
  20. package/dist/group.d.ts +57 -23
  21. package/dist/group.js +75 -33
  22. package/dist/group.js.map +1 -1
  23. package/dist/index.d.ts +8 -6
  24. package/dist/index.js +8 -8
  25. package/dist/index.js.map +1 -1
  26. package/dist/{node.d.ts → localNode.d.ts} +16 -8
  27. package/dist/{node.js → localNode.js} +48 -40
  28. package/dist/localNode.js.map +1 -0
  29. package/dist/permissions.js +6 -3
  30. package/dist/permissions.js.map +1 -1
  31. package/dist/queriedCoValues/queriedCoList.d.ts +66 -0
  32. package/dist/queriedCoValues/queriedCoList.js +120 -0
  33. package/dist/queriedCoValues/queriedCoList.js.map +1 -0
  34. package/dist/queriedCoValues/queriedCoMap.d.ts +47 -0
  35. package/dist/queriedCoValues/queriedCoMap.js +83 -0
  36. package/dist/queriedCoValues/queriedCoMap.js.map +1 -0
  37. package/dist/queriedCoValues/queriedCoStream.d.ts +40 -0
  38. package/dist/queriedCoValues/queriedCoStream.js +72 -0
  39. package/dist/queriedCoValues/queriedCoStream.js.map +1 -0
  40. package/dist/queries.d.ts +29 -112
  41. package/dist/queries.js +44 -227
  42. package/dist/queries.js.map +1 -1
  43. package/dist/sync.d.ts +1 -1
  44. package/dist/sync.js +1 -1
  45. package/dist/sync.js.map +1 -1
  46. package/dist/tests/testUtils.d.ts +1 -1
  47. package/dist/tests/testUtils.js +3 -3
  48. package/dist/tests/testUtils.js.map +1 -1
  49. package/package.json +2 -2
  50. package/src/account.ts +1 -1
  51. package/src/coValue.ts +25 -20
  52. package/src/coValueCore.ts +17 -21
  53. package/src/coValues/coList.ts +242 -128
  54. package/src/coValues/coMap.ts +293 -162
  55. package/src/coValues/coStream.ts +227 -94
  56. package/src/crypto.ts +37 -24
  57. package/src/group.ts +90 -63
  58. package/src/index.ts +35 -25
  59. package/src/{node.ts → localNode.ts} +64 -64
  60. package/src/permissions.ts +15 -18
  61. package/src/queriedCoValues/queriedCoList.ts +248 -0
  62. package/src/queriedCoValues/queriedCoMap.ts +180 -0
  63. package/src/queriedCoValues/queriedCoStream.ts +125 -0
  64. package/src/queries.ts +83 -460
  65. package/src/sync.ts +2 -2
  66. package/src/tests/account.test.ts +3 -6
  67. package/src/tests/coValue.test.ts +116 -110
  68. package/src/tests/coValueCore.test.ts +1 -1
  69. package/src/tests/crypto.test.ts +19 -21
  70. package/src/tests/permissions.test.ts +255 -242
  71. package/src/tests/queries.test.ts +57 -40
  72. package/src/tests/sync.test.ts +30 -30
  73. package/src/tests/testUtils.ts +3 -3
  74. package/dist/coValues/static.d.ts +0 -14
  75. package/dist/coValues/static.js +0 -20
  76. package/dist/coValues/static.js.map +0 -1
  77. package/dist/node.js.map +0 -1
  78. package/src/coValues/static.ts +0 -31
@@ -1,9 +1,7 @@
1
1
  import { CoID } from "./coValue.js";
2
2
  import { MapOpPayload } from "./coValues/coMap.js";
3
3
  import { JsonValue } from "./jsonValue.js";
4
- import {
5
- KeyID,
6
- } from "./crypto.js";
4
+ import { KeyID } from "./crypto.js";
7
5
  import {
8
6
  CoValueCore,
9
7
  Transaction,
@@ -11,11 +9,9 @@ import {
11
9
  accountOrAgentIDfromSessionID,
12
10
  } from "./coValueCore.js";
13
11
  import { AgentID, RawCoID, SessionID, TransactionID } from "./ids.js";
14
- import {
15
- AccountID,
16
- Profile,
17
- } from "./account.js";
12
+ import { AccountID, Profile } from "./account.js";
18
13
  import { parseJSON } from "./jsonStringify.js";
14
+ import { expectGroupContent } from "./group.js";
19
15
 
20
16
  export type PermissionsDef =
21
17
  | { type: "group"; initialAdmin: AccountID | AgentID }
@@ -77,7 +73,7 @@ export function determineValidTransactions(
77
73
  // console.log("before", { memberState, validTransactions });
78
74
  const transactor = accountOrAgentIDfromSessionID(sessionID);
79
75
 
80
- const changes = parseJSON(tx.changes)
76
+ const changes = parseJSON(tx.changes);
81
77
 
82
78
  const change = changes[0] as
83
79
  | MapOpPayload<AccountID | AgentID, Role>
@@ -193,12 +189,14 @@ export function determineValidTransactions(
193
189
 
194
190
  return validTransactions;
195
191
  } else if (coValue.header.ruleset.type === "ownedByGroup") {
196
- const groupContent = coValue.node
197
- .expectCoValueLoaded(
198
- coValue.header.ruleset.group,
199
- "Determining valid transaction in owned object but its group wasn't loaded"
200
- )
201
- .getCurrentContent();
192
+ const groupContent = expectGroupContent(
193
+ coValue.node
194
+ .expectCoValueLoaded(
195
+ coValue.header.ruleset.group,
196
+ "Determining valid transaction in owned object but its group wasn't loaded"
197
+ )
198
+ .getCurrentContent()
199
+ );
202
200
 
203
201
  if (groupContent.type !== "comap") {
204
202
  throw new Error("Group must be a map");
@@ -211,10 +209,9 @@ export function determineValidTransactions(
211
209
  );
212
210
  return sessionLog.transactions
213
211
  .filter((tx) => {
214
- const transactorRoleAtTxTime = groupContent.getAtTime(
215
- transactor,
216
- tx.madeAt
217
- );
212
+ const transactorRoleAtTxTime = groupContent
213
+ .atTime(tx.madeAt)
214
+ .get(transactor);
218
215
 
219
216
  return (
220
217
  transactorRoleAtTxTime === "admin" ||
@@ -0,0 +1,248 @@
1
+ import { CoList, MutableCoList } from "../coValues/coList.js";
2
+ import { CoValueCore } from "../coValueCore.js";
3
+ import { Group } from "../group.js";
4
+ import { isAccountID } from "../account.js";
5
+ import { AnyCoList, CoID, CoValue } from "../coValue.js";
6
+ import { TransactionID } from "../ids.js";
7
+ import { QueriedAccountAndProfile } from "./queriedCoMap.js";
8
+ import { ValueOrSubQueried, QueryContext } from "../queries.js";
9
+
10
+ export class QueriedCoList<L extends AnyCoList> extends Array<
11
+ ValueOrSubQueried<L["_item"]>
12
+ > {
13
+ coList!: L;
14
+ id!: CoID<L>;
15
+ type!: "colist";
16
+
17
+ /** @internal */
18
+ constructor(coList: L, queryContext: QueryContext) {
19
+ if (!(coList instanceof CoList)) {
20
+ // this might be called from an intrinsic, like map, trying to create an empty array
21
+ // passing `0` as the only parameter
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ return new Array(coList) as any;
24
+ }
25
+ super(
26
+ ...coList
27
+ .asArray()
28
+ .map(
29
+ (item) =>
30
+ queryContext.resolveValue(item) as ValueOrSubQueried<
31
+ L["_item"]
32
+ >
33
+ )
34
+ );
35
+
36
+ Object.defineProperties(this, {
37
+ coList: { value: coList },
38
+ id: { value: coList.id },
39
+ type: { value: "colist" },
40
+ edits: {
41
+ value: [...this.keys()].map((i) => {
42
+ const edit = coList.editAt(i)!;
43
+ return {
44
+ by:
45
+ edit.by && isAccountID(edit.by)
46
+ ? queryContext.resolveAccount(edit.by)
47
+ : undefined,
48
+ tx: edit.tx,
49
+ at: new Date(edit.at),
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ value: queryContext.resolveValue(edit.value) as any,
52
+ };
53
+ }),
54
+ },
55
+ deletions: {
56
+ value: coList.deletionEdits().map((deletion) => ({
57
+ by:
58
+ deletion.by && isAccountID(deletion.by)
59
+ ? queryContext.resolveAccount(deletion.by)
60
+ : undefined,
61
+ tx: deletion.tx,
62
+ at: new Date(deletion.at),
63
+ })),
64
+ },
65
+ });
66
+ }
67
+
68
+ get meta(): L["meta"] {
69
+ return this.coList.meta;
70
+ }
71
+
72
+ get group(): Group {
73
+ return this.coList.group;
74
+ }
75
+
76
+ get core(): CoValueCore {
77
+ return this.coList.core;
78
+ }
79
+
80
+ append(
81
+ item: L["_item"] extends CoValue
82
+ ? L["_item"] | CoID<L["_item"]>
83
+ : L["_item"],
84
+ after?: number,
85
+ privacy?: "private" | "trusting"
86
+ ): L {
87
+ return this.coList.append(item, after, privacy);
88
+ }
89
+
90
+ prepend(
91
+ item: L["_item"] extends CoValue
92
+ ? L["_item"] | CoID<L["_item"]>
93
+ : L["_item"],
94
+ before?: number,
95
+ privacy?: "private" | "trusting"
96
+ ): L {
97
+ return this.coList.prepend(item, before, privacy);
98
+ }
99
+
100
+ delete(at: number, privacy: "private" | "trusting"): L {
101
+ return this.coList.delete(at, privacy);
102
+ }
103
+
104
+ mutate(
105
+ mutator: (mutable: MutableCoList<L["_item"], L["meta"]>) => void
106
+ ): L {
107
+ return this.coList.mutate(mutator);
108
+ }
109
+
110
+ edits!: {
111
+ by?: QueriedAccountAndProfile;
112
+ tx: TransactionID;
113
+ at: Date;
114
+ value: L["_item"] extends CoValue
115
+ ? CoID<L["_item"]>
116
+ : Exclude<L["_item"], CoValue>;
117
+ }[];
118
+
119
+ deletions!: {
120
+ by?: QueriedAccountAndProfile;
121
+ tx: TransactionID;
122
+ at: Date;
123
+ }[];
124
+
125
+ /** @internal */
126
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
127
+ static isArray(arg: any): arg is any[] {
128
+ return Array.isArray(arg);
129
+ }
130
+
131
+ /** @internal */
132
+ static from<T>(arrayLike: ArrayLike<T>): T[];
133
+ /** @internal */
134
+ static from<T, U>(
135
+ arrayLike: ArrayLike<T>,
136
+ mapfn: (v: T, k: number) => U,
137
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
138
+ thisArg?: any
139
+ ): U[];
140
+ /** @internal */
141
+ static from<T>(iterable: Iterable<T> | ArrayLike<T>): T[];
142
+ /** @internal */
143
+ static from<T, U>(
144
+ iterable: Iterable<T> | ArrayLike<T>,
145
+ mapfn: (v: T, k: number) => U,
146
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
147
+ thisArg?: any
148
+ ): U[];
149
+ /** @internal */
150
+ static from<T, U>(
151
+ _iterable: unknown,
152
+ _mapfn?: unknown,
153
+ _thisArg?: unknown
154
+ ): T[] | U[] | T[] | U[] {
155
+ throw new Error("Array method 'from' not supported on QueriedCoList");
156
+ }
157
+
158
+ /** @internal */
159
+ static of<T>(..._items: T[]): T[] {
160
+ throw new Error("Array method 'of' not supported on QueriedCoList");
161
+ }
162
+
163
+ /** @internal */
164
+ pop(): ValueOrSubQueried<L["_item"]> | undefined {
165
+ throw new Error("Array method 'pop' not supported on QueriedCoList");
166
+ }
167
+
168
+ /** @internal */
169
+ push(..._items: ValueOrSubQueried<L["_item"]>[]): number {
170
+ throw new Error("Array method 'push' not supported on QueriedCoList");
171
+ }
172
+
173
+ /** @internal */
174
+ concat(
175
+ ..._items: ConcatArray<ValueOrSubQueried<L["_item"]>>[]
176
+ ): ValueOrSubQueried<L["_item"]>[];
177
+ /** @internal */
178
+ concat(
179
+ ..._items: (
180
+ | ValueOrSubQueried<L["_item"]>
181
+ | ConcatArray<ValueOrSubQueried<L["_item"]>>
182
+ )[]
183
+ ): ValueOrSubQueried<L["_item"]>[];
184
+ /** @internal */
185
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
186
+ concat(..._items: any[]): ValueOrSubQueried<L["_item"]>[] {
187
+ throw new Error("Array method 'concat' not supported on QueriedCoList");
188
+ }
189
+
190
+ /** @internal */
191
+ reverse(): ValueOrSubQueried<L["_item"]>[] {
192
+ throw new Error(
193
+ "Array method 'reverse' not supported on QueriedCoList"
194
+ );
195
+ }
196
+
197
+ /** @internal */
198
+ shift(): ValueOrSubQueried<L["_item"]> | undefined {
199
+ throw new Error("Array method 'shift' not supported on QueriedCoList");
200
+ }
201
+
202
+ /** @internal */
203
+ sort(
204
+ _compareFn?:
205
+ | ((
206
+ a: ValueOrSubQueried<L["_item"]>,
207
+ b: ValueOrSubQueried<L["_item"]>
208
+ ) => number)
209
+ | undefined
210
+ ): this {
211
+ throw new Error("Array method 'sort' not supported on QueriedCoList");
212
+ }
213
+
214
+ /** @internal */
215
+ splice(
216
+ _start: number,
217
+ _deleteCount?: number | undefined
218
+ ): ValueOrSubQueried<L["_item"]>[] {
219
+ throw new Error("Array method 'splice' not supported on QueriedCoList");
220
+ }
221
+
222
+ /** @internal */
223
+ unshift(..._items: ValueOrSubQueried<L["_item"]>[]): number {
224
+ throw new Error(
225
+ "Array method 'unshift' not supported on QueriedCoList"
226
+ );
227
+ }
228
+
229
+ /** @internal */
230
+ fill(
231
+ _value: ValueOrSubQueried<L["_item"]>,
232
+ _start?: number | undefined,
233
+ _end?: number | undefined
234
+ ): this {
235
+ throw new Error("Array method 'fill' not supported on QueriedCoList");
236
+ }
237
+
238
+ /** @internal */
239
+ copyWithin(
240
+ _target: number,
241
+ _start: number,
242
+ _end?: number | undefined
243
+ ): this {
244
+ throw new Error(
245
+ "Array method 'copyWithin' not supported on QueriedCoList"
246
+ );
247
+ }
248
+ }
@@ -0,0 +1,180 @@
1
+ import { MutableCoMap } from "../coValues/coMap.js";
2
+ import { CoValueCore } from "../coValueCore.js";
3
+ import { Group } from "../group.js";
4
+ import { Account, AccountID, Profile, isAccountID } from "../account.js";
5
+ import { AnyCoMap, CoID, CoValue } from "../coValue.js";
6
+ import { TransactionID } from "../ids.js";
7
+ import { ValueOrSubQueried, QueryContext } from "../queries.js";
8
+
9
+ export type QueriedCoMap<M extends AnyCoMap> = {
10
+ [K in keyof M["_shape"] & string]: ValueOrSubQueried<M["_shape"][K]>;
11
+ } & QueriedCoMapBase<M>;
12
+
13
+ export type QueriedCoMapEdit<
14
+ M extends AnyCoMap,
15
+ K extends keyof M["_shape"]
16
+ > = {
17
+ by?: QueriedAccountAndProfile;
18
+ tx: TransactionID;
19
+ at: Date;
20
+ value: M["_shape"][K] extends CoValue
21
+ ? CoID<M["_shape"][K]>
22
+ : Exclude<M["_shape"][K], CoValue>;
23
+ };
24
+
25
+ export class QueriedCoMapBase<M extends AnyCoMap> {
26
+ coMap!: M;
27
+ id!: CoID<M>;
28
+ type!: "comap";
29
+
30
+ /** @internal */
31
+ static newWithKVPairs<M extends AnyCoMap>(
32
+ coMap: M,
33
+ queryContext: QueryContext
34
+ ): QueriedCoMap<M> {
35
+ const kv = {} as {
36
+ [K in keyof M["_shape"] & string]: ValueOrSubQueried<
37
+ M["_shape"][K]
38
+ >;
39
+ };
40
+
41
+ if (coMap.meta?.type === "account") {
42
+ const profileID = coMap.get("profile");
43
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
+ (kv as any).profile =
45
+ profileID && queryContext.resolveValue(profileID);
46
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
+ (kv as any).isMe =
48
+ (coMap as unknown as Account).id ===
49
+ queryContext.node.account.id;
50
+ } else {
51
+ for (const key of coMap.keys()) {
52
+ const value = coMap.get(key);
53
+
54
+ if (value === undefined) continue;
55
+
56
+ kv[key as keyof typeof kv] = queryContext.resolveValue(
57
+ value
58
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
+ ) as any;
60
+ }
61
+ }
62
+
63
+ return Object.assign(new QueriedCoMapBase(coMap, queryContext), kv);
64
+ }
65
+
66
+ /** @internal */
67
+ constructor(coMap: M, queryContext: QueryContext) {
68
+ Object.defineProperties(this, {
69
+ coMap: { value: coMap, enumerable: false },
70
+ id: { value: coMap.id, enumerable: false },
71
+ type: { value: "comap", enumerable: false },
72
+ edits: {
73
+ value: Object.fromEntries(
74
+ coMap.keys().flatMap((key) => {
75
+ const edits = [...coMap.editsAt(key)].map((edit) => ({
76
+ by:
77
+ edit.by && isAccountID(edit.by)
78
+ ? queryContext.resolveAccount(edit.by)
79
+ : undefined,
80
+ tx: edit.tx,
81
+ at: new Date(edit.at),
82
+ value:
83
+ edit.value &&
84
+ queryContext.resolveValue(edit.value),
85
+ }));
86
+ const lastEdit = edits[edits.length - 1];
87
+ if (!lastEdit) return [];
88
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
+ const editsAtKey = {
90
+ by: lastEdit.by,
91
+ tx: lastEdit.tx,
92
+ at: lastEdit.at,
93
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
+ value: lastEdit.value as any,
95
+ all: edits,
96
+ };
97
+
98
+ return [[key, editsAtKey]];
99
+ })
100
+ ),
101
+ enumerable: false,
102
+ },
103
+ });
104
+ }
105
+
106
+ edits!: {
107
+ [K in keyof M["_shape"] & string]:
108
+ | (QueriedCoMapEdit<M, K> & {
109
+ all: QueriedCoMapEdit<M, K>[];
110
+ })
111
+ | undefined;
112
+ };
113
+
114
+ get meta(): M["meta"] {
115
+ return this.coMap.meta;
116
+ }
117
+
118
+ get group(): Group {
119
+ return this.coMap.group;
120
+ }
121
+
122
+ get core(): CoValueCore {
123
+ return this.coMap.core;
124
+ }
125
+
126
+ set<K extends keyof M["_shape"] & string>(
127
+ key: K,
128
+ value: M["_shape"][K] extends CoValue
129
+ ? M["_shape"][K] | CoID<M["_shape"][K]>
130
+ : M["_shape"][K],
131
+ privacy?: "private" | "trusting"
132
+ ): M;
133
+ set(
134
+ kv: {
135
+ [K in keyof M["_shape"] & string]?: M["_shape"][K] extends CoValue
136
+ ? M["_shape"][K] | CoID<M["_shape"][K]>
137
+ : M["_shape"][K];
138
+ },
139
+ privacy?: "private" | "trusting"
140
+ ): M;
141
+ set<K extends keyof M["_shape"] & string>(
142
+ ...args:
143
+ | [
144
+ {
145
+ [K in keyof M["_shape"] &
146
+ string]?: M["_shape"][K] extends CoValue
147
+ ? M["_shape"][K] | CoID<M["_shape"][K]>
148
+ : M["_shape"][K];
149
+ },
150
+ ("private" | "trusting")?
151
+ ]
152
+ | [
153
+ K,
154
+ M["_shape"][K] extends CoValue
155
+ ? M["_shape"][K] | CoID<M["_shape"][K]>
156
+ : M["_shape"][K],
157
+ ("private" | "trusting")?
158
+ ]
159
+ ): M {
160
+ // eslint-disable-next-line @typescript-eslint/ban-types
161
+ return (this.coMap.set as Function)(...args);
162
+ }
163
+ delete(
164
+ key: keyof M["_shape"] & string,
165
+ privacy?: "private" | "trusting"
166
+ ): M {
167
+ return this.coMap.delete(key, privacy);
168
+ }
169
+ mutate(
170
+ mutator: (mutable: MutableCoMap<M["_shape"], M["meta"]>) => void
171
+ ): M {
172
+ return this.coMap.mutate(mutator);
173
+ }
174
+ }
175
+
176
+ export type QueriedAccountAndProfile = {
177
+ profile?: { name?: string; id: CoID<Profile> };
178
+ isMe?: boolean;
179
+ id: AccountID;
180
+ };
@@ -0,0 +1,125 @@
1
+ import { JsonValue } from "../jsonValue.js";
2
+ import { MutableCoStream } from "../coValues/coStream.js";
3
+ import { CoValueCore } from "../coValueCore.js";
4
+ import { Group } from "../group.js";
5
+ import { AccountID, isAccountID } from "../account.js";
6
+ import { AnyCoStream, CoID, CoValue } from "../coValue.js";
7
+ import { SessionID, TransactionID } from "../ids.js";
8
+ import { QueriedAccountAndProfile } from "./queriedCoMap.js";
9
+ import { ValueOrSubQueried, QueryContext } from "../queries.js";
10
+
11
+
12
+ export type QueriedCoStreamItems<Item extends JsonValue | CoValue> = {
13
+ last?: ValueOrSubQueried<Item>;
14
+ by?: QueriedAccountAndProfile;
15
+ tx?: TransactionID;
16
+ at?: Date;
17
+ all: {
18
+ value: ValueOrSubQueried<Item>;
19
+ by?: QueriedAccountAndProfile;
20
+ tx: TransactionID;
21
+ at: Date;
22
+ }[];
23
+ };
24
+
25
+ export class QueriedCoStream<S extends AnyCoStream> {
26
+ coStream: S;
27
+ id: CoID<S>;
28
+ type = "costream" as const;
29
+
30
+ /** @internal */
31
+ constructor(coStream: S, queryContext: QueryContext) {
32
+ this.coStream = coStream;
33
+ this.id = coStream.id;
34
+
35
+ this.perSession = Object.fromEntries(
36
+ coStream.sessions().map((sessionID) => {
37
+ const items = [...coStream.itemsIn(sessionID)].map((item) => ({
38
+ by: item.by && isAccountID(item.by)
39
+ ? queryContext.resolveAccount(item.by)
40
+ : undefined,
41
+ tx: item.tx,
42
+ at: new Date(item.at),
43
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
+ value: queryContext.resolveValue(item.value) as any,
45
+ }));
46
+
47
+ const lastItem = items[items.length - 1];
48
+
49
+ return [
50
+ sessionID,
51
+ {
52
+ last: lastItem?.value,
53
+ by: lastItem?.by,
54
+ tx: lastItem?.tx,
55
+ at: lastItem?.at,
56
+ all: items,
57
+ } satisfies QueriedCoStreamItems<S["_item"]>,
58
+ ];
59
+ })
60
+ );
61
+
62
+ this.perAccount = Object.fromEntries(
63
+ [...coStream.accounts()].map((accountID) => {
64
+ const items = [...coStream.itemsBy(accountID)].map((item) => ({
65
+ by: item.by && isAccountID(item.by)
66
+ ? queryContext.resolveAccount(item.by)
67
+ : undefined,
68
+ tx: item.tx,
69
+ at: new Date(item.at),
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ value: queryContext.resolveValue(item.value) as any,
72
+ }));
73
+
74
+ const lastItem = items[items.length - 1];
75
+
76
+ return [
77
+ accountID,
78
+ {
79
+ last: lastItem?.value,
80
+ by: lastItem?.by,
81
+ tx: lastItem?.tx,
82
+ at: lastItem?.at,
83
+ all: items,
84
+ } satisfies QueriedCoStreamItems<S["_item"]>,
85
+ ];
86
+ })
87
+ );
88
+
89
+ this.me = isAccountID(queryContext.node.account.id)
90
+ ? this.perAccount[queryContext.node.account.id]
91
+ : undefined;
92
+ }
93
+
94
+ get meta(): S["meta"] {
95
+ return this.coStream.meta;
96
+ }
97
+
98
+ get group(): Group {
99
+ return this.coStream.group;
100
+ }
101
+
102
+ get core(): CoValueCore {
103
+ return this.coStream.core;
104
+ }
105
+
106
+ me?: QueriedCoStreamItems<S["_item"]>;
107
+ perAccount: {
108
+ [account: AccountID]: QueriedCoStreamItems<S["_item"]>;
109
+ };
110
+ perSession: {
111
+ [session: SessionID]: QueriedCoStreamItems<S["_item"]>;
112
+ };
113
+
114
+ push(
115
+ item: S["_item"] extends CoValue ? S["_item"] | CoID<S["_item"]> : S["_item"],
116
+ privacy?: "private" | "trusting"
117
+ ): S {
118
+ return this.coStream.push(item, privacy);
119
+ }
120
+ mutate(
121
+ mutator: (mutable: MutableCoStream<S["_item"], S["meta"]>) => void
122
+ ): S {
123
+ return this.coStream.mutate(mutator);
124
+ }
125
+ }