cojson 0.4.0 → 0.4.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/dist/coValue.js +1 -1
- package/dist/coValue.js.map +1 -1
- package/dist/coValues/coList.js +1 -1
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.js +1 -1
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coStream.js +3 -2
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/coValues/group.js.map +1 -1
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/localNode.js +1 -14
- package/dist/localNode.js.map +1 -1
- package/package.json +4 -4
- package/src/coValue.ts +10 -7
- package/src/coValues/coList.ts +1 -1
- package/src/coValues/coMap.ts +1 -1
- package/src/coValues/coStream.ts +4 -6
- package/src/coValues/group.ts +4 -4
- package/src/index.ts +16 -16
- package/src/localNode.ts +6 -47
- package/src/tests/coValue.test.ts +5 -5
- package/src/tests/group.test.ts +1 -1
- package/dist/base64url.d.ts +0 -2
- package/dist/coValue.d.ts +0 -38
- package/dist/coValueCore.d.ts +0 -103
- package/dist/coValues/account.d.ts +0 -62
- package/dist/coValues/coList.d.ts +0 -179
- package/dist/coValues/coMap.d.ts +0 -149
- package/dist/coValues/coStream.d.ts +0 -123
- package/dist/coValues/group.d.ts +0 -111
- package/dist/crypto.d.ts +0 -120
- package/dist/ids.d.ts +0 -11
- package/dist/index.d.ts +0 -67
- package/dist/jsonStringify.d.ts +0 -6
- package/dist/jsonValue.d.ts +0 -7
- package/dist/localNode.d.ts +0 -101
- package/dist/media.d.ts +0 -7
- package/dist/permissions.d.ts +0 -20
- package/dist/queriedCoValues/queriedAccount.d.ts +0 -13
- package/dist/queriedCoValues/queriedAccount.js +0 -24
- package/dist/queriedCoValues/queriedAccount.js.map +0 -1
- package/dist/queriedCoValues/queriedCoList.d.ts +0 -66
- package/dist/queriedCoValues/queriedCoList.js +0 -116
- package/dist/queriedCoValues/queriedCoList.js.map +0 -1
- package/dist/queriedCoValues/queriedCoMap.d.ts +0 -40
- package/dist/queriedCoValues/queriedCoMap.js +0 -82
- package/dist/queriedCoValues/queriedCoMap.js.map +0 -1
- package/dist/queriedCoValues/queriedCoStream.d.ts +0 -40
- package/dist/queriedCoValues/queriedCoStream.js +0 -96
- package/dist/queriedCoValues/queriedCoStream.js.map +0 -1
- package/dist/queriedCoValues/queriedGroup.d.ts +0 -29
- package/dist/queriedCoValues/queriedGroup.js +0 -54
- package/dist/queriedCoValues/queriedGroup.js.map +0 -1
- package/dist/queries.d.ts +0 -62
- package/dist/queries.js +0 -142
- package/dist/queries.js.map +0 -1
- package/dist/streamUtils.d.ts +0 -8
- package/dist/sync.d.ts +0 -80
- package/dist/tests/testUtils.d.ts +0 -37
- package/src/queriedCoValues/queriedAccount.ts +0 -40
- package/src/queriedCoValues/queriedCoList.ts +0 -240
- package/src/queriedCoValues/queriedCoMap.ts +0 -168
- package/src/queriedCoValues/queriedCoStream.ts +0 -155
- package/src/queriedCoValues/queriedGroup.ts +0 -90
- package/src/queries.ts +0 -263
- package/src/tests/queries.test.ts +0 -337
package/src/queries.ts
DELETED
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import { JsonValue } from "./jsonValue.js";
|
|
2
|
-
import { CoMap } from "./coValues/coMap.js";
|
|
3
|
-
import { CoStream } from "./coValues/coStream.js";
|
|
4
|
-
import { CoList } from "./coValues/coList.js";
|
|
5
|
-
import { Account, AccountID } from "./coValues/account.js";
|
|
6
|
-
import { CoID, CoValue } from "./coValue.js";
|
|
7
|
-
import { LocalNode } from "./localNode.js";
|
|
8
|
-
import {
|
|
9
|
-
QueriedCoMap,
|
|
10
|
-
QueriedCoMapBase,
|
|
11
|
-
} from "./queriedCoValues/queriedCoMap.js";
|
|
12
|
-
import { QueriedCoList } from "./queriedCoValues/queriedCoList.js";
|
|
13
|
-
import { QueriedCoStream } from "./queriedCoValues/queriedCoStream.js";
|
|
14
|
-
import { Group } from "./coValues/group.js";
|
|
15
|
-
import { QueriedAccount } from "./queriedCoValues/queriedAccount.js";
|
|
16
|
-
import { QueriedGroup } from "./queriedCoValues/queriedGroup.js";
|
|
17
|
-
|
|
18
|
-
export type Queried<T extends CoValue> = T extends CoMap
|
|
19
|
-
? T extends Account
|
|
20
|
-
? QueriedAccount<T>
|
|
21
|
-
: T extends Group
|
|
22
|
-
? QueriedGroup<T>
|
|
23
|
-
: QueriedCoMap<T>
|
|
24
|
-
: T extends CoList
|
|
25
|
-
? QueriedCoList<T>
|
|
26
|
-
: T extends CoStream
|
|
27
|
-
? T["meta"] extends { type: "binary" }
|
|
28
|
-
? never
|
|
29
|
-
: QueriedCoStream<T>
|
|
30
|
-
:
|
|
31
|
-
| QueriedAccount
|
|
32
|
-
| QueriedGroup
|
|
33
|
-
| QueriedCoMap<CoMap>
|
|
34
|
-
| QueriedCoList<CoList>
|
|
35
|
-
| QueriedCoStream<CoStream>;
|
|
36
|
-
|
|
37
|
-
export type ValueOrSubQueried<
|
|
38
|
-
V extends JsonValue | CoValue | CoID<CoValue> | undefined
|
|
39
|
-
> = V extends CoID<infer C>
|
|
40
|
-
? Queried<C> | undefined
|
|
41
|
-
: V extends CoValue
|
|
42
|
-
? Queried<V> | undefined
|
|
43
|
-
: V;
|
|
44
|
-
|
|
45
|
-
export interface CleanupCallbackAndUsable {
|
|
46
|
-
(): void;
|
|
47
|
-
[Symbol.dispose]: () => void;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface QueryExtension<T extends CoValue, O> {
|
|
51
|
-
id: string;
|
|
52
|
-
query(
|
|
53
|
-
base: T,
|
|
54
|
-
queryContext: QueryContext,
|
|
55
|
-
onUpdate: (value: O) => void
|
|
56
|
-
): () => void;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export class QueryContext {
|
|
60
|
-
values: {
|
|
61
|
-
[id: CoID<CoValue>]: {
|
|
62
|
-
lastUpdate: CoValue | undefined;
|
|
63
|
-
lastQueried: Queried<CoValue> | undefined;
|
|
64
|
-
render: () => void;
|
|
65
|
-
unsubscribe: () => void;
|
|
66
|
-
};
|
|
67
|
-
} = {};
|
|
68
|
-
extensions: {
|
|
69
|
-
[id: `${CoID<CoValue>}_${string}`]: {
|
|
70
|
-
lastOutput: unknown;
|
|
71
|
-
unsubscribe: () => void;
|
|
72
|
-
};
|
|
73
|
-
} = {};
|
|
74
|
-
node: LocalNode;
|
|
75
|
-
onUpdate: () => void;
|
|
76
|
-
|
|
77
|
-
constructor(node: LocalNode, onUpdate: () => void) {
|
|
78
|
-
this.node = node;
|
|
79
|
-
this.onUpdate = onUpdate;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
query<T extends CoValue>(valueID: CoID<T>, alsoRender: CoID<CoValue>[]) {
|
|
83
|
-
let value = this.values[valueID];
|
|
84
|
-
if (!value) {
|
|
85
|
-
const render = () => {
|
|
86
|
-
let newQueried;
|
|
87
|
-
const lastUpdate = value!.lastUpdate;
|
|
88
|
-
|
|
89
|
-
if (lastUpdate instanceof CoMap) {
|
|
90
|
-
if (lastUpdate instanceof Account) {
|
|
91
|
-
newQueried = new QueriedAccount(
|
|
92
|
-
lastUpdate,
|
|
93
|
-
this
|
|
94
|
-
) as Queried<T>;
|
|
95
|
-
} else if (lastUpdate instanceof Group) {
|
|
96
|
-
newQueried = new QueriedGroup(
|
|
97
|
-
lastUpdate,
|
|
98
|
-
this
|
|
99
|
-
) as Queried<T>;
|
|
100
|
-
} else {
|
|
101
|
-
newQueried = QueriedCoMapBase.newWithKVPairs(
|
|
102
|
-
lastUpdate,
|
|
103
|
-
this
|
|
104
|
-
) as Queried<T>;
|
|
105
|
-
}
|
|
106
|
-
} else if (lastUpdate instanceof CoList) {
|
|
107
|
-
newQueried = new QueriedCoList(
|
|
108
|
-
lastUpdate,
|
|
109
|
-
this
|
|
110
|
-
) as Queried<T>;
|
|
111
|
-
} else if (lastUpdate instanceof CoStream) {
|
|
112
|
-
if (lastUpdate.meta?.type === "binary") {
|
|
113
|
-
// Querying binary string not yet implemented
|
|
114
|
-
} else {
|
|
115
|
-
newQueried = new QueriedCoStream(
|
|
116
|
-
lastUpdate,
|
|
117
|
-
this
|
|
118
|
-
) as Queried<T>;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// console.log(
|
|
123
|
-
// "Rendered ",
|
|
124
|
-
// valueID,
|
|
125
|
-
// lastUpdate?.constructor.name,
|
|
126
|
-
// newQueried
|
|
127
|
-
// );
|
|
128
|
-
|
|
129
|
-
value!.lastQueried = newQueried;
|
|
130
|
-
|
|
131
|
-
for (const alsoRenderID of alsoRender) {
|
|
132
|
-
// console.log("Also rendering", alsoRenderID);
|
|
133
|
-
this.values[alsoRenderID]?.render();
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
value = {
|
|
138
|
-
lastQueried: undefined,
|
|
139
|
-
lastUpdate: undefined,
|
|
140
|
-
render,
|
|
141
|
-
unsubscribe: this.node.subscribe(valueID, (valueUpdate) => {
|
|
142
|
-
value!.lastUpdate = valueUpdate;
|
|
143
|
-
value!.render();
|
|
144
|
-
this.onUpdate();
|
|
145
|
-
}),
|
|
146
|
-
};
|
|
147
|
-
this.values[valueID] = value;
|
|
148
|
-
}
|
|
149
|
-
return value.lastQueried as Queried<T> | undefined;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
queryIfCoID<T extends JsonValue | undefined>(value: T, alsoRender: CoID<CoValue>[]): T extends CoID<infer C> ? Queried<C> | undefined : T {
|
|
153
|
-
if (typeof value === "string" && value.startsWith("co_")) {
|
|
154
|
-
return this.query(value as CoID<CoValue>, alsoRender) as T extends CoID<infer C> ? Queried<C> | undefined : never;
|
|
155
|
-
} else {
|
|
156
|
-
return value as T extends CoID<infer C> ? Queried<C> | undefined : T;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
valueOrSubQueryPropertyDescriptor<T extends JsonValue | undefined>(
|
|
161
|
-
value: T,
|
|
162
|
-
alsoRender: CoID<CoValue>[]
|
|
163
|
-
): T extends CoID<infer C>
|
|
164
|
-
? { get(): Queried<C> | undefined }
|
|
165
|
-
: { value: T } {
|
|
166
|
-
if (typeof value === "string" && value.startsWith("co_")) {
|
|
167
|
-
// TODO: when we track render dirty status, we can actually return the queried value without a getter if it's up to date
|
|
168
|
-
return {
|
|
169
|
-
get: () => this.query(value as CoID<CoValue>, alsoRender),
|
|
170
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
171
|
-
} as any;
|
|
172
|
-
} else {
|
|
173
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
174
|
-
return { value: value } as any;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
defineSubqueryPropertiesIn<
|
|
179
|
-
O extends object,
|
|
180
|
-
P extends {
|
|
181
|
-
[key: string]: { value: JsonValue | undefined; enumerable: boolean };
|
|
182
|
-
}
|
|
183
|
-
>(
|
|
184
|
-
obj: O,
|
|
185
|
-
subqueryProps: P,
|
|
186
|
-
alsoRender: CoID<CoValue>[]
|
|
187
|
-
): O & {
|
|
188
|
-
[Key in keyof P]: ValueOrSubQueried<P[Key]["value"]>;
|
|
189
|
-
} {
|
|
190
|
-
for (const [key, descriptor] of Object.entries(subqueryProps)) {
|
|
191
|
-
Object.defineProperty(
|
|
192
|
-
obj,
|
|
193
|
-
key,
|
|
194
|
-
{
|
|
195
|
-
...this.valueOrSubQueryPropertyDescriptor(descriptor.value, alsoRender),
|
|
196
|
-
enumerable: descriptor.enumerable,
|
|
197
|
-
}
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
return obj as O & {
|
|
201
|
-
[Key in keyof P]: ValueOrSubQueried<P[Key]["value"]>
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
getOrCreateExtension<T extends CoValue, O>(
|
|
206
|
-
valueID: CoID<T>,
|
|
207
|
-
extension: QueryExtension<T, O>
|
|
208
|
-
): O | undefined {
|
|
209
|
-
const id = `${valueID}_${extension.id}`;
|
|
210
|
-
let ext = this.extensions[id as keyof typeof this.extensions];
|
|
211
|
-
if (!ext) {
|
|
212
|
-
ext = {
|
|
213
|
-
lastOutput: undefined,
|
|
214
|
-
unsubscribe: extension.query(
|
|
215
|
-
this.node
|
|
216
|
-
.expectCoValueLoaded(valueID)
|
|
217
|
-
.getCurrentContent() as T,
|
|
218
|
-
this,
|
|
219
|
-
(output) => {
|
|
220
|
-
ext!.lastOutput = output;
|
|
221
|
-
this.values[valueID]?.render();
|
|
222
|
-
this.onUpdate();
|
|
223
|
-
}
|
|
224
|
-
),
|
|
225
|
-
};
|
|
226
|
-
this.extensions[id as keyof typeof this.extensions] = ext;
|
|
227
|
-
}
|
|
228
|
-
return ext.lastOutput as O | undefined;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
cleanup() {
|
|
232
|
-
for (const child of Object.values(this.values)) {
|
|
233
|
-
child.unsubscribe?.();
|
|
234
|
-
}
|
|
235
|
-
for (const extension of Object.values(this.extensions)) {
|
|
236
|
-
extension.unsubscribe();
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
export function query<T extends CoValue>(
|
|
242
|
-
id: CoID<T>,
|
|
243
|
-
node: LocalNode,
|
|
244
|
-
callback: (queried: Queried<T> | undefined) => void
|
|
245
|
-
): CleanupCallbackAndUsable {
|
|
246
|
-
// console.log("querying", id);
|
|
247
|
-
|
|
248
|
-
const context = new QueryContext(node, () => {
|
|
249
|
-
const rootQueried = context.values[id]?.lastQueried as
|
|
250
|
-
| Queried<T>
|
|
251
|
-
| undefined;
|
|
252
|
-
callback(rootQueried);
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
context.query(id, []);
|
|
256
|
-
|
|
257
|
-
const cleanup = function cleanup() {
|
|
258
|
-
context.cleanup();
|
|
259
|
-
} as CleanupCallbackAndUsable;
|
|
260
|
-
cleanup[Symbol.dispose] = cleanup;
|
|
261
|
-
|
|
262
|
-
return cleanup;
|
|
263
|
-
}
|
|
@@ -1,337 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BinaryCoStream,
|
|
3
|
-
CoList,
|
|
4
|
-
CoMap,
|
|
5
|
-
CoStream,
|
|
6
|
-
Group,
|
|
7
|
-
LocalNode,
|
|
8
|
-
cojsonReady,
|
|
9
|
-
} from "..";
|
|
10
|
-
|
|
11
|
-
beforeEach(async () => {
|
|
12
|
-
await cojsonReady;
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
test("Queries with maps work", async () => {
|
|
16
|
-
const { node, accountID } =
|
|
17
|
-
LocalNode.withNewlyCreatedAccount({name: "Hermes Puggington"});
|
|
18
|
-
|
|
19
|
-
const group = node.createGroup();
|
|
20
|
-
|
|
21
|
-
let map = group.createMap<
|
|
22
|
-
CoMap<{
|
|
23
|
-
hello: "world";
|
|
24
|
-
subMap: CoMap<{
|
|
25
|
-
hello: "world" | "moon" | "sun";
|
|
26
|
-
id: string;
|
|
27
|
-
}>["id"];
|
|
28
|
-
}>
|
|
29
|
-
>();
|
|
30
|
-
|
|
31
|
-
const done = new Promise<void>((resolve) => {
|
|
32
|
-
const unsubQuery = node.query(map.id, (queriedMap) => {
|
|
33
|
-
// console.log("update", update);
|
|
34
|
-
if (queriedMap) {
|
|
35
|
-
expect(queriedMap.type).toBe("comap");
|
|
36
|
-
expect(queriedMap.id).toEqual(map.id);
|
|
37
|
-
expect(queriedMap.core).toEqual(map.core);
|
|
38
|
-
expect(queriedMap.group).toBeInstanceOf(Group);
|
|
39
|
-
expect(queriedMap.group.id).toBe(group.id);
|
|
40
|
-
expect(queriedMap.meta).toBe(null);
|
|
41
|
-
expect(queriedMap.hello).toBe("world");
|
|
42
|
-
expect(Object.keys(queriedMap)).toEqual(["hello", "subMap"]);
|
|
43
|
-
if (queriedMap.edits.hello?.by?.profile?.name) {
|
|
44
|
-
expect(queriedMap.edits.hello.by.id).toEqual(accountID);
|
|
45
|
-
expect(queriedMap.edits.hello.by.profile.id).toEqual(
|
|
46
|
-
node.expectProfileLoaded(accountID).id
|
|
47
|
-
);
|
|
48
|
-
expect(queriedMap.edits.hello.by.profile.name).toEqual(
|
|
49
|
-
"Hermes Puggington"
|
|
50
|
-
);
|
|
51
|
-
expect(queriedMap.edits.hello.by.isMe).toBe(true);
|
|
52
|
-
expect(queriedMap.edits.hello.tx).toEqual(
|
|
53
|
-
map.lastEditAt("hello")!.tx
|
|
54
|
-
);
|
|
55
|
-
expect(queriedMap.edits.hello.at).toEqual(
|
|
56
|
-
new Date(map.lastEditAt("hello")!.at)
|
|
57
|
-
);
|
|
58
|
-
if (queriedMap.subMap) {
|
|
59
|
-
expect(queriedMap.subMap.type).toBe("comap");
|
|
60
|
-
expect(queriedMap.subMap.id).toEqual("foreignID");
|
|
61
|
-
expect(queriedMap.subMap.core).toEqual(subMap.core);
|
|
62
|
-
expect(queriedMap.subMap.group).toBeInstanceOf(Group);
|
|
63
|
-
expect(queriedMap.subMap.group.id).toBe(group.id);
|
|
64
|
-
expect(queriedMap.subMap.meta).toBe(null);
|
|
65
|
-
if (queriedMap.subMap.hello === "moon") {
|
|
66
|
-
// console.log("got to 'moon'");
|
|
67
|
-
queriedMap.subMap.set("hello", "sun");
|
|
68
|
-
} else if (
|
|
69
|
-
queriedMap.subMap.hello === "sun" &&
|
|
70
|
-
queriedMap.subMap.edits.hello?.by?.profile?.name ===
|
|
71
|
-
"Hermes Puggington"
|
|
72
|
-
) {
|
|
73
|
-
// console.log("final update", queriedMap);
|
|
74
|
-
resolve();
|
|
75
|
-
unsubQuery();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
map = map.set("hello", "world");
|
|
84
|
-
|
|
85
|
-
let subMap = group.createMap<
|
|
86
|
-
CoMap<{
|
|
87
|
-
hello: "world" | "moon" | "sun";
|
|
88
|
-
id: string;
|
|
89
|
-
}>
|
|
90
|
-
>();
|
|
91
|
-
|
|
92
|
-
map = map.set("subMap", subMap.id);
|
|
93
|
-
|
|
94
|
-
subMap = subMap.mutate((subMap) => {
|
|
95
|
-
subMap.set("hello", "world");
|
|
96
|
-
subMap.set("id", "foreignID");
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
subMap = subMap.set("hello", "moon");
|
|
100
|
-
|
|
101
|
-
await done;
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
test("Queries with lists work", () => {
|
|
105
|
-
const { node, accountID } =
|
|
106
|
-
LocalNode.withNewlyCreatedAccount({name: "Hermes Puggington"});
|
|
107
|
-
|
|
108
|
-
const group = node.createGroup();
|
|
109
|
-
|
|
110
|
-
let list = group.createList<CoList<string>>();
|
|
111
|
-
|
|
112
|
-
const done = new Promise<void>((resolve) => {
|
|
113
|
-
const unsubQuery = node.query(list.id, (queriedList) => {
|
|
114
|
-
if (queriedList) {
|
|
115
|
-
// console.log("update", queriedList, queriedList.edits);
|
|
116
|
-
expect(queriedList.type).toBe("colist");
|
|
117
|
-
expect(queriedList.id).toEqual(list.id);
|
|
118
|
-
expect(queriedList.core).toEqual(list.core);
|
|
119
|
-
expect(queriedList.group).toBeInstanceOf(Group);
|
|
120
|
-
expect(queriedList.group.id).toBe(group.id);
|
|
121
|
-
expect(queriedList.meta).toBe(null);
|
|
122
|
-
expect(queriedList[0]).toBe("hello");
|
|
123
|
-
expect(queriedList[1]).toBe("world");
|
|
124
|
-
expect(queriedList[2]).toBe("moon");
|
|
125
|
-
if (queriedList.edits[2]?.by?.profile?.name) {
|
|
126
|
-
expect(queriedList.edits[2].by.id).toEqual(accountID);
|
|
127
|
-
expect(queriedList.edits[2].by.profile.id).toEqual(
|
|
128
|
-
node.expectProfileLoaded(accountID).id
|
|
129
|
-
);
|
|
130
|
-
expect(queriedList.edits[2].by.profile.name).toEqual(
|
|
131
|
-
"Hermes Puggington"
|
|
132
|
-
);
|
|
133
|
-
expect(queriedList.edits[2].by.isMe).toBe(true);
|
|
134
|
-
expect(queriedList.edits[2].at).toBeInstanceOf(Date);
|
|
135
|
-
if (queriedList.length === 3) {
|
|
136
|
-
queriedList.append("sun");
|
|
137
|
-
} else if (
|
|
138
|
-
queriedList.length === 4 &&
|
|
139
|
-
queriedList.edits[3]?.by?.profile?.name ===
|
|
140
|
-
"Hermes Puggington"
|
|
141
|
-
) {
|
|
142
|
-
expect(queriedList[3]).toBe("sun");
|
|
143
|
-
// console.log("final update", queriedList);
|
|
144
|
-
resolve();
|
|
145
|
-
unsubQuery();
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
list = list.mutate((list) => {
|
|
153
|
-
list.append("hello");
|
|
154
|
-
list.append("world");
|
|
155
|
-
list.append("moon");
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
return done;
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
test("List of nested maps works", () => {
|
|
162
|
-
const { node } = LocalNode.withNewlyCreatedAccount({name: "Hermes Puggington"});
|
|
163
|
-
|
|
164
|
-
const group = node.createGroup();
|
|
165
|
-
|
|
166
|
-
let list = group.createList<CoList<CoMap<{ hello: "world" }>["id"]>>();
|
|
167
|
-
|
|
168
|
-
const done = new Promise<void>((resolve) => {
|
|
169
|
-
const unsubQuery = node.query(list.id, (queriedList) => {
|
|
170
|
-
if (queriedList && queriedList[0]) {
|
|
171
|
-
// console.log("update", queriedList);
|
|
172
|
-
expect(queriedList[0]).toMatchObject({
|
|
173
|
-
hello: "world",
|
|
174
|
-
id: list.get(0)!,
|
|
175
|
-
});
|
|
176
|
-
// console.log("final update", queriedList);
|
|
177
|
-
resolve();
|
|
178
|
-
unsubQuery();
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
list = list.append(
|
|
184
|
-
group.createMap<CoMap<{ hello: "world" }>>({
|
|
185
|
-
hello: "world",
|
|
186
|
-
}).id
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
return done;
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
test("Can call .map on a quieried coList", async () => {
|
|
193
|
-
const { node } = LocalNode.withNewlyCreatedAccount({name: "Hermes Puggington"});
|
|
194
|
-
|
|
195
|
-
const group = node.createGroup();
|
|
196
|
-
|
|
197
|
-
let list = group.createList<CoList<string>>();
|
|
198
|
-
|
|
199
|
-
const done = new Promise<void>((resolve) => {
|
|
200
|
-
const unsubQuery = node.query(list.id, (queriedList) => {
|
|
201
|
-
if (queriedList && queriedList[0]) {
|
|
202
|
-
// console.log("update", queriedList);
|
|
203
|
-
expect(queriedList.map((item) => item + "!!!")).toEqual([
|
|
204
|
-
"hello!!!",
|
|
205
|
-
"world!!!",
|
|
206
|
-
]);
|
|
207
|
-
// console.log("final update", queriedList);
|
|
208
|
-
resolve();
|
|
209
|
-
unsubQuery();
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
list = list.mutate((list) => {
|
|
215
|
-
list.append("hello");
|
|
216
|
-
list.append("world");
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
await done;
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
test("Queries with streams work", () => {
|
|
223
|
-
const { node, accountID } =
|
|
224
|
-
LocalNode.withNewlyCreatedAccount({name: "Hermes Puggington"});
|
|
225
|
-
|
|
226
|
-
const group = node.createGroup();
|
|
227
|
-
|
|
228
|
-
let stream = group.createStream<CoStream<string>>();
|
|
229
|
-
|
|
230
|
-
const done = new Promise<void>((resolve) => {
|
|
231
|
-
const unsubQuery = node.query(stream.id, (queriedStream) => {
|
|
232
|
-
if (queriedStream) {
|
|
233
|
-
// console.log("update", queriedStream);
|
|
234
|
-
if (queriedStream.me?.by?.profile?.name) {
|
|
235
|
-
expect(queriedStream.type).toBe("costream");
|
|
236
|
-
expect(queriedStream.id).toEqual(stream.id);
|
|
237
|
-
expect(queriedStream.core).toEqual(stream.core);
|
|
238
|
-
expect(queriedStream.group).toBeInstanceOf(Group);
|
|
239
|
-
expect(queriedStream.group.id).toBe(group.id);
|
|
240
|
-
expect(queriedStream.meta).toBe(null);
|
|
241
|
-
|
|
242
|
-
expect(queriedStream.perSession[node.currentSessionID].last).toEqual(
|
|
243
|
-
"world"
|
|
244
|
-
);
|
|
245
|
-
expect(queriedStream.perSession[node.currentSessionID].all[0].value).toEqual("hello");
|
|
246
|
-
expect(queriedStream.perSession[node.currentSessionID].all[0].at).toEqual(new Date(
|
|
247
|
-
stream.items[
|
|
248
|
-
node.currentSessionID
|
|
249
|
-
][0].madeAt
|
|
250
|
-
));
|
|
251
|
-
expect(queriedStream.perSession[node.currentSessionID].all[1].value).toEqual("world");
|
|
252
|
-
expect(queriedStream.perSession[node.currentSessionID].all[1].at).toEqual(new Date(
|
|
253
|
-
stream.items[
|
|
254
|
-
node.currentSessionID
|
|
255
|
-
][1].madeAt
|
|
256
|
-
));
|
|
257
|
-
expect(queriedStream.perSession[node.currentSessionID].by?.id).toEqual(accountID);
|
|
258
|
-
expect(queriedStream.perSession[node.currentSessionID].by?.profile?.id).toEqual(
|
|
259
|
-
node.expectProfileLoaded(accountID).id
|
|
260
|
-
);
|
|
261
|
-
expect(queriedStream.perSession[node.currentSessionID].by?.profile?.name).toEqual(
|
|
262
|
-
"Hermes Puggington"
|
|
263
|
-
);
|
|
264
|
-
expect(queriedStream.perSession[node.currentSessionID].by?.isMe).toBe(true);
|
|
265
|
-
expect(queriedStream.perSession[node.currentSessionID].at).toBeInstanceOf(Date);
|
|
266
|
-
|
|
267
|
-
expect(queriedStream.perAccount[accountID].last).toEqual(
|
|
268
|
-
"world"
|
|
269
|
-
);
|
|
270
|
-
expect(queriedStream.perAccount[accountID].all[0].value).toEqual("hello");
|
|
271
|
-
expect(queriedStream.perAccount[accountID].all[0].at).toEqual(new Date(
|
|
272
|
-
stream.items[
|
|
273
|
-
node.currentSessionID
|
|
274
|
-
][0].madeAt
|
|
275
|
-
));
|
|
276
|
-
expect(queriedStream.perAccount[accountID].all[1].value).toEqual("world");
|
|
277
|
-
expect(queriedStream.perAccount[accountID].all[1].at).toEqual(new Date(
|
|
278
|
-
stream.items[
|
|
279
|
-
node.currentSessionID
|
|
280
|
-
][1].madeAt
|
|
281
|
-
));
|
|
282
|
-
expect(queriedStream.perAccount[accountID].by?.id).toEqual(accountID);
|
|
283
|
-
expect(queriedStream.perAccount[accountID].by?.profile?.id).toEqual(
|
|
284
|
-
node.expectProfileLoaded(accountID).id
|
|
285
|
-
);
|
|
286
|
-
expect(queriedStream.perAccount[accountID].by?.profile?.name).toEqual(
|
|
287
|
-
"Hermes Puggington"
|
|
288
|
-
);
|
|
289
|
-
expect(queriedStream.perAccount[accountID].by?.isMe).toBe(true);
|
|
290
|
-
expect(queriedStream.perAccount[accountID].at).toBeInstanceOf(Date);
|
|
291
|
-
|
|
292
|
-
expect(queriedStream.me).toEqual(queriedStream.perAccount[accountID]);
|
|
293
|
-
// console.log("final update", queriedStream);
|
|
294
|
-
resolve();
|
|
295
|
-
unsubQuery();
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
stream = stream.push("hello");
|
|
302
|
-
stream = stream.push("world");
|
|
303
|
-
|
|
304
|
-
return done;
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
test("Streams of nested maps work", () => {
|
|
308
|
-
const { node } = LocalNode.withNewlyCreatedAccount({name:"Hermes Puggington"});
|
|
309
|
-
|
|
310
|
-
const group = node.createGroup();
|
|
311
|
-
|
|
312
|
-
let stream =
|
|
313
|
-
group.createStream<CoStream<CoMap<{ hello: "world" }>["id"]>>();
|
|
314
|
-
|
|
315
|
-
const done = new Promise<void>((resolve) => {
|
|
316
|
-
const unsubQuery = node.query(stream.id, (queriedStream) => {
|
|
317
|
-
if (queriedStream && queriedStream.me?.last) {
|
|
318
|
-
// console.log("update", queriedList);
|
|
319
|
-
expect(queriedStream.me.last).toMatchObject({
|
|
320
|
-
hello: "world",
|
|
321
|
-
id: map.id,
|
|
322
|
-
});
|
|
323
|
-
// console.log("final update", queriedList);
|
|
324
|
-
resolve();
|
|
325
|
-
unsubQuery();
|
|
326
|
-
}
|
|
327
|
-
});
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
const map = group.createMap<CoMap<{ hello: "world" }>>({
|
|
331
|
-
hello: "world",
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
stream = stream.push(map.id);
|
|
335
|
-
|
|
336
|
-
return done;
|
|
337
|
-
});
|