jazz-tools 0.13.17 → 0.13.19
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 +7 -7
- package/CHANGELOG.md +17 -0
- package/dist/{chunk-PYBQOYML.js → chunk-4HBHY4I7.js} +735 -595
- package/dist/chunk-4HBHY4I7.js.map +1 -0
- package/dist/coValues/account.d.ts +5 -4
- package/dist/coValues/account.d.ts.map +1 -1
- package/dist/coValues/coFeed.d.ts +1 -0
- package/dist/coValues/coFeed.d.ts.map +1 -1
- package/dist/coValues/coList.d.ts +1 -0
- package/dist/coValues/coList.d.ts.map +1 -1
- package/dist/coValues/coMap.d.ts +4 -2
- package/dist/coValues/coMap.d.ts.map +1 -1
- package/dist/coValues/coPlainText.d.ts +2 -2
- package/dist/coValues/coPlainText.d.ts.map +1 -1
- package/dist/coValues/deepLoading.d.ts +1 -9
- package/dist/coValues/deepLoading.d.ts.map +1 -1
- package/dist/coValues/extensions/imageDef.d.ts.map +1 -1
- package/dist/coValues/group.d.ts.map +1 -1
- package/dist/coValues/inbox.d.ts.map +1 -1
- package/dist/coValues/interfaces.d.ts +4 -1
- package/dist/coValues/interfaces.d.ts.map +1 -1
- package/dist/implementation/createContext.d.ts.map +1 -1
- package/dist/implementation/refs.d.ts +5 -10
- package/dist/implementation/refs.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/subscribe/CoValueCoreSubscription.d.ts +14 -0
- package/dist/subscribe/CoValueCoreSubscription.d.ts.map +1 -0
- package/dist/subscribe/JazzError.d.ts +16 -0
- package/dist/subscribe/JazzError.d.ts.map +1 -0
- package/dist/subscribe/SubscriptionScope.d.ts +43 -0
- package/dist/subscribe/SubscriptionScope.d.ts.map +1 -0
- package/dist/subscribe/index.d.ts +21 -0
- package/dist/subscribe/index.d.ts.map +1 -0
- package/dist/subscribe/types.d.ts +12 -0
- package/dist/subscribe/types.d.ts.map +1 -0
- package/dist/subscribe/utils.d.ts +10 -0
- package/dist/subscribe/utils.d.ts.map +1 -0
- package/dist/testing.js +2 -2
- package/dist/testing.js.map +1 -1
- package/dist/tests/coMap.record.test.d.ts +2 -0
- package/dist/tests/coMap.record.test.d.ts.map +1 -0
- package/dist/tests/utils.d.ts +2 -2
- package/dist/tests/utils.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/coValues/account.ts +43 -31
- package/src/coValues/coFeed.ts +11 -7
- package/src/coValues/coList.ts +13 -17
- package/src/coValues/coMap.ts +72 -80
- package/src/coValues/coPlainText.ts +13 -2
- package/src/coValues/deepLoading.ts +4 -277
- package/src/coValues/extensions/imageDef.ts +1 -7
- package/src/coValues/group.ts +7 -6
- package/src/coValues/inbox.ts +4 -11
- package/src/coValues/interfaces.ts +54 -111
- package/src/implementation/createContext.ts +3 -4
- package/src/implementation/invites.ts +2 -2
- package/src/implementation/refs.ts +30 -121
- package/src/internal.ts +1 -2
- package/src/subscribe/CoValueCoreSubscription.ts +71 -0
- package/src/subscribe/JazzError.ts +48 -0
- package/src/subscribe/SubscriptionScope.ts +536 -0
- package/src/subscribe/index.ts +82 -0
- package/src/subscribe/types.ts +7 -0
- package/src/subscribe/utils.ts +36 -0
- package/src/testing.ts +1 -1
- package/src/tests/ContextManager.test.ts +13 -9
- package/src/tests/coFeed.test.ts +6 -6
- package/src/tests/coList.test.ts +304 -115
- package/src/tests/coMap.record.test.ts +325 -0
- package/src/tests/coMap.test.ts +718 -645
- package/src/tests/coPlainText.test.ts +2 -2
- package/src/tests/createContext.test.ts +8 -8
- package/src/tests/deepLoading.test.ts +8 -34
- package/src/tests/groupsAndAccounts.test.ts +6 -4
- package/src/tests/subscribe.test.ts +614 -42
- package/src/tests/utils.ts +8 -6
- package/dist/chunk-PYBQOYML.js.map +0 -1
- package/dist/implementation/subscriptionScope.d.ts +0 -34
- package/dist/implementation/subscriptionScope.d.ts.map +0 -1
- package/src/implementation/subscriptionScope.ts +0 -165
package/src/coValues/coMap.ts
CHANGED
@@ -29,6 +29,8 @@ import {
|
|
29
29
|
ItemsSym,
|
30
30
|
Ref,
|
31
31
|
SchemaInit,
|
32
|
+
accessChildById,
|
33
|
+
accessChildByKey,
|
32
34
|
ensureCoValueLoaded,
|
33
35
|
inspect,
|
34
36
|
isRefEncoded,
|
@@ -38,7 +40,6 @@ import {
|
|
38
40
|
parseSubscribeRestArgs,
|
39
41
|
subscribeToCoValueWithoutMe,
|
40
42
|
subscribeToExistingCoValue,
|
41
|
-
subscriptionsScopes,
|
42
43
|
} from "../internal.js";
|
43
44
|
import { RegisteredAccount } from "../types.js";
|
44
45
|
import { type Account } from "./account.js";
|
@@ -137,20 +138,20 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
137
138
|
[Key in CoKeys<this>]: IfCo<this[Key], RefIfCoValue<this[Key]>>;
|
138
139
|
} {
|
139
140
|
return makeRefs<CoKeys<this>>(
|
141
|
+
this,
|
140
142
|
(key) => this._raw.get(key as string) as unknown as ID<CoValue>,
|
141
143
|
() => {
|
142
144
|
const keys = this._raw.keys().filter((key) => {
|
143
|
-
const
|
144
|
-
|
145
|
-
|
146
|
-
|
145
|
+
const descriptor = this.getDescriptor(key as string);
|
146
|
+
return (
|
147
|
+
descriptor && descriptor !== "json" && isRefEncoded(descriptor)
|
148
|
+
);
|
147
149
|
}) as CoKeys<this>[];
|
148
150
|
|
149
151
|
return keys;
|
150
152
|
},
|
151
153
|
this._loadedAs,
|
152
|
-
(key) =>
|
153
|
-
(this._schema[key] || this._schema[ItemsSym]) as RefEncoded<CoValue>,
|
154
|
+
(key) => this.getDescriptor(key as string) as RefEncoded<CoValue>,
|
154
155
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
155
156
|
) as any;
|
156
157
|
}
|
@@ -175,21 +176,22 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
175
176
|
? rawEdit.value === null || rawEdit.value === undefined
|
176
177
|
? rawEdit.value
|
177
178
|
: descriptor.encoded.decode(rawEdit.value)
|
178
|
-
:
|
179
|
-
rawEdit.value as ID<CoValue>,
|
180
|
-
target._loadedAs,
|
181
|
-
descriptor,
|
182
|
-
).accessFrom(target, "_edits." + key + ".value"),
|
179
|
+
: accessChildById(target, rawEdit.value as string, descriptor),
|
183
180
|
ref:
|
184
181
|
descriptor !== "json" && isRefEncoded(descriptor)
|
185
|
-
? new Ref(
|
182
|
+
? new Ref(
|
183
|
+
rawEdit.value as ID<CoValue>,
|
184
|
+
target._loadedAs,
|
185
|
+
descriptor,
|
186
|
+
target,
|
187
|
+
)
|
186
188
|
: undefined,
|
187
189
|
by:
|
188
190
|
rawEdit.by &&
|
189
|
-
|
191
|
+
accessChildById(target, rawEdit.by, {
|
190
192
|
ref: RegisteredSchemas["Account"],
|
191
193
|
optional: false,
|
192
|
-
})
|
194
|
+
}),
|
193
195
|
madeAt: rawEdit.at,
|
194
196
|
key,
|
195
197
|
};
|
@@ -205,9 +207,9 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
205
207
|
const rawEdit = map._raw.lastEditAt(key as string);
|
206
208
|
if (!rawEdit) return undefined;
|
207
209
|
|
208
|
-
const descriptor = map.
|
209
|
-
|
210
|
-
|
210
|
+
const descriptor = map.getDescriptor(key as string);
|
211
|
+
|
212
|
+
if (!descriptor) return undefined;
|
211
213
|
|
212
214
|
return {
|
213
215
|
...map.getEditFromRaw(map, rawEdit, descriptor, key as string),
|
@@ -300,6 +302,7 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
300
302
|
},
|
301
303
|
_raw: { value: raw, enumerable: false },
|
302
304
|
});
|
305
|
+
|
303
306
|
return instance;
|
304
307
|
}
|
305
308
|
|
@@ -316,8 +319,7 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
316
319
|
|
317
320
|
for (const key of this._raw.keys()) {
|
318
321
|
const tKey = key as CoKeys<this>;
|
319
|
-
const descriptor =
|
320
|
-
this._schema[ItemsSym]) as Schema;
|
322
|
+
const descriptor = this.getDescriptor(tKey);
|
321
323
|
|
322
324
|
if (!descriptor) {
|
323
325
|
continue;
|
@@ -379,8 +381,7 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
379
381
|
for (const key of Object.keys(init) as (keyof Fields)[]) {
|
380
382
|
const initValue = init[key as keyof typeof init];
|
381
383
|
|
382
|
-
const descriptor =
|
383
|
-
this._schema[ItemsSym]) as Schema;
|
384
|
+
const descriptor = this.getDescriptor(key as string);
|
384
385
|
|
385
386
|
if (!descriptor) {
|
386
387
|
continue;
|
@@ -403,6 +404,10 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
403
404
|
return rawOwner.createMap(rawInit, null, "private", uniqueness);
|
404
405
|
}
|
405
406
|
|
407
|
+
getDescriptor(key: string) {
|
408
|
+
return this._schema?.[key] || this._schema?.[ItemsSym];
|
409
|
+
}
|
410
|
+
|
406
411
|
/**
|
407
412
|
* Declare a Record-like CoMap schema, by extending `CoMap.Record(...)` and passing the value schema using `co`. Keys are always `string`.
|
408
413
|
*
|
@@ -528,7 +533,7 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
528
533
|
uniqueness: unique,
|
529
534
|
};
|
530
535
|
const crypto =
|
531
|
-
as._type === "Anonymous" ? as.node.crypto : as._raw.core.crypto;
|
536
|
+
as._type === "Anonymous" ? as.node.crypto : as._raw.core.node.crypto;
|
532
537
|
return cojsonInternals.idforHeader(header, crypto) as ID<M>;
|
533
538
|
}
|
534
539
|
|
@@ -576,25 +581,24 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
576
581
|
for (const key in newValues) {
|
577
582
|
if (Object.prototype.hasOwnProperty.call(newValues, key)) {
|
578
583
|
const tKey = key as keyof typeof newValues & keyof this;
|
579
|
-
const descriptor =
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
}
|
584
|
+
const descriptor = this.getDescriptor(key);
|
585
|
+
|
586
|
+
if (!descriptor) continue;
|
587
|
+
|
588
|
+
const newValue = newValues[tKey];
|
589
|
+
const currentValue = (this as unknown as N)[tKey];
|
590
|
+
|
591
|
+
if (descriptor === "json" || "encoded" in descriptor) {
|
592
|
+
if (currentValue !== newValue) {
|
593
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
594
|
+
(this as any)[tKey] = newValue;
|
595
|
+
}
|
596
|
+
} else if (isRefEncoded(descriptor)) {
|
597
|
+
const currentId = (currentValue as CoValue | undefined)?.id;
|
598
|
+
const newId = (newValue as CoValue | undefined)?.id;
|
599
|
+
if (currentId !== newId) {
|
600
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
601
|
+
(this as any)[tKey] = newValue;
|
598
602
|
}
|
599
603
|
}
|
600
604
|
}
|
@@ -664,33 +668,27 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
664
668
|
} else if (key in target) {
|
665
669
|
return Reflect.get(target, key, receiver);
|
666
670
|
} else {
|
667
|
-
|
668
|
-
|
669
|
-
if (!schema) {
|
671
|
+
if (typeof key !== "string") {
|
670
672
|
return undefined;
|
671
673
|
}
|
672
674
|
|
673
|
-
const descriptor = (
|
674
|
-
schema[ItemsSym]) as Schema;
|
675
|
-
if (descriptor && typeof key === "string") {
|
676
|
-
const raw = target._raw.get(key);
|
675
|
+
const descriptor = target.getDescriptor(key as string);
|
677
676
|
|
678
|
-
|
679
|
-
return raw;
|
680
|
-
} else if ("encoded" in descriptor) {
|
681
|
-
return raw === undefined ? undefined : descriptor.encoded.decode(raw);
|
682
|
-
} else if (isRefEncoded(descriptor)) {
|
683
|
-
return raw === undefined
|
684
|
-
? undefined
|
685
|
-
: new Ref(
|
686
|
-
raw as unknown as ID<CoValue>,
|
687
|
-
target._loadedAs,
|
688
|
-
descriptor,
|
689
|
-
).accessFrom(receiver, key);
|
690
|
-
}
|
691
|
-
} else {
|
677
|
+
if (!descriptor) {
|
692
678
|
return undefined;
|
693
679
|
}
|
680
|
+
|
681
|
+
const raw = target._raw.get(key);
|
682
|
+
|
683
|
+
if (descriptor === "json") {
|
684
|
+
return raw;
|
685
|
+
} else if ("encoded" in descriptor) {
|
686
|
+
return raw === undefined ? undefined : descriptor.encoded.decode(raw);
|
687
|
+
} else if (isRefEncoded(descriptor)) {
|
688
|
+
return raw === undefined
|
689
|
+
? undefined
|
690
|
+
: accessChildByKey(target, raw as string, key);
|
691
|
+
}
|
694
692
|
}
|
695
693
|
},
|
696
694
|
set(target, key, value, receiver) {
|
@@ -705,9 +703,11 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
705
703
|
return true;
|
706
704
|
}
|
707
705
|
|
708
|
-
const descriptor =
|
709
|
-
|
710
|
-
if (descriptor
|
706
|
+
const descriptor = target.getDescriptor(key as string);
|
707
|
+
|
708
|
+
if (!descriptor) return false;
|
709
|
+
|
710
|
+
if (typeof key === "string") {
|
711
711
|
if (descriptor === "json") {
|
712
712
|
target._raw.set(key, value);
|
713
713
|
} else if ("encoded" in descriptor) {
|
@@ -721,9 +721,6 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
721
721
|
}
|
722
722
|
} else if (value?.id) {
|
723
723
|
target._raw.set(key, value.id);
|
724
|
-
subscriptionsScopes
|
725
|
-
.get(target)
|
726
|
-
?.onRefAccessedOrSet(target.id, value.id);
|
727
724
|
} else {
|
728
725
|
throw new Error(
|
729
726
|
`Cannot set reference ${key} to a non-CoValue. Got ${value}`,
|
@@ -751,11 +748,7 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
751
748
|
},
|
752
749
|
ownKeys(target) {
|
753
750
|
const keys = Reflect.ownKeys(target).filter((k) => k !== ItemsSym);
|
754
|
-
|
755
|
-
// if (key !== ItemsSym && !keys.includes(key)) {
|
756
|
-
// keys.push(key);
|
757
|
-
// }
|
758
|
-
// }
|
751
|
+
|
759
752
|
for (const key of target._raw.keys()) {
|
760
753
|
if (!keys.includes(key)) {
|
761
754
|
keys.push(key);
|
@@ -768,8 +761,8 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
768
761
|
if (key in target) {
|
769
762
|
return Reflect.getOwnPropertyDescriptor(target, key);
|
770
763
|
} else {
|
771
|
-
const descriptor =
|
772
|
-
|
764
|
+
const descriptor = target.getDescriptor(key as string);
|
765
|
+
|
773
766
|
if (descriptor || key in target._raw.latest) {
|
774
767
|
return {
|
775
768
|
enumerable: true,
|
@@ -780,8 +773,7 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
780
773
|
}
|
781
774
|
},
|
782
775
|
has(target, key) {
|
783
|
-
const descriptor =
|
784
|
-
target._schema?.[ItemsSym]) as Schema;
|
776
|
+
const descriptor = target.getDescriptor(key as string);
|
785
777
|
|
786
778
|
if (target._raw && typeof key === "string" && descriptor) {
|
787
779
|
return target._raw.get(key) !== undefined;
|
@@ -790,8 +782,8 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
790
782
|
}
|
791
783
|
},
|
792
784
|
deleteProperty(target, key) {
|
793
|
-
const descriptor =
|
794
|
-
|
785
|
+
const descriptor = target.getDescriptor(key as string);
|
786
|
+
|
795
787
|
if (typeof key === "string" && descriptor) {
|
796
788
|
target._raw.delete(key);
|
797
789
|
return true;
|
@@ -1,11 +1,12 @@
|
|
1
1
|
import {
|
2
|
+
ControlledAccount,
|
2
3
|
type OpID,
|
3
4
|
RawAccount,
|
4
5
|
type RawCoPlainText,
|
5
6
|
stringifyOpID,
|
6
7
|
} from "cojson";
|
7
8
|
import { calcPatch } from "fast-myers-diff";
|
8
|
-
import
|
9
|
+
import {
|
9
10
|
AnonymousJazzAgent,
|
10
11
|
CoValue,
|
11
12
|
CoValueClass,
|
@@ -21,8 +22,10 @@ import {
|
|
21
22
|
subscribeToCoValueWithoutMe,
|
22
23
|
subscribeToExistingCoValue,
|
23
24
|
} from "../internal.js";
|
25
|
+
import { coValuesCache } from "../lib/cache.js";
|
24
26
|
import { Account } from "./account.js";
|
25
27
|
import { Group } from "./group.js";
|
28
|
+
import { RegisteredSchemas } from "./registeredSchemas.js";
|
26
29
|
|
27
30
|
export type TextPos = OpID;
|
28
31
|
|
@@ -38,7 +41,15 @@ export class CoPlainText extends String implements CoValue {
|
|
38
41
|
}
|
39
42
|
|
40
43
|
get _loadedAs() {
|
41
|
-
|
44
|
+
const agent = this._raw.core.node.getCurrentAgent();
|
45
|
+
|
46
|
+
if (agent instanceof ControlledAccount) {
|
47
|
+
return coValuesCache.get(agent.account, () =>
|
48
|
+
RegisteredSchemas["Account"].fromRaw(agent.account),
|
49
|
+
);
|
50
|
+
}
|
51
|
+
|
52
|
+
return new AnonymousJazzAgent(this._raw.core.node);
|
42
53
|
}
|
43
54
|
|
44
55
|
constructor(
|
@@ -1,283 +1,10 @@
|
|
1
|
-
import {
|
2
|
-
import { ItemsSym,
|
1
|
+
import { SessionID } from "cojson";
|
2
|
+
import { ItemsSym, UnCo } from "../internal.js";
|
3
3
|
import { type Account } from "./account.js";
|
4
|
-
import {
|
5
|
-
import { type
|
6
|
-
import { type CoKeys, type CoMap } from "./coMap.js";
|
4
|
+
import { CoFeedEntry } from "./coFeed.js";
|
5
|
+
import { type CoKeys } from "./coMap.js";
|
7
6
|
import { type CoValue, type ID } from "./interfaces.js";
|
8
7
|
|
9
|
-
function hasRefValue(value: CoValue, key: string | number) {
|
10
|
-
return Boolean(
|
11
|
-
(
|
12
|
-
value as unknown as {
|
13
|
-
_refs: { [key: string]: Ref<CoValue> | undefined };
|
14
|
-
}
|
15
|
-
)._refs?.[key],
|
16
|
-
);
|
17
|
-
}
|
18
|
-
|
19
|
-
function hasReadAccess(value: CoValue, key: string | number) {
|
20
|
-
return Boolean(
|
21
|
-
(
|
22
|
-
value as unknown as {
|
23
|
-
_refs: { [key: string]: Ref<CoValue> | undefined };
|
24
|
-
}
|
25
|
-
)._refs?.[key]?.hasReadAccess(),
|
26
|
-
);
|
27
|
-
}
|
28
|
-
|
29
|
-
function isOptionalField(value: CoValue, key: string): boolean {
|
30
|
-
return (
|
31
|
-
((value as CoMap)._schema[key] as RefEncoded<CoValue>)?.optional ?? false
|
32
|
-
);
|
33
|
-
}
|
34
|
-
|
35
|
-
type FulfillsDepthResult =
|
36
|
-
| {
|
37
|
-
status: "fulfilled" | "unfulfilled";
|
38
|
-
}
|
39
|
-
| {
|
40
|
-
status: "unauthorized";
|
41
|
-
path: string[];
|
42
|
-
id: JsonValue;
|
43
|
-
};
|
44
|
-
|
45
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
46
|
-
export function fulfillsDepth(depth: any, value: CoValue): FulfillsDepthResult {
|
47
|
-
if (depth === true || depth === undefined) {
|
48
|
-
return {
|
49
|
-
status: "fulfilled",
|
50
|
-
};
|
51
|
-
}
|
52
|
-
|
53
|
-
if (
|
54
|
-
value._type === "CoMap" ||
|
55
|
-
value._type === "Group" ||
|
56
|
-
value._type === "Account"
|
57
|
-
) {
|
58
|
-
const map = value as CoMap;
|
59
|
-
|
60
|
-
if ("$each" in depth) {
|
61
|
-
const result: FulfillsDepthResult = { status: "fulfilled" };
|
62
|
-
|
63
|
-
for (const [key, item] of Object.entries(value)) {
|
64
|
-
const rawValue = map._raw.get(key);
|
65
|
-
|
66
|
-
if (rawValue !== undefined && rawValue !== null) {
|
67
|
-
if (!item) {
|
68
|
-
if (hasReadAccess(map, key)) {
|
69
|
-
result.status = "unfulfilled";
|
70
|
-
continue;
|
71
|
-
} else {
|
72
|
-
return {
|
73
|
-
status: "unauthorized",
|
74
|
-
path: [key],
|
75
|
-
id: rawValue,
|
76
|
-
};
|
77
|
-
}
|
78
|
-
}
|
79
|
-
|
80
|
-
const innerResult = fulfillsDepth(depth.$each, item);
|
81
|
-
|
82
|
-
if (innerResult.status === "unfulfilled") {
|
83
|
-
result.status = "unfulfilled";
|
84
|
-
} else if (
|
85
|
-
innerResult.status === "unauthorized" &&
|
86
|
-
!isOptionalField(value, ItemsSym)
|
87
|
-
) {
|
88
|
-
innerResult.path.unshift(key);
|
89
|
-
|
90
|
-
return innerResult; // If any item is unauthorized, the whole thing is unauthorized
|
91
|
-
}
|
92
|
-
} else if (!isOptionalField(value, ItemsSym)) {
|
93
|
-
return {
|
94
|
-
status: "unfulfilled",
|
95
|
-
};
|
96
|
-
}
|
97
|
-
}
|
98
|
-
|
99
|
-
return result;
|
100
|
-
} else {
|
101
|
-
const result: FulfillsDepthResult = { status: "fulfilled" };
|
102
|
-
|
103
|
-
for (const key of Object.keys(depth)) {
|
104
|
-
const rawValue = map._raw.get(key);
|
105
|
-
|
106
|
-
if (rawValue === undefined || rawValue === null) {
|
107
|
-
if (!map._schema?.[key]) {
|
108
|
-
// Field not defined in schema
|
109
|
-
if (map._schema?.[ItemsSym]) {
|
110
|
-
// CoMap.Record
|
111
|
-
if (isOptionalField(map, ItemsSym)) {
|
112
|
-
continue;
|
113
|
-
} else {
|
114
|
-
// All fields are required, so the returned type is not optional and we must comply
|
115
|
-
throw new Error(
|
116
|
-
`The ref ${key} requested on ${map.constructor.name} is missing`,
|
117
|
-
);
|
118
|
-
}
|
119
|
-
} else {
|
120
|
-
// Field not defined in CoMap schema
|
121
|
-
throw new Error(
|
122
|
-
`The ref ${key} requested on ${map.constructor.name} is not defined in the schema`,
|
123
|
-
);
|
124
|
-
}
|
125
|
-
} else if (isOptionalField(map, key)) {
|
126
|
-
continue;
|
127
|
-
} else {
|
128
|
-
// Field is required but has never been set
|
129
|
-
throw new Error(
|
130
|
-
`The ref ${key} on ${map.constructor.name} is required but missing`,
|
131
|
-
);
|
132
|
-
}
|
133
|
-
} else {
|
134
|
-
const item = (value as Record<string, any>)[key];
|
135
|
-
|
136
|
-
if (!item) {
|
137
|
-
if (hasReadAccess(map, key)) {
|
138
|
-
result.status = "unfulfilled";
|
139
|
-
continue;
|
140
|
-
} else {
|
141
|
-
return {
|
142
|
-
status: "unauthorized",
|
143
|
-
path: [key],
|
144
|
-
id: rawValue,
|
145
|
-
};
|
146
|
-
}
|
147
|
-
}
|
148
|
-
|
149
|
-
const innerResult = fulfillsDepth(depth[key], item);
|
150
|
-
|
151
|
-
if (innerResult.status === "unfulfilled") {
|
152
|
-
result.status = "unfulfilled";
|
153
|
-
} else if (
|
154
|
-
innerResult.status === "unauthorized" &&
|
155
|
-
!isOptionalField(value, key)
|
156
|
-
) {
|
157
|
-
innerResult.path.unshift(key);
|
158
|
-
|
159
|
-
return innerResult; // If any item is unauthorized, the whole thing is unauthorized
|
160
|
-
}
|
161
|
-
}
|
162
|
-
}
|
163
|
-
|
164
|
-
return result;
|
165
|
-
}
|
166
|
-
} else if (value._type === "CoList") {
|
167
|
-
if ("$each" in depth) {
|
168
|
-
const result: FulfillsDepthResult = { status: "fulfilled" };
|
169
|
-
const list = value as CoList;
|
170
|
-
|
171
|
-
for (const [key, item] of (value as CoList).entries()) {
|
172
|
-
const rawValue = list._raw.get(key);
|
173
|
-
|
174
|
-
if (!rawValue) {
|
175
|
-
if (isOptionalField(value, ItemsSym)) {
|
176
|
-
continue;
|
177
|
-
}
|
178
|
-
|
179
|
-
// Throw an error and mark this as unavailable
|
180
|
-
throw new Error(
|
181
|
-
`The ref ${key} on ${list.constructor.name} is required but missing`,
|
182
|
-
);
|
183
|
-
}
|
184
|
-
|
185
|
-
if (hasRefValue(value, key)) {
|
186
|
-
if (!item) {
|
187
|
-
if (hasReadAccess(value, key)) {
|
188
|
-
result.status = "unfulfilled";
|
189
|
-
continue;
|
190
|
-
} else {
|
191
|
-
return {
|
192
|
-
status: "unauthorized",
|
193
|
-
path: [key.toString()],
|
194
|
-
id: (value._raw as RawCoList).get(key) ?? "undefined",
|
195
|
-
};
|
196
|
-
}
|
197
|
-
}
|
198
|
-
|
199
|
-
const innerResult = fulfillsDepth(depth.$each, item);
|
200
|
-
|
201
|
-
if (innerResult.status === "unfulfilled") {
|
202
|
-
result.status = "unfulfilled";
|
203
|
-
} else if (
|
204
|
-
innerResult.status === "unauthorized" &&
|
205
|
-
!isOptionalField(value, ItemsSym)
|
206
|
-
) {
|
207
|
-
innerResult.path.unshift(key.toString());
|
208
|
-
|
209
|
-
return innerResult; // If any item is unauthorized, the whole thing is unauthorized
|
210
|
-
}
|
211
|
-
} else if (!isOptionalField(value, ItemsSym)) {
|
212
|
-
return {
|
213
|
-
status: "unfulfilled",
|
214
|
-
};
|
215
|
-
}
|
216
|
-
}
|
217
|
-
|
218
|
-
return result;
|
219
|
-
}
|
220
|
-
|
221
|
-
return {
|
222
|
-
status: "fulfilled",
|
223
|
-
};
|
224
|
-
} else if (value._type === "CoStream") {
|
225
|
-
if ("$each" in depth) {
|
226
|
-
const result: FulfillsDepthResult = { status: "fulfilled" };
|
227
|
-
|
228
|
-
for (const item of Object.values((value as CoFeed).perSession)) {
|
229
|
-
if (item.ref) {
|
230
|
-
if (!item.value) {
|
231
|
-
if (item.ref.hasReadAccess()) {
|
232
|
-
result.status = "unfulfilled";
|
233
|
-
continue;
|
234
|
-
} else {
|
235
|
-
return {
|
236
|
-
status: "unauthorized",
|
237
|
-
path: [item.ref.id],
|
238
|
-
id: item.ref.id,
|
239
|
-
};
|
240
|
-
}
|
241
|
-
}
|
242
|
-
|
243
|
-
const innerResult = fulfillsDepth(depth.$each, item.value);
|
244
|
-
|
245
|
-
if (innerResult.status === "unfulfilled") {
|
246
|
-
result.status = "unfulfilled";
|
247
|
-
} else if (
|
248
|
-
innerResult.status === "unauthorized" &&
|
249
|
-
!isOptionalField(value, ItemsSym)
|
250
|
-
) {
|
251
|
-
innerResult.path.unshift(item.ref.id);
|
252
|
-
|
253
|
-
return innerResult; // If any item is unauthorized, the whole thing is unauthorized
|
254
|
-
}
|
255
|
-
} else if (!isOptionalField(value, ItemsSym)) {
|
256
|
-
return {
|
257
|
-
status: "unfulfilled",
|
258
|
-
};
|
259
|
-
}
|
260
|
-
}
|
261
|
-
|
262
|
-
return result;
|
263
|
-
}
|
264
|
-
|
265
|
-
return {
|
266
|
-
status: "fulfilled",
|
267
|
-
};
|
268
|
-
} else if (
|
269
|
-
value._type === "BinaryCoStream" ||
|
270
|
-
value._type === "CoPlainText"
|
271
|
-
) {
|
272
|
-
return {
|
273
|
-
status: "fulfilled",
|
274
|
-
};
|
275
|
-
} else {
|
276
|
-
console.error(value);
|
277
|
-
throw new Error("Unexpected value type: " + value._type);
|
278
|
-
}
|
279
|
-
}
|
280
|
-
|
281
8
|
type UnCoNotNull<T> = UnCo<Exclude<T, null>>;
|
282
9
|
export type Clean<T> = UnCo<NonNullable<T>>;
|
283
10
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { co
|
1
|
+
import { co } from "../../internal.js";
|
2
2
|
import { FileStream } from "../coFeed.js";
|
3
3
|
import { CoMap } from "../coMap.js";
|
4
4
|
|
@@ -14,12 +14,6 @@ export class ImageDefinition extends CoMap {
|
|
14
14
|
maxWidth?: number;
|
15
15
|
targetWidth?: number;
|
16
16
|
}): { res: `${number}x${number}`; stream: FileStream } | undefined {
|
17
|
-
if (!subscriptionsScopes.get(this)) {
|
18
|
-
console.warn(
|
19
|
-
"highestResAvailable() only makes sense when used within a subscription.",
|
20
|
-
);
|
21
|
-
}
|
22
|
-
|
23
17
|
const resolutions = Object.keys(this).filter((key) =>
|
24
18
|
key.match(/^\d+x\d+$/),
|
25
19
|
) as `${number}x${number}`[];
|
package/src/coValues/group.ts
CHANGED
@@ -22,6 +22,7 @@ import type {
|
|
22
22
|
import {
|
23
23
|
CoValueBase,
|
24
24
|
Ref,
|
25
|
+
accessChildById,
|
25
26
|
co,
|
26
27
|
ensureCoValueLoaded,
|
27
28
|
loadCoValueWithoutMe,
|
@@ -85,6 +86,7 @@ export class Group extends CoValueBase implements CoValue {
|
|
85
86
|
profileID,
|
86
87
|
this._loadedAs,
|
87
88
|
this._schema.profile as RefEncoded<NonNullable<this["profile"]>>,
|
89
|
+
this,
|
88
90
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
89
91
|
) as any as this["profile"] extends Profile
|
90
92
|
? Ref<this["profile"]>
|
@@ -95,6 +97,7 @@ export class Group extends CoValueBase implements CoValue {
|
|
95
97
|
rootID,
|
96
98
|
this._loadedAs,
|
97
99
|
this._schema.root as RefEncoded<NonNullable<this["root"]>>,
|
100
|
+
this,
|
98
101
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
99
102
|
) as any as this["root"] extends CoMap ? Ref<this["root"]> : never),
|
100
103
|
};
|
@@ -112,7 +115,7 @@ export class Group extends CoValueBase implements CoValue {
|
|
112
115
|
if (!initOwner) throw new Error("No owner provided");
|
113
116
|
if (initOwner._type === "Account" && isControlledAccount(initOwner)) {
|
114
117
|
const rawOwner = initOwner._raw;
|
115
|
-
raw = rawOwner.createGroup();
|
118
|
+
raw = rawOwner.core.node.createGroup();
|
116
119
|
} else {
|
117
120
|
throw new Error("Can only construct group as a controlled account");
|
118
121
|
}
|
@@ -181,12 +184,10 @@ export class Group extends CoValueBase implements CoValue {
|
|
181
184
|
accountID as unknown as ID<RegisteredAccount>,
|
182
185
|
this._loadedAs,
|
183
186
|
refEncodedAccountSchema,
|
187
|
+
this,
|
184
188
|
);
|
185
|
-
const accessRef = () => ref.accessFrom(this, "members." + accountID);
|
186
189
|
|
187
|
-
|
188
|
-
console.warn("Account not loaded", accountID);
|
189
|
-
}
|
190
|
+
const group = this;
|
190
191
|
|
191
192
|
members.push({
|
192
193
|
id: accountID as unknown as ID<Account>,
|
@@ -194,7 +195,7 @@ export class Group extends CoValueBase implements CoValue {
|
|
194
195
|
ref,
|
195
196
|
get account() {
|
196
197
|
// Accounts values are non-nullable because are loaded as dependencies
|
197
|
-
return
|
198
|
+
return accessChildById(group, accountID, refEncodedAccountSchema);
|
198
199
|
},
|
199
200
|
});
|
200
201
|
}
|