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
package/src/coValues/coMap.ts
CHANGED
@@ -7,6 +7,7 @@ import {
|
|
7
7
|
type RawCoMap,
|
8
8
|
cojsonInternals,
|
9
9
|
} from "cojson";
|
10
|
+
import { activeAccountContext } from "../implementation/activeAccountContext.js";
|
10
11
|
import type {
|
11
12
|
AnonymousJazzAgent,
|
12
13
|
CoValue,
|
@@ -28,10 +29,10 @@ import {
|
|
28
29
|
ensureCoValueLoaded,
|
29
30
|
inspect,
|
30
31
|
isRefEncoded,
|
31
|
-
|
32
|
+
loadCoValueWithoutMe,
|
32
33
|
makeRefs,
|
33
34
|
parseCoValueCreateOptions,
|
34
|
-
|
35
|
+
subscribeToCoValueWithoutMe,
|
35
36
|
subscribeToExistingCoValue,
|
36
37
|
subscriptionsScopes,
|
37
38
|
} from "../internal.js";
|
@@ -274,7 +275,7 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
274
275
|
static create<M extends CoMap>(
|
275
276
|
this: CoValueClass<M>,
|
276
277
|
init: Simplify<CoMapInit<M>>,
|
277
|
-
options
|
278
|
+
options?:
|
278
279
|
| {
|
279
280
|
owner: Account | Group;
|
280
281
|
unique?: CoValueUniqueness["uniqueness"];
|
@@ -432,13 +433,24 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
432
433
|
*
|
433
434
|
* @category Subscription & Loading
|
434
435
|
*/
|
435
|
-
static load<
|
436
|
-
this: CoValueClass<
|
437
|
-
id: ID<
|
436
|
+
static load<C extends CoMap, Depth>(
|
437
|
+
this: CoValueClass<C>,
|
438
|
+
id: ID<C>,
|
439
|
+
depth: Depth & DepthsIn<C>,
|
440
|
+
): Promise<DeeplyLoaded<C, Depth> | undefined>;
|
441
|
+
static load<C extends CoMap, Depth>(
|
442
|
+
this: CoValueClass<C>,
|
443
|
+
id: ID<C>,
|
438
444
|
as: Account,
|
439
|
-
depth: Depth & DepthsIn<
|
440
|
-
): Promise<DeeplyLoaded<
|
441
|
-
|
445
|
+
depth: Depth & DepthsIn<C>,
|
446
|
+
): Promise<DeeplyLoaded<C, Depth> | undefined>;
|
447
|
+
static load<C extends CoMap, Depth>(
|
448
|
+
this: CoValueClass<C>,
|
449
|
+
id: ID<C>,
|
450
|
+
asOrDepth: Account | (Depth & DepthsIn<C>),
|
451
|
+
depth?: Depth & DepthsIn<C>,
|
452
|
+
): Promise<DeeplyLoaded<C, Depth> | undefined> {
|
453
|
+
return loadCoValueWithoutMe(this, id, asOrDepth, depth);
|
442
454
|
}
|
443
455
|
|
444
456
|
/**
|
@@ -469,22 +481,45 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
469
481
|
*
|
470
482
|
* @category Subscription & Loading
|
471
483
|
*/
|
472
|
-
static subscribe<
|
473
|
-
this: CoValueClass<
|
474
|
-
id: ID<
|
484
|
+
static subscribe<C extends CoMap, Depth>(
|
485
|
+
this: CoValueClass<C>,
|
486
|
+
id: ID<C>,
|
487
|
+
depth: Depth & DepthsIn<C>,
|
488
|
+
listener: (value: DeeplyLoaded<C, Depth>) => void,
|
489
|
+
): () => void;
|
490
|
+
static subscribe<C extends CoMap, Depth>(
|
491
|
+
this: CoValueClass<C>,
|
492
|
+
id: ID<C>,
|
475
493
|
as: Account,
|
476
|
-
depth: Depth & DepthsIn<
|
477
|
-
listener: (value: DeeplyLoaded<
|
494
|
+
depth: Depth & DepthsIn<C>,
|
495
|
+
listener: (value: DeeplyLoaded<C, Depth>) => void,
|
496
|
+
): () => void;
|
497
|
+
static subscribe<C extends CoMap, Depth>(
|
498
|
+
this: CoValueClass<C>,
|
499
|
+
id: ID<C>,
|
500
|
+
asOrDepth: Account | (Depth & DepthsIn<C>),
|
501
|
+
depthOrListener:
|
502
|
+
| (Depth & DepthsIn<C>)
|
503
|
+
| ((value: DeeplyLoaded<C, Depth>) => void),
|
504
|
+
listener?: (value: DeeplyLoaded<C, Depth>) => void,
|
478
505
|
): () => void {
|
479
|
-
return
|
506
|
+
return subscribeToCoValueWithoutMe<C, Depth>(
|
507
|
+
this,
|
508
|
+
id,
|
509
|
+
asOrDepth,
|
510
|
+
depthOrListener,
|
511
|
+
listener,
|
512
|
+
);
|
480
513
|
}
|
481
514
|
|
482
515
|
static findUnique<M extends CoMap>(
|
483
516
|
this: CoValueClass<M>,
|
484
517
|
unique: CoValueUniqueness["uniqueness"],
|
485
518
|
ownerID: ID<Account> | ID<Group>,
|
486
|
-
as
|
519
|
+
as?: Account | Group | AnonymousJazzAgent,
|
487
520
|
) {
|
521
|
+
as ||= activeAccountContext.get();
|
522
|
+
|
488
523
|
const header = {
|
489
524
|
type: "comap" as const,
|
490
525
|
ruleset: {
|
@@ -0,0 +1,243 @@
|
|
1
|
+
import {
|
2
|
+
type OpID,
|
3
|
+
RawAccount,
|
4
|
+
type RawCoPlainText,
|
5
|
+
stringifyOpID,
|
6
|
+
} from "cojson";
|
7
|
+
import { activeAccountContext } from "../implementation/activeAccountContext.js";
|
8
|
+
import type { CoValue, CoValueClass, ID } from "../internal.js";
|
9
|
+
import {
|
10
|
+
inspect,
|
11
|
+
isAccountInstance,
|
12
|
+
loadCoValue,
|
13
|
+
subscribeToCoValue,
|
14
|
+
subscribeToExistingCoValue,
|
15
|
+
} from "../internal.js";
|
16
|
+
import { Account } from "./account.js";
|
17
|
+
import { Group } from "./group.js";
|
18
|
+
|
19
|
+
export type TextPos = OpID;
|
20
|
+
|
21
|
+
export class CoPlainText extends String implements CoValue {
|
22
|
+
declare id: ID<this>;
|
23
|
+
declare _type: "CoPlainText";
|
24
|
+
declare _raw: RawCoPlainText;
|
25
|
+
|
26
|
+
get _owner(): Account | Group {
|
27
|
+
return this._raw.group instanceof RawAccount
|
28
|
+
? Account.fromRaw(this._raw.group)
|
29
|
+
: Group.fromRaw(this._raw.group);
|
30
|
+
}
|
31
|
+
|
32
|
+
get _loadedAs() {
|
33
|
+
return Account.fromNode(this._raw.core.node);
|
34
|
+
}
|
35
|
+
|
36
|
+
constructor(
|
37
|
+
options:
|
38
|
+
| { fromRaw: RawCoPlainText }
|
39
|
+
| { text: string; owner: Account | Group },
|
40
|
+
) {
|
41
|
+
super();
|
42
|
+
|
43
|
+
let raw;
|
44
|
+
|
45
|
+
if ("fromRaw" in options) {
|
46
|
+
raw = options.fromRaw;
|
47
|
+
} else {
|
48
|
+
raw = options.owner._raw.createPlainText(options.text);
|
49
|
+
}
|
50
|
+
|
51
|
+
Object.defineProperties(this, {
|
52
|
+
id: { value: raw.id, enumerable: false },
|
53
|
+
_type: { value: "CoPlainText", enumerable: false },
|
54
|
+
_raw: { value: raw, enumerable: false },
|
55
|
+
});
|
56
|
+
}
|
57
|
+
|
58
|
+
static create<T extends CoPlainText>(
|
59
|
+
this: CoValueClass<T>,
|
60
|
+
text: string,
|
61
|
+
options: { owner: Account | Group },
|
62
|
+
) {
|
63
|
+
return new this({ text, owner: options.owner });
|
64
|
+
}
|
65
|
+
|
66
|
+
toString() {
|
67
|
+
return this._raw.toString();
|
68
|
+
}
|
69
|
+
|
70
|
+
valueOf() {
|
71
|
+
return this._raw.toString();
|
72
|
+
}
|
73
|
+
|
74
|
+
toJSON(): string {
|
75
|
+
return this._raw.toString();
|
76
|
+
}
|
77
|
+
|
78
|
+
[inspect]() {
|
79
|
+
return this.toJSON();
|
80
|
+
}
|
81
|
+
|
82
|
+
insertAfter(idx: number, text: string) {
|
83
|
+
this._raw.insertAfter(idx, text);
|
84
|
+
}
|
85
|
+
|
86
|
+
deleteRange(range: { from: number; to: number }) {
|
87
|
+
this._raw.deleteRange(range);
|
88
|
+
}
|
89
|
+
|
90
|
+
posBefore(idx: number): TextPos | undefined {
|
91
|
+
return this._raw.mapping.opIDbeforeIdx[idx];
|
92
|
+
}
|
93
|
+
|
94
|
+
posAfter(idx: number): TextPos | undefined {
|
95
|
+
return this._raw.mapping.opIDafterIdx[idx];
|
96
|
+
}
|
97
|
+
|
98
|
+
idxBefore(pos: TextPos): number | undefined {
|
99
|
+
return this._raw.mapping.idxBeforeOpID[stringifyOpID(pos)];
|
100
|
+
}
|
101
|
+
|
102
|
+
idxAfter(pos: TextPos): number | undefined {
|
103
|
+
return this._raw.mapping.idxAfterOpID[stringifyOpID(pos)];
|
104
|
+
}
|
105
|
+
|
106
|
+
static fromRaw<V extends CoPlainText>(
|
107
|
+
this: CoValueClass<V> & typeof CoPlainText,
|
108
|
+
raw: RawCoPlainText,
|
109
|
+
) {
|
110
|
+
return new this({ fromRaw: raw });
|
111
|
+
}
|
112
|
+
|
113
|
+
/**
|
114
|
+
* Load a `CoPlainText` with a given ID, as a given account.
|
115
|
+
*
|
116
|
+
* `depth` specifies which (if any) fields that reference other CoValues to load as well before resolving.
|
117
|
+
* The `DeeplyLoaded` return type guarantees that corresponding referenced CoValues are loaded to the specified depth.
|
118
|
+
*
|
119
|
+
* You can pass `[]` or `{}` for shallowly loading only this CoPlainText, or `{ fieldA: depthA, fieldB: depthB }` for recursively loading referenced CoValues.
|
120
|
+
*
|
121
|
+
* Check out the `load` methods on `CoMap`/`CoList`/`CoStream`/`Group`/`Account` to see which depth structures are valid to nest.
|
122
|
+
*
|
123
|
+
* @example
|
124
|
+
* ```ts
|
125
|
+
* const person = await Person.load(
|
126
|
+
* "co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
|
127
|
+
* me,
|
128
|
+
* { pet: {} }
|
129
|
+
* );
|
130
|
+
* ```
|
131
|
+
*
|
132
|
+
* @category Subscription & Loading
|
133
|
+
*/
|
134
|
+
static load<T extends CoPlainText>(
|
135
|
+
this: CoValueClass<T>,
|
136
|
+
id: ID<T>,
|
137
|
+
as?: Account,
|
138
|
+
): Promise<T | undefined> {
|
139
|
+
return loadCoValue(this, id, as ?? activeAccountContext.get(), []);
|
140
|
+
}
|
141
|
+
|
142
|
+
// /**
|
143
|
+
// * Effectful version of `CoMap.load()`.
|
144
|
+
// *
|
145
|
+
// * Needs to be run inside an `AccountCtx` context.
|
146
|
+
// *
|
147
|
+
// * @category Subscription & Loading
|
148
|
+
// */
|
149
|
+
// static loadEf<T extends CoPlainText>(
|
150
|
+
// this: CoValueClass<T>,
|
151
|
+
// id: ID<T>,
|
152
|
+
// ): Effect.Effect<T, UnavailableError, AccountCtx> {
|
153
|
+
// return loadCoValueEf(this, id, []);
|
154
|
+
// }
|
155
|
+
|
156
|
+
/**
|
157
|
+
* Load and subscribe to a `CoMap` with a given ID, as a given account.
|
158
|
+
*
|
159
|
+
* Automatically also subscribes to updates to all referenced/nested CoValues as soon as they are accessed in the listener.
|
160
|
+
*
|
161
|
+
* `depth` specifies which (if any) fields that reference other CoValues to load as well before calling `listener` for the first time.
|
162
|
+
* The `DeeplyLoaded` return type guarantees that corresponding referenced CoValues are loaded to the specified depth.
|
163
|
+
*
|
164
|
+
* You can pass `[]` or `{}` for shallowly loading only this CoMap, or `{ fieldA: depthA, fieldB: depthB }` for recursively loading referenced CoValues.
|
165
|
+
*
|
166
|
+
* Check out the `load` methods on `CoMap`/`CoList`/`CoStream`/`Group`/`Account` to see which depth structures are valid to nest.
|
167
|
+
*
|
168
|
+
* Returns an unsubscribe function that you should call when you no longer need updates.
|
169
|
+
*
|
170
|
+
* Also see the `useCoState` hook to reactively subscribe to a CoValue in a React component.
|
171
|
+
*
|
172
|
+
* @example
|
173
|
+
* ```ts
|
174
|
+
* const unsub = Person.subscribe(
|
175
|
+
* "co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
|
176
|
+
* me,
|
177
|
+
* { pet: {} },
|
178
|
+
* (person) => console.log(person)
|
179
|
+
* );
|
180
|
+
* ```
|
181
|
+
*
|
182
|
+
* @category Subscription & Loading
|
183
|
+
*/
|
184
|
+
static subscribe<T extends CoPlainText>(
|
185
|
+
this: CoValueClass<T>,
|
186
|
+
id: ID<T>,
|
187
|
+
listener: (value: T) => void,
|
188
|
+
): () => void;
|
189
|
+
static subscribe<T extends CoPlainText>(
|
190
|
+
this: CoValueClass<T>,
|
191
|
+
id: ID<T>,
|
192
|
+
as: Account,
|
193
|
+
listener: (value: T) => void,
|
194
|
+
): () => void;
|
195
|
+
static subscribe<T extends CoPlainText>(
|
196
|
+
this: CoValueClass<T>,
|
197
|
+
id: ID<T>,
|
198
|
+
asOrListener: Account | ((value: T) => void),
|
199
|
+
listener?: (value: T) => void,
|
200
|
+
): () => void {
|
201
|
+
if (isAccountInstance(asOrListener)) {
|
202
|
+
return subscribeToCoValue(this, id, asOrListener, [], listener!);
|
203
|
+
}
|
204
|
+
|
205
|
+
return subscribeToCoValue(
|
206
|
+
this,
|
207
|
+
id,
|
208
|
+
activeAccountContext.get(),
|
209
|
+
[],
|
210
|
+
listener!,
|
211
|
+
);
|
212
|
+
}
|
213
|
+
|
214
|
+
// /**
|
215
|
+
// * Effectful version of `CoMap.subscribe()` that returns a stream of updates.
|
216
|
+
// *
|
217
|
+
// * Needs to be run inside an `AccountCtx` context.
|
218
|
+
// *
|
219
|
+
// * @category Subscription & Loading
|
220
|
+
// */
|
221
|
+
// static subscribeEf<T extends CoPlainText>(
|
222
|
+
// this: CoValueClass<T>,
|
223
|
+
// id: ID<T>,
|
224
|
+
// ): Stream.Stream<T, UnavailableError, AccountCtx> {
|
225
|
+
// return subscribeToCoValueEf(this, id, []);
|
226
|
+
// }
|
227
|
+
|
228
|
+
/**
|
229
|
+
* Given an already loaded `CoMap`, subscribe to updates to the `CoMap` and ensure that the specified fields are loaded to the specified depth.
|
230
|
+
*
|
231
|
+
* Works like `CoMap.subscribe()`, but you don't need to pass the ID or the account to load as again.
|
232
|
+
*
|
233
|
+
* Returns an unsubscribe function that you should call when you no longer need updates.
|
234
|
+
*
|
235
|
+
* @category Subscription & Loading
|
236
|
+
**/
|
237
|
+
subscribe<T extends CoPlainText>(
|
238
|
+
this: T,
|
239
|
+
listener: (value: T) => void,
|
240
|
+
): () => void {
|
241
|
+
return subscribeToExistingCoValue(this, [], listener);
|
242
|
+
}
|
243
|
+
}
|