jazz-tools 0.13.16 → 0.13.18

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.
Files changed (83) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/CHANGELOG.md +19 -0
  3. package/dist/{chunk-GIZWJXSR.js → chunk-ITSHLDQB.js} +731 -600
  4. package/dist/chunk-ITSHLDQB.js.map +1 -0
  5. package/dist/coValues/account.d.ts +5 -4
  6. package/dist/coValues/account.d.ts.map +1 -1
  7. package/dist/coValues/coFeed.d.ts +3 -3
  8. package/dist/coValues/coFeed.d.ts.map +1 -1
  9. package/dist/coValues/coList.d.ts +1 -0
  10. package/dist/coValues/coList.d.ts.map +1 -1
  11. package/dist/coValues/coMap.d.ts +4 -2
  12. package/dist/coValues/coMap.d.ts.map +1 -1
  13. package/dist/coValues/coPlainText.d.ts +2 -2
  14. package/dist/coValues/coPlainText.d.ts.map +1 -1
  15. package/dist/coValues/deepLoading.d.ts +1 -9
  16. package/dist/coValues/deepLoading.d.ts.map +1 -1
  17. package/dist/coValues/extensions/imageDef.d.ts.map +1 -1
  18. package/dist/coValues/group.d.ts.map +1 -1
  19. package/dist/coValues/inbox.d.ts.map +1 -1
  20. package/dist/coValues/interfaces.d.ts +4 -1
  21. package/dist/coValues/interfaces.d.ts.map +1 -1
  22. package/dist/implementation/createContext.d.ts.map +1 -1
  23. package/dist/implementation/refs.d.ts +5 -10
  24. package/dist/implementation/refs.d.ts.map +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/internal.d.ts +1 -1
  27. package/dist/internal.d.ts.map +1 -1
  28. package/dist/subscribe/CoValueCoreSubscription.d.ts +14 -0
  29. package/dist/subscribe/CoValueCoreSubscription.d.ts.map +1 -0
  30. package/dist/subscribe/JazzError.d.ts +16 -0
  31. package/dist/subscribe/JazzError.d.ts.map +1 -0
  32. package/dist/subscribe/SubscriptionScope.d.ts +42 -0
  33. package/dist/subscribe/SubscriptionScope.d.ts.map +1 -0
  34. package/dist/subscribe/index.d.ts +21 -0
  35. package/dist/subscribe/index.d.ts.map +1 -0
  36. package/dist/subscribe/types.d.ts +12 -0
  37. package/dist/subscribe/types.d.ts.map +1 -0
  38. package/dist/subscribe/utils.d.ts +10 -0
  39. package/dist/subscribe/utils.d.ts.map +1 -0
  40. package/dist/testing.js +2 -2
  41. package/dist/testing.js.map +1 -1
  42. package/dist/tests/coMap.record.test.d.ts +2 -0
  43. package/dist/tests/coMap.record.test.d.ts.map +1 -0
  44. package/dist/tests/utils.d.ts +2 -2
  45. package/dist/tests/utils.d.ts.map +1 -1
  46. package/package.json +2 -2
  47. package/src/coValues/account.ts +43 -31
  48. package/src/coValues/coFeed.ts +28 -13
  49. package/src/coValues/coList.ts +13 -17
  50. package/src/coValues/coMap.ts +72 -80
  51. package/src/coValues/coPlainText.ts +13 -2
  52. package/src/coValues/deepLoading.ts +4 -277
  53. package/src/coValues/extensions/imageDef.ts +1 -7
  54. package/src/coValues/group.ts +7 -6
  55. package/src/coValues/inbox.ts +4 -11
  56. package/src/coValues/interfaces.ts +54 -111
  57. package/src/implementation/createContext.ts +3 -4
  58. package/src/implementation/invites.ts +2 -2
  59. package/src/implementation/refs.ts +30 -121
  60. package/src/internal.ts +1 -2
  61. package/src/subscribe/CoValueCoreSubscription.ts +71 -0
  62. package/src/subscribe/JazzError.ts +48 -0
  63. package/src/subscribe/SubscriptionScope.ts +523 -0
  64. package/src/subscribe/index.ts +82 -0
  65. package/src/subscribe/types.ts +7 -0
  66. package/src/subscribe/utils.ts +36 -0
  67. package/src/testing.ts +1 -1
  68. package/src/tests/ContextManager.test.ts +13 -9
  69. package/src/tests/coFeed.test.ts +104 -4
  70. package/src/tests/coList.test.ts +304 -115
  71. package/src/tests/coMap.record.test.ts +325 -0
  72. package/src/tests/coMap.test.ts +718 -645
  73. package/src/tests/coPlainText.test.ts +2 -2
  74. package/src/tests/createContext.test.ts +8 -8
  75. package/src/tests/deepLoading.test.ts +8 -34
  76. package/src/tests/groupsAndAccounts.test.ts +6 -4
  77. package/src/tests/subscribe.test.ts +357 -42
  78. package/src/tests/utils.ts +8 -6
  79. package/tsconfig.json +2 -1
  80. package/dist/chunk-GIZWJXSR.js.map +0 -1
  81. package/dist/implementation/subscriptionScope.d.ts +0 -34
  82. package/dist/implementation/subscriptionScope.d.ts.map +0 -1
  83. package/src/implementation/subscriptionScope.ts +0 -165
@@ -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 schema =
144
- this._schema[key as keyof typeof this._schema] ||
145
- (this._schema[ItemsSym] as Schema | undefined);
146
- return schema && schema !== "json" && isRefEncoded(schema);
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
- : new Ref(
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(rawEdit.value as ID<CoValue>, target._loadedAs, descriptor)
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
- new Ref<Account>(rawEdit.by as ID<Account>, target._loadedAs, {
191
+ accessChildById(target, rawEdit.by, {
190
192
  ref: RegisteredSchemas["Account"],
191
193
  optional: false,
192
- }).accessFrom(target, "_edits." + key + ".by"),
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._schema[
209
- key as keyof typeof map._schema
210
- ] as Schema;
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 = (this._schema[tKey] ||
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 = (this._schema[key as keyof typeof this._schema] ||
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 = (this._schema[tKey as string] ||
580
- this._schema[ItemsSym]) as Schema;
581
-
582
- if (tKey in this._schema) {
583
- const newValue = newValues[tKey];
584
- const currentValue = (this as unknown as N)[tKey];
585
-
586
- if (descriptor === "json" || "encoded" in descriptor) {
587
- if (currentValue !== newValue) {
588
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
589
- (this as any)[tKey] = newValue;
590
- }
591
- } else if (isRefEncoded(descriptor)) {
592
- const currentId = (currentValue as CoValue | undefined)?.id;
593
- const newId = (newValue as CoValue | undefined)?.id;
594
- if (currentId !== newId) {
595
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
596
- (this as any)[tKey] = newValue;
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
- const schema = target._schema;
668
-
669
- if (!schema) {
671
+ if (typeof key !== "string") {
670
672
  return undefined;
671
673
  }
672
674
 
673
- const descriptor = (schema[key as keyof CoMap["_schema"]] ||
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
- if (descriptor === "json") {
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 = (target._schema[key as keyof CoMap["_schema"]] ||
709
- target._schema[ItemsSym]) as Schema;
710
- if (descriptor && typeof key === "string") {
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
- // for (const key of Reflect.ownKeys(target._schema)) {
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 = (target._schema[key as keyof CoMap["_schema"]] ||
772
- target._schema[ItemsSym]) as Schema;
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 = (target._schema?.[key as keyof CoMap["_schema"]] ||
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 = (target._schema[key as keyof CoMap["_schema"]] ||
794
- target._schema[ItemsSym]) as Schema;
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 type {
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
- return Account.fromNode(this._raw.core.node);
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 { JsonValue, RawCoList, SessionID } from "cojson";
2
- import { ItemsSym, type Ref, RefEncoded, UnCo } from "../internal.js";
1
+ import { SessionID } from "cojson";
2
+ import { ItemsSym, UnCo } from "../internal.js";
3
3
  import { type Account } from "./account.js";
4
- import { type CoFeed, CoFeedEntry } from "./coFeed.js";
5
- import { type CoList } from "./coList.js";
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, subscriptionsScopes } from "../../internal.js";
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}`[];
@@ -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
- if (!ref.syncLoad()) {
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 accessRef() as RegisteredAccount;
198
+ return accessChildById(group, accountID, refEncodedAccountSchema);
198
199
  },
199
200
  });
200
201
  }