jazz-tools 0.9.1 → 0.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +6 -0
- package/dist/{chunk-7LENDMTN.js → chunk-YD32FKHW.js} +732 -281
- package/dist/chunk-YD32FKHW.js.map +1 -0
- package/dist/index.native.js +7 -1
- package/dist/index.native.js.map +1 -1
- package/dist/index.web.js +7 -1
- package/dist/index.web.js.map +1 -1
- package/dist/testing.js +10 -2
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
- package/src/coValues/account.ts +41 -3
- package/src/coValues/coFeed.ts +112 -20
- package/src/coValues/coList.ts +47 -15
- package/src/coValues/coMap.ts +51 -16
- package/src/coValues/coPlainText.ts +243 -0
- package/src/coValues/coRichText.ts +475 -0
- package/src/coValues/deepLoading.ts +11 -2
- package/src/coValues/group.ts +49 -17
- package/src/coValues/inbox.ts +7 -2
- package/src/coValues/interfaces.ts +112 -9
- package/src/exports.ts +12 -8
- package/src/implementation/activeAccountContext.ts +33 -0
- package/src/implementation/createContext.ts +8 -0
- package/src/testing.ts +9 -0
- package/src/tests/account.test.ts +1 -0
- package/src/tests/coFeed.test.ts +13 -0
- package/src/tests/coPlainText.test.ts +33 -0
- package/src/tests/coRichText.test.ts +57 -0
- package/src/tests/interfaces.test.ts +90 -0
- package/dist/chunk-7LENDMTN.js.map +0 -1
@@ -0,0 +1,475 @@
|
|
1
|
+
import { co } from "../internal.js";
|
2
|
+
import type { Account } from "./account.js";
|
3
|
+
import { CoList } from "./coList.js";
|
4
|
+
import { CoMap, type CoMapInit } from "./coMap.js";
|
5
|
+
import { CoPlainText, type TextPos } from "./coPlainText.js";
|
6
|
+
import type { Group } from "./group.js";
|
7
|
+
|
8
|
+
/**
|
9
|
+
* Base class for text annotations and formatting marks.
|
10
|
+
* Represents a mark with start and end positions in text.
|
11
|
+
*/
|
12
|
+
export class Mark extends CoMap {
|
13
|
+
startAfter = co.json<TextPos | null>();
|
14
|
+
startBefore = co.json<TextPos>();
|
15
|
+
endAfter = co.json<TextPos>();
|
16
|
+
endBefore = co.json<TextPos | null>();
|
17
|
+
tag = co.string;
|
18
|
+
}
|
19
|
+
|
20
|
+
/**
|
21
|
+
* A mark with resolved numeric positions in text.
|
22
|
+
* Contains both position information and reference to the source mark.
|
23
|
+
* @template R Type extending Mark, defaults to Mark
|
24
|
+
*/
|
25
|
+
export type ResolvedMark<R extends Mark = Mark> = {
|
26
|
+
startAfter: number;
|
27
|
+
startBefore: number;
|
28
|
+
endAfter: number;
|
29
|
+
endBefore: number;
|
30
|
+
sourceMark: R;
|
31
|
+
};
|
32
|
+
|
33
|
+
/**
|
34
|
+
* A mark that has been resolved and diffused with certainty information.
|
35
|
+
* Includes start/end positions and indication of boundary certainty.
|
36
|
+
* @template R Type extending Mark, defaults to Mark
|
37
|
+
*/
|
38
|
+
export type ResolvedAndDiffusedMark<R extends Mark = Mark> = {
|
39
|
+
start: number;
|
40
|
+
end: number;
|
41
|
+
side: "uncertainStart" | "certainMiddle" | "uncertainEnd";
|
42
|
+
sourceMark: R;
|
43
|
+
};
|
44
|
+
|
45
|
+
/**
|
46
|
+
* Defines how marks should be focused when resolving positions.
|
47
|
+
* - 'far': Positions marks at furthest valid positions
|
48
|
+
* - 'close': Positions marks at nearest valid positions
|
49
|
+
* - 'closestWhitespace': Positions marks at nearest whitespace
|
50
|
+
*/
|
51
|
+
export type FocusBias = "far" | "close" | "closestWhitespace";
|
52
|
+
|
53
|
+
/**
|
54
|
+
* A mark that has been resolved and focused to specific positions.
|
55
|
+
* Contains simplified position information and reference to source mark.
|
56
|
+
* @template R Type extending Mark, defaults to Mark
|
57
|
+
*/
|
58
|
+
export type ResolvedAndFocusedMark<R extends Mark = Mark> = {
|
59
|
+
start: number;
|
60
|
+
end: number;
|
61
|
+
sourceMark: R;
|
62
|
+
};
|
63
|
+
|
64
|
+
/**
|
65
|
+
* Main class for handling rich text content with marks.
|
66
|
+
* Combines plain text with a list of marks for formatting and annotations.
|
67
|
+
* Provides methods for text manipulation, mark insertion, and tree conversion.
|
68
|
+
*/
|
69
|
+
export class CoRichText extends CoMap {
|
70
|
+
text = co.ref(CoPlainText);
|
71
|
+
marks = co.ref(CoList.Of(co.ref(Mark)));
|
72
|
+
|
73
|
+
/**
|
74
|
+
* Create a CoRichText from plain text.
|
75
|
+
*/
|
76
|
+
static createFromPlainText(
|
77
|
+
text: string,
|
78
|
+
options: { owner: Account | Group },
|
79
|
+
) {
|
80
|
+
return this.create(
|
81
|
+
{
|
82
|
+
text: CoPlainText.create(text, { owner: options.owner }),
|
83
|
+
marks: CoList.Of(co.ref(Mark)).create([], {
|
84
|
+
owner: options.owner,
|
85
|
+
}),
|
86
|
+
},
|
87
|
+
{ owner: options.owner },
|
88
|
+
);
|
89
|
+
}
|
90
|
+
|
91
|
+
/**
|
92
|
+
* Create a CoRichText from plain text and a mark.
|
93
|
+
*/
|
94
|
+
static createFromPlainTextAndMark<
|
95
|
+
MarkClass extends {
|
96
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
97
|
+
new (...args: any[]): Mark;
|
98
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
99
|
+
create(init: any, options: { owner: Account | Group }): Mark;
|
100
|
+
},
|
101
|
+
>(
|
102
|
+
text: string,
|
103
|
+
WrapIn: MarkClass,
|
104
|
+
extraArgs: Omit<
|
105
|
+
CoMapInit<InstanceType<MarkClass>>,
|
106
|
+
"startAfter" | "startBefore" | "endAfter" | "endBefore"
|
107
|
+
>,
|
108
|
+
options: { owner: Account | Group },
|
109
|
+
) {
|
110
|
+
const richtext = this.createFromPlainText(text, options);
|
111
|
+
|
112
|
+
richtext.insertMark(0, text.length, WrapIn, extraArgs);
|
113
|
+
|
114
|
+
return richtext;
|
115
|
+
}
|
116
|
+
|
117
|
+
/**
|
118
|
+
* Insert text at a specific index.
|
119
|
+
*/
|
120
|
+
insertAfter(idx: number, text: string) {
|
121
|
+
if (!this.text)
|
122
|
+
throw new Error("Cannot insert into a CoRichText without loaded text");
|
123
|
+
this.text.insertAfter(idx, text);
|
124
|
+
}
|
125
|
+
|
126
|
+
/**
|
127
|
+
* Delete a range of text.
|
128
|
+
*/
|
129
|
+
deleteRange(range: { from: number; to: number }) {
|
130
|
+
if (!this.text)
|
131
|
+
throw new Error("Cannot delete from a CoRichText without loaded text");
|
132
|
+
this.text.deleteRange(range);
|
133
|
+
}
|
134
|
+
|
135
|
+
/**
|
136
|
+
* Get the position of a specific index.
|
137
|
+
*/
|
138
|
+
posBefore(idx: number): TextPos | undefined {
|
139
|
+
if (!this.text)
|
140
|
+
throw new Error(
|
141
|
+
"Cannot get posBefore in a CoRichText without loaded text",
|
142
|
+
);
|
143
|
+
return this.text.posBefore(idx);
|
144
|
+
}
|
145
|
+
|
146
|
+
/**
|
147
|
+
* Get the position of a specific index.
|
148
|
+
*/
|
149
|
+
posAfter(idx: number): TextPos | undefined {
|
150
|
+
if (!this.text)
|
151
|
+
throw new Error(
|
152
|
+
"Cannot get posAfter in a CoRichText without loaded text",
|
153
|
+
);
|
154
|
+
return this.text.posAfter(idx);
|
155
|
+
}
|
156
|
+
|
157
|
+
/**
|
158
|
+
* Get the index of a specific position.
|
159
|
+
*/
|
160
|
+
idxBefore(pos: TextPos): number | undefined {
|
161
|
+
if (!this.text)
|
162
|
+
throw new Error(
|
163
|
+
"Cannot get idxBefore in a CoRichText without loaded text",
|
164
|
+
);
|
165
|
+
return this.text.idxBefore(pos);
|
166
|
+
}
|
167
|
+
|
168
|
+
/**
|
169
|
+
* Get the index of a specific position.
|
170
|
+
*/
|
171
|
+
idxAfter(pos: TextPos): number | undefined {
|
172
|
+
if (!this.text)
|
173
|
+
throw new Error(
|
174
|
+
"Cannot get idxAfter in a CoRichText without loaded text",
|
175
|
+
);
|
176
|
+
return this.text.idxAfter(pos);
|
177
|
+
}
|
178
|
+
|
179
|
+
/**
|
180
|
+
* Insert a mark at a specific range.
|
181
|
+
*/
|
182
|
+
insertMark<
|
183
|
+
MarkClass extends {
|
184
|
+
new (...args: any[]): Mark;
|
185
|
+
create(init: any, options: { owner: Account | Group }): Mark;
|
186
|
+
},
|
187
|
+
>(
|
188
|
+
start: number,
|
189
|
+
end: number,
|
190
|
+
RangeClass: MarkClass,
|
191
|
+
extraArgs: Omit<
|
192
|
+
CoMapInit<InstanceType<MarkClass>>,
|
193
|
+
"startAfter" | "startBefore" | "endAfter" | "endBefore"
|
194
|
+
>,
|
195
|
+
options?: { markOwner?: Account | Group },
|
196
|
+
) {
|
197
|
+
if (!this.marks) {
|
198
|
+
throw new Error("Cannot insert a range without loaded ranges");
|
199
|
+
}
|
200
|
+
const range = RangeClass.create(
|
201
|
+
{
|
202
|
+
...extraArgs,
|
203
|
+
startAfter: this.posBefore(start),
|
204
|
+
startBefore: this.posAfter(start),
|
205
|
+
endAfter: this.posBefore(end),
|
206
|
+
endBefore: this.posAfter(end),
|
207
|
+
},
|
208
|
+
{ owner: options?.markOwner || this._owner },
|
209
|
+
);
|
210
|
+
this.marks.push(range);
|
211
|
+
}
|
212
|
+
|
213
|
+
/**
|
214
|
+
* Resolve the positions of all marks.
|
215
|
+
*/
|
216
|
+
resolveMarks(): ResolvedMark[] {
|
217
|
+
if (!this.text || !this.marks) {
|
218
|
+
throw new Error("Cannot resolve ranges without loaded text and ranges");
|
219
|
+
}
|
220
|
+
const ranges = this.marks.flatMap((mark) => {
|
221
|
+
if (!mark) return [];
|
222
|
+
const startBefore = this.idxAfter(mark.startBefore);
|
223
|
+
const endAfter = this.idxAfter(mark.endAfter);
|
224
|
+
if (startBefore === undefined || endAfter === undefined) {
|
225
|
+
return [];
|
226
|
+
}
|
227
|
+
const startAfter = mark.startAfter
|
228
|
+
? this.idxAfter(mark.startAfter)
|
229
|
+
: startBefore - 1;
|
230
|
+
const endBefore = mark.endBefore
|
231
|
+
? this.idxAfter(mark.endBefore)
|
232
|
+
: endAfter + 1;
|
233
|
+
if (startAfter === undefined || endBefore === undefined) {
|
234
|
+
return [];
|
235
|
+
}
|
236
|
+
return [
|
237
|
+
{
|
238
|
+
sourceMark: mark,
|
239
|
+
startAfter,
|
240
|
+
startBefore,
|
241
|
+
endAfter,
|
242
|
+
endBefore,
|
243
|
+
tag: mark.tag,
|
244
|
+
from: mark,
|
245
|
+
},
|
246
|
+
];
|
247
|
+
});
|
248
|
+
return ranges;
|
249
|
+
}
|
250
|
+
|
251
|
+
/**
|
252
|
+
* Resolve and diffuse the positions of all marks.
|
253
|
+
*/
|
254
|
+
resolveAndDiffuseMarks(): ResolvedAndDiffusedMark[] {
|
255
|
+
return this.resolveMarks().flatMap((range) => [
|
256
|
+
...(range.startAfter < range.startBefore - 1
|
257
|
+
? [
|
258
|
+
{
|
259
|
+
start: range.startAfter,
|
260
|
+
end: range.startBefore - 1,
|
261
|
+
side: "uncertainStart" as const,
|
262
|
+
sourceMark: range.sourceMark,
|
263
|
+
},
|
264
|
+
]
|
265
|
+
: []),
|
266
|
+
{
|
267
|
+
start: range.startBefore - 1,
|
268
|
+
end: range.endAfter + 1,
|
269
|
+
side: "certainMiddle" as const,
|
270
|
+
sourceMark: range.sourceMark,
|
271
|
+
},
|
272
|
+
...(range.endAfter + 1 < range.endBefore
|
273
|
+
? [
|
274
|
+
{
|
275
|
+
start: range.endAfter + 1,
|
276
|
+
end: range.endBefore,
|
277
|
+
side: "uncertainEnd" as const,
|
278
|
+
sourceMark: range.sourceMark,
|
279
|
+
},
|
280
|
+
]
|
281
|
+
: []),
|
282
|
+
]);
|
283
|
+
}
|
284
|
+
|
285
|
+
/**
|
286
|
+
* Resolve, diffuse, and focus the positions of all marks.
|
287
|
+
*/
|
288
|
+
resolveAndDiffuseAndFocusMarks(): ResolvedAndFocusedMark[] {
|
289
|
+
// for now we only keep the certainMiddle ranges
|
290
|
+
return this.resolveAndDiffuseMarks().filter(
|
291
|
+
(range) => range.side === "certainMiddle",
|
292
|
+
);
|
293
|
+
}
|
294
|
+
|
295
|
+
/**
|
296
|
+
* Convert a CoRichText to a tree structure useful for client libraries.
|
297
|
+
*/
|
298
|
+
toTree(tagPrecedence: string[]): TreeNode {
|
299
|
+
const ranges = this.resolveAndDiffuseAndFocusMarks();
|
300
|
+
|
301
|
+
// convert a bunch of (potentially overlapping) ranges into a tree
|
302
|
+
// - make sure we include all text in leaves, even if it's not covered by a range
|
303
|
+
// - we split overlapping ranges in a way where the higher precedence (tag earlier in tagPrecedence)
|
304
|
+
// stays intact and the lower precende tag is split into two ranges, one inside and one outside the higher precedence range
|
305
|
+
|
306
|
+
const text = this.text?.toString() || "";
|
307
|
+
|
308
|
+
let currentNodes: (TreeLeaf | TreeNode)[] = [
|
309
|
+
{
|
310
|
+
type: "leaf",
|
311
|
+
start: 0,
|
312
|
+
end: text.length,
|
313
|
+
},
|
314
|
+
];
|
315
|
+
|
316
|
+
const rangesSortedLowToHighPrecedence = ranges.sort((a, b) => {
|
317
|
+
const aPrecedence = tagPrecedence.indexOf(a.sourceMark.tag);
|
318
|
+
const bPrecedence = tagPrecedence.indexOf(b.sourceMark.tag);
|
319
|
+
return bPrecedence - aPrecedence;
|
320
|
+
});
|
321
|
+
|
322
|
+
// for each range, split the current nodes where necessary (no matter if leaf or already a node), wrapping the resulting "inside" parts in a node with the range's tag
|
323
|
+
for (const range of rangesSortedLowToHighPrecedence) {
|
324
|
+
// console.log("currentNodes", currentNodes);
|
325
|
+
const newNodes = currentNodes.flatMap((node) => {
|
326
|
+
const [before, inOrAfter] = splitNode(node, range.start);
|
327
|
+
const [inside, after] = inOrAfter
|
328
|
+
? splitNode(inOrAfter, range.end)
|
329
|
+
: [undefined, undefined];
|
330
|
+
|
331
|
+
// console.log("split", range.start, range.end, {
|
332
|
+
// before,
|
333
|
+
// inside,
|
334
|
+
// after,
|
335
|
+
// });
|
336
|
+
|
337
|
+
// TODO: also split children
|
338
|
+
|
339
|
+
return [
|
340
|
+
...(before ? [before] : []),
|
341
|
+
...(inside
|
342
|
+
? [
|
343
|
+
{
|
344
|
+
type: "node" as const,
|
345
|
+
tag: range.sourceMark.tag,
|
346
|
+
start: inside.start,
|
347
|
+
end: inside.end,
|
348
|
+
children: [inside],
|
349
|
+
},
|
350
|
+
]
|
351
|
+
: []),
|
352
|
+
...(after ? [after] : []),
|
353
|
+
];
|
354
|
+
});
|
355
|
+
|
356
|
+
currentNodes = newNodes;
|
357
|
+
}
|
358
|
+
|
359
|
+
return {
|
360
|
+
type: "node",
|
361
|
+
tag: "root",
|
362
|
+
start: 0,
|
363
|
+
end: text.length,
|
364
|
+
children: currentNodes,
|
365
|
+
};
|
366
|
+
}
|
367
|
+
|
368
|
+
/**
|
369
|
+
* Convert a CoRichText to plain text.
|
370
|
+
*/
|
371
|
+
toString() {
|
372
|
+
if (!this.text) return "";
|
373
|
+
return this.text.toString();
|
374
|
+
}
|
375
|
+
}
|
376
|
+
|
377
|
+
/**
|
378
|
+
* Represents a leaf node in the rich text tree structure.
|
379
|
+
* Contains plain text without any marks.
|
380
|
+
*/
|
381
|
+
export type TreeLeaf = {
|
382
|
+
type: "leaf";
|
383
|
+
start: number;
|
384
|
+
end: number;
|
385
|
+
};
|
386
|
+
|
387
|
+
/**
|
388
|
+
* Represents a node in the rich text tree structure.
|
389
|
+
* Can contain other nodes or leaves, and includes formatting information.
|
390
|
+
*/
|
391
|
+
export type TreeNode = {
|
392
|
+
type: "node";
|
393
|
+
tag: string;
|
394
|
+
start: number;
|
395
|
+
end: number;
|
396
|
+
range?: ResolvedAndFocusedMark;
|
397
|
+
children: (TreeNode | TreeLeaf)[];
|
398
|
+
};
|
399
|
+
|
400
|
+
/**
|
401
|
+
* Split a node at a specific index. So that the node is split into two parts, one before the index, and one after the index.
|
402
|
+
*/
|
403
|
+
function splitNode(
|
404
|
+
node: TreeNode | TreeLeaf,
|
405
|
+
at: number,
|
406
|
+
): [TreeNode | TreeLeaf | undefined, TreeNode | TreeLeaf | undefined] {
|
407
|
+
if (node.type === "leaf") {
|
408
|
+
return [
|
409
|
+
at > node.start
|
410
|
+
? {
|
411
|
+
type: "leaf",
|
412
|
+
start: node.start,
|
413
|
+
end: Math.min(at, node.end),
|
414
|
+
}
|
415
|
+
: undefined,
|
416
|
+
at < node.end
|
417
|
+
? {
|
418
|
+
type: "leaf",
|
419
|
+
start: Math.max(at, node.start),
|
420
|
+
end: node.end,
|
421
|
+
}
|
422
|
+
: undefined,
|
423
|
+
];
|
424
|
+
} else {
|
425
|
+
const children = node.children;
|
426
|
+
return [
|
427
|
+
at > node.start
|
428
|
+
? {
|
429
|
+
type: "node",
|
430
|
+
tag: node.tag,
|
431
|
+
start: node.start,
|
432
|
+
end: Math.min(at, node.end),
|
433
|
+
children: children
|
434
|
+
.map((child) => splitNode(child, at)[0])
|
435
|
+
.filter((c): c is Exclude<typeof c, undefined> => !!c),
|
436
|
+
}
|
437
|
+
: undefined,
|
438
|
+
at < node.end
|
439
|
+
? {
|
440
|
+
type: "node",
|
441
|
+
tag: node.tag,
|
442
|
+
start: Math.max(at, node.start),
|
443
|
+
end: node.end,
|
444
|
+
children: children
|
445
|
+
.map((child) => splitNode(child, at)[1])
|
446
|
+
.filter((c): c is Exclude<typeof c, undefined> => !!c),
|
447
|
+
}
|
448
|
+
: undefined,
|
449
|
+
];
|
450
|
+
}
|
451
|
+
}
|
452
|
+
|
453
|
+
/**
|
454
|
+
* Collection of predefined mark types for common text formatting.
|
455
|
+
* Includes marks for headings, paragraphs, links, and text styling.
|
456
|
+
*/
|
457
|
+
export const Marks = {
|
458
|
+
Heading: class Heading extends Mark {
|
459
|
+
tag = co.literal("heading");
|
460
|
+
level = co.number;
|
461
|
+
},
|
462
|
+
Paragraph: class Paragraph extends Mark {
|
463
|
+
tag = co.literal("paragraph");
|
464
|
+
},
|
465
|
+
Link: class Link extends Mark {
|
466
|
+
tag = co.literal("link");
|
467
|
+
url = co.string;
|
468
|
+
},
|
469
|
+
Strong: class Strong extends Mark {
|
470
|
+
tag = co.literal("strong");
|
471
|
+
},
|
472
|
+
Em: class Italic extends Mark {
|
473
|
+
tag = co.literal("em");
|
474
|
+
},
|
475
|
+
};
|
@@ -67,7 +67,10 @@ export function fulfillsDepth(depth: any, value: CoValue): boolean {
|
|
67
67
|
.optional,
|
68
68
|
);
|
69
69
|
}
|
70
|
-
} else if (
|
70
|
+
} else if (
|
71
|
+
value._type === "BinaryCoStream" ||
|
72
|
+
value._type === "CoPlainText"
|
73
|
+
) {
|
71
74
|
return true;
|
72
75
|
} else {
|
73
76
|
console.error(value);
|
@@ -204,4 +207,10 @@ export type DeeplyLoaded<
|
|
204
207
|
},
|
205
208
|
]
|
206
209
|
? V
|
207
|
-
:
|
210
|
+
: [V] extends [
|
211
|
+
{
|
212
|
+
_type: "CoPlainText";
|
213
|
+
},
|
214
|
+
]
|
215
|
+
? V
|
216
|
+
: never;
|
package/src/coValues/group.ts
CHANGED
@@ -13,9 +13,9 @@ import {
|
|
13
13
|
MembersSym,
|
14
14
|
Ref,
|
15
15
|
ensureCoValueLoaded,
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
loadCoValueWithoutMe,
|
17
|
+
parseGroupCreateOptions,
|
18
|
+
subscribeToCoValueWithoutMe,
|
19
19
|
subscribeToExistingCoValue,
|
20
20
|
} from "../internal.js";
|
21
21
|
import { AccountAndGroupProxyHandler, isControlledAccount } from "./account.js";
|
@@ -124,9 +124,9 @@ export class Group extends CoValueBase implements CoValue {
|
|
124
124
|
|
125
125
|
static create<G extends Group>(
|
126
126
|
this: CoValueClass<G>,
|
127
|
-
options
|
127
|
+
options?: { owner: Account } | Account,
|
128
128
|
) {
|
129
|
-
return new this(
|
129
|
+
return new this(parseGroupCreateOptions(options));
|
130
130
|
}
|
131
131
|
|
132
132
|
myRole(): Role | undefined {
|
@@ -179,24 +179,56 @@ export class Group extends CoValueBase implements CoValue {
|
|
179
179
|
}
|
180
180
|
|
181
181
|
/** @category Subscription & Loading */
|
182
|
-
static load<
|
183
|
-
this: CoValueClass<
|
184
|
-
id: ID<
|
182
|
+
static load<C extends Group, Depth>(
|
183
|
+
this: CoValueClass<C>,
|
184
|
+
id: ID<C>,
|
185
|
+
depth: Depth & DepthsIn<C>,
|
186
|
+
): Promise<DeeplyLoaded<C, Depth> | undefined>;
|
187
|
+
static load<C extends Group, Depth>(
|
188
|
+
this: CoValueClass<C>,
|
189
|
+
id: ID<C>,
|
185
190
|
as: Account,
|
186
|
-
depth: Depth & DepthsIn<
|
187
|
-
): Promise<DeeplyLoaded<
|
188
|
-
|
191
|
+
depth: Depth & DepthsIn<C>,
|
192
|
+
): Promise<DeeplyLoaded<C, Depth> | undefined>;
|
193
|
+
static load<C extends Group, Depth>(
|
194
|
+
this: CoValueClass<C>,
|
195
|
+
id: ID<C>,
|
196
|
+
asOrDepth: Account | (Depth & DepthsIn<C>),
|
197
|
+
depth?: Depth & DepthsIn<C>,
|
198
|
+
): Promise<DeeplyLoaded<C, Depth> | undefined> {
|
199
|
+
return loadCoValueWithoutMe(this, id, asOrDepth, depth);
|
189
200
|
}
|
190
201
|
|
191
202
|
/** @category Subscription & Loading */
|
192
|
-
static subscribe<
|
193
|
-
this: CoValueClass<
|
194
|
-
id: ID<
|
203
|
+
static subscribe<C extends Group, Depth>(
|
204
|
+
this: CoValueClass<C>,
|
205
|
+
id: ID<C>,
|
206
|
+
depth: Depth & DepthsIn<C>,
|
207
|
+
listener: (value: DeeplyLoaded<C, Depth>) => void,
|
208
|
+
): () => void;
|
209
|
+
static subscribe<C extends Group, Depth>(
|
210
|
+
this: CoValueClass<C>,
|
211
|
+
id: ID<C>,
|
195
212
|
as: Account,
|
196
|
-
depth: Depth & DepthsIn<
|
197
|
-
listener: (value: DeeplyLoaded<
|
213
|
+
depth: Depth & DepthsIn<C>,
|
214
|
+
listener: (value: DeeplyLoaded<C, Depth>) => void,
|
215
|
+
): () => void;
|
216
|
+
static subscribe<C extends Group, Depth>(
|
217
|
+
this: CoValueClass<C>,
|
218
|
+
id: ID<C>,
|
219
|
+
asOrDepth: Account | (Depth & DepthsIn<C>),
|
220
|
+
depthOrListener:
|
221
|
+
| (Depth & DepthsIn<C>)
|
222
|
+
| ((value: DeeplyLoaded<C, Depth>) => void),
|
223
|
+
listener?: (value: DeeplyLoaded<C, Depth>) => void,
|
198
224
|
): () => void {
|
199
|
-
return
|
225
|
+
return subscribeToCoValueWithoutMe<C, Depth>(
|
226
|
+
this,
|
227
|
+
id,
|
228
|
+
asOrDepth,
|
229
|
+
depthOrListener,
|
230
|
+
listener,
|
231
|
+
);
|
200
232
|
}
|
201
233
|
|
202
234
|
/** @category Subscription & Loading */
|
package/src/coValues/inbox.ts
CHANGED
@@ -7,6 +7,7 @@ import {
|
|
7
7
|
SessionID,
|
8
8
|
} from "cojson";
|
9
9
|
import { CoStreamItem, RawCoStream } from "cojson";
|
10
|
+
import { activeAccountContext } from "../implementation/activeAccountContext.js";
|
10
11
|
import { type Account } from "./account.js";
|
11
12
|
import { CoValue, CoValueClass, ID, loadCoValue } from "./interfaces.js";
|
12
13
|
|
@@ -312,7 +313,9 @@ export class InboxSender<I extends CoValue, O extends CoValue | undefined> {
|
|
312
313
|
static async load<
|
313
314
|
I extends CoValue,
|
314
315
|
O extends CoValue | undefined = undefined,
|
315
|
-
>(inboxOwnerID: ID<Account>, currentAccount
|
316
|
+
>(inboxOwnerID: ID<Account>, currentAccount?: Account) {
|
317
|
+
currentAccount ||= activeAccountContext.get();
|
318
|
+
|
316
319
|
const node = currentAccount._raw.core.node;
|
317
320
|
|
318
321
|
const inboxOwnerRaw = await node.load(
|
@@ -347,7 +350,9 @@ export class InboxSender<I extends CoValue, O extends CoValue | undefined> {
|
|
347
350
|
}
|
348
351
|
}
|
349
352
|
|
350
|
-
async function acceptInvite(invite: string, account
|
353
|
+
async function acceptInvite(invite: string, account?: Account) {
|
354
|
+
account ||= activeAccountContext.get();
|
355
|
+
|
351
356
|
const id = invite.slice(0, invite.indexOf("/")) as CoID<MessagesStream>;
|
352
357
|
|
353
358
|
const inviteSecret = invite.slice(invite.indexOf("/") + 1) as InviteSecret;
|