cojson 0.2.3 → 0.3.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.
- package/dist/account.d.ts +1 -1
- package/dist/coValue.d.ts +5 -13
- package/dist/coValue.js +14 -7
- package/dist/coValue.js.map +1 -1
- package/dist/coValueCore.d.ts +6 -6
- package/dist/coValueCore.js +11 -14
- package/dist/coValueCore.js.map +1 -1
- package/dist/coValues/coList.d.ts +99 -34
- package/dist/coValues/coList.js +162 -72
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.d.ts +96 -31
- package/dist/coValues/coMap.js +157 -114
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coStream.d.ts +67 -23
- package/dist/coValues/coStream.js +131 -59
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/crypto.d.ts +8 -3
- package/dist/crypto.js +6 -6
- package/dist/crypto.js.map +1 -1
- package/dist/group.d.ts +57 -23
- package/dist/group.js +75 -33
- package/dist/group.js.map +1 -1
- package/dist/index.d.ts +8 -6
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/{node.d.ts → localNode.d.ts} +16 -8
- package/dist/{node.js → localNode.js} +48 -40
- package/dist/localNode.js.map +1 -0
- package/dist/permissions.js +6 -3
- package/dist/permissions.js.map +1 -1
- package/dist/queriedCoValues/queriedCoList.d.ts +66 -0
- package/dist/queriedCoValues/queriedCoList.js +120 -0
- package/dist/queriedCoValues/queriedCoList.js.map +1 -0
- package/dist/queriedCoValues/queriedCoMap.d.ts +47 -0
- package/dist/queriedCoValues/queriedCoMap.js +83 -0
- package/dist/queriedCoValues/queriedCoMap.js.map +1 -0
- package/dist/queriedCoValues/queriedCoStream.d.ts +40 -0
- package/dist/queriedCoValues/queriedCoStream.js +72 -0
- package/dist/queriedCoValues/queriedCoStream.js.map +1 -0
- package/dist/queries.d.ts +29 -112
- package/dist/queries.js +44 -227
- package/dist/queries.js.map +1 -1
- package/dist/sync.d.ts +1 -1
- package/dist/sync.js +1 -1
- package/dist/sync.js.map +1 -1
- package/dist/tests/testUtils.d.ts +1 -1
- package/dist/tests/testUtils.js +3 -3
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +2 -2
- package/src/account.ts +1 -1
- package/src/coValue.ts +25 -20
- package/src/coValueCore.ts +17 -21
- package/src/coValues/coList.ts +242 -128
- package/src/coValues/coMap.ts +293 -162
- package/src/coValues/coStream.ts +227 -94
- package/src/crypto.ts +37 -24
- package/src/group.ts +90 -63
- package/src/index.ts +35 -25
- package/src/{node.ts → localNode.ts} +64 -64
- package/src/permissions.ts +15 -18
- package/src/queriedCoValues/queriedCoList.ts +248 -0
- package/src/queriedCoValues/queriedCoMap.ts +180 -0
- package/src/queriedCoValues/queriedCoStream.ts +125 -0
- package/src/queries.ts +83 -460
- package/src/sync.ts +2 -2
- package/src/tests/account.test.ts +3 -6
- package/src/tests/coValue.test.ts +116 -110
- package/src/tests/coValueCore.test.ts +1 -1
- package/src/tests/crypto.test.ts +19 -21
- package/src/tests/permissions.test.ts +255 -242
- package/src/tests/queries.test.ts +57 -40
- package/src/tests/sync.test.ts +30 -30
- package/src/tests/testUtils.ts +3 -3
- package/dist/coValues/static.d.ts +0 -14
- package/dist/coValues/static.js +0 -20
- package/dist/coValues/static.js.map +0 -1
- package/dist/node.js.map +0 -1
- package/src/coValues/static.ts +0 -31
package/src/permissions.ts
CHANGED
|
@@ -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 =
|
|
197
|
-
.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
|
215
|
-
|
|
216
|
-
|
|
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
|
+
}
|