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
@@ -38,7 +38,7 @@ var AnonymousJazzAgent = class {
38
38
  };
39
39
 
40
40
  // src/coValues/interfaces.ts
41
- import { RawAccount as RawAccount3 } from "cojson";
41
+ import { ControlledAccount, RawAccount as RawAccount3 } from "cojson";
42
42
 
43
43
  // src/implementation/inspect.ts
44
44
  var inspect = Symbol.for("nodejs.util.inspect.custom");
@@ -47,203 +47,100 @@ var inspect = Symbol.for("nodejs.util.inspect.custom");
47
47
  var SchemaInit = "$SchemaInit$";
48
48
  var ItemsSym = "$items$";
49
49
 
50
- // src/coValues/deepLoading.ts
51
- function hasRefValue(value, key) {
52
- return Boolean(
53
- value._refs?.[key]
54
- );
55
- }
56
- function hasReadAccess(value, key) {
57
- return Boolean(
58
- value._refs?.[key]?.hasReadAccess()
59
- );
60
- }
61
- function isOptionalField(value, key) {
62
- return value._schema[key]?.optional ?? false;
63
- }
64
- function fulfillsDepth(depth, value) {
65
- if (depth === true || depth === void 0) {
66
- return {
67
- status: "fulfilled"
50
+ // src/subscribe/CoValueCoreSubscription.ts
51
+ var CoValueCoreSubscription = class {
52
+ constructor(node, id, listener) {
53
+ this.node = node;
54
+ this.id = id;
55
+ this.listener = listener;
56
+ this._unsubscribe = () => {
68
57
  };
69
- }
70
- if (value._type === "CoMap" || value._type === "Group" || value._type === "Account") {
71
- const map = value;
72
- if ("$each" in depth) {
73
- const result = { status: "fulfilled" };
74
- for (const [key, item] of Object.entries(value)) {
75
- const rawValue = map._raw.get(key);
76
- if (rawValue !== void 0 && rawValue !== null) {
77
- if (!item) {
78
- if (hasReadAccess(map, key)) {
79
- result.status = "unfulfilled";
80
- continue;
81
- } else {
82
- return {
83
- status: "unauthorized",
84
- path: [key],
85
- id: rawValue
86
- };
87
- }
88
- }
89
- const innerResult = fulfillsDepth(depth.$each, item);
90
- if (innerResult.status === "unfulfilled") {
91
- result.status = "unfulfilled";
92
- } else if (innerResult.status === "unauthorized" && !isOptionalField(value, ItemsSym)) {
93
- innerResult.path.unshift(key);
94
- return innerResult;
95
- }
96
- } else if (!isOptionalField(value, ItemsSym)) {
97
- return {
98
- status: "unfulfilled"
99
- };
100
- }
101
- }
102
- return result;
58
+ this.unsubscribed = false;
59
+ const entry = this.node.getCoValue(this.id);
60
+ if (entry?.isAvailable()) {
61
+ this.subscribe(entry.getCurrentContent());
103
62
  } else {
104
- const result = { status: "fulfilled" };
105
- for (const key of Object.keys(depth)) {
106
- const rawValue = map._raw.get(key);
107
- if (rawValue === void 0 || rawValue === null) {
108
- if (!map._schema?.[key]) {
109
- if (map._schema?.[ItemsSym]) {
110
- if (isOptionalField(map, ItemsSym)) {
111
- continue;
112
- } else {
113
- throw new Error(
114
- `The ref ${key} requested on ${map.constructor.name} is missing`
115
- );
116
- }
117
- } else {
118
- throw new Error(
119
- `The ref ${key} requested on ${map.constructor.name} is not defined in the schema`
120
- );
121
- }
122
- } else if (isOptionalField(map, key)) {
123
- continue;
124
- } else {
125
- throw new Error(
126
- `The ref ${key} on ${map.constructor.name} is required but missing`
127
- );
128
- }
63
+ this.node.loadCoValueCore(this.id).then((value) => {
64
+ if (this.unsubscribed) return;
65
+ if (value.isAvailable()) {
66
+ this.subscribe(value.getCurrentContent());
129
67
  } else {
130
- const item = value[key];
131
- if (!item) {
132
- if (hasReadAccess(map, key)) {
133
- result.status = "unfulfilled";
134
- continue;
135
- } else {
136
- return {
137
- status: "unauthorized",
138
- path: [key],
139
- id: rawValue
140
- };
141
- }
142
- }
143
- const innerResult = fulfillsDepth(depth[key], item);
144
- if (innerResult.status === "unfulfilled") {
145
- result.status = "unfulfilled";
146
- } else if (innerResult.status === "unauthorized" && !isOptionalField(value, key)) {
147
- innerResult.path.unshift(key);
148
- return innerResult;
149
- }
68
+ this.listener("unavailable");
69
+ this.subscribeToState();
150
70
  }
151
- }
152
- return result;
71
+ });
153
72
  }
154
- } else if (value._type === "CoList") {
155
- if ("$each" in depth) {
156
- const result = { status: "fulfilled" };
157
- const list = value;
158
- for (const [key, item] of value.entries()) {
159
- const rawValue = list._raw.get(key);
160
- if (!rawValue) {
161
- if (isOptionalField(value, ItemsSym)) {
162
- continue;
163
- }
164
- throw new Error(
165
- `The ref ${key} on ${list.constructor.name} is required but missing`
166
- );
167
- }
168
- if (hasRefValue(value, key)) {
169
- if (!item) {
170
- if (hasReadAccess(value, key)) {
171
- result.status = "unfulfilled";
172
- continue;
173
- } else {
174
- return {
175
- status: "unauthorized",
176
- path: [key.toString()],
177
- id: value._raw.get(key) ?? "undefined"
178
- };
179
- }
180
- }
181
- const innerResult = fulfillsDepth(depth.$each, item);
182
- if (innerResult.status === "unfulfilled") {
183
- result.status = "unfulfilled";
184
- } else if (innerResult.status === "unauthorized" && !isOptionalField(value, ItemsSym)) {
185
- innerResult.path.unshift(key.toString());
186
- return innerResult;
187
- }
188
- } else if (!isOptionalField(value, ItemsSym)) {
189
- return {
190
- status: "unfulfilled"
191
- };
192
- }
73
+ }
74
+ subscribeToState() {
75
+ const entry = this.node.getCoValue(this.id);
76
+ const handleStateChange = (core, unsubFromStateChange2) => {
77
+ if (this.unsubscribed) {
78
+ unsubFromStateChange2();
79
+ return;
193
80
  }
194
- return result;
195
- }
196
- return {
197
- status: "fulfilled"
198
- };
199
- } else if (value._type === "CoStream") {
200
- if ("$each" in depth) {
201
- const result = { status: "fulfilled" };
202
- for (const item of Object.values(value.perSession)) {
203
- if (item.ref) {
204
- if (!item.value) {
205
- if (item.ref.hasReadAccess()) {
206
- result.status = "unfulfilled";
207
- continue;
208
- } else {
209
- return {
210
- status: "unauthorized",
211
- path: [item.ref.id],
212
- id: item.ref.id
213
- };
214
- }
215
- }
216
- const innerResult = fulfillsDepth(depth.$each, item.value);
217
- if (innerResult.status === "unfulfilled") {
218
- result.status = "unfulfilled";
219
- } else if (innerResult.status === "unauthorized" && !isOptionalField(value, ItemsSym)) {
220
- innerResult.path.unshift(item.ref.id);
221
- return innerResult;
222
- }
223
- } else if (!isOptionalField(value, ItemsSym)) {
224
- return {
225
- status: "unfulfilled"
226
- };
227
- }
81
+ if (core.isAvailable()) {
82
+ this.subscribe(core.getCurrentContent());
83
+ unsubFromStateChange2();
228
84
  }
229
- return result;
230
- }
231
- return {
232
- status: "fulfilled"
233
85
  };
234
- } else if (value._type === "BinaryCoStream" || value._type === "CoPlainText") {
235
- return {
236
- status: "fulfilled"
86
+ const unsubFromStateChange = entry.subscribe(handleStateChange);
87
+ this._unsubscribe = () => {
88
+ unsubFromStateChange();
237
89
  };
238
- } else {
239
- console.error(value);
240
- throw new Error("Unexpected value type: " + value._type);
241
90
  }
242
- }
91
+ subscribe(value) {
92
+ if (this.unsubscribed) return;
93
+ this._unsubscribe = value.subscribe((value2) => {
94
+ this.listener(value2);
95
+ });
96
+ this.listener(value);
97
+ }
98
+ unsubscribe() {
99
+ if (this.unsubscribed) return;
100
+ this.unsubscribed = true;
101
+ this._unsubscribe();
102
+ }
103
+ };
243
104
 
244
- // src/implementation/refs.ts
105
+ // src/subscribe/JazzError.ts
106
+ var JazzError = class _JazzError {
107
+ constructor(id, type, issues) {
108
+ this.id = id;
109
+ this.type = type;
110
+ this.issues = issues;
111
+ }
112
+ toString() {
113
+ return this.issues.map((issue) => {
114
+ let message = `${issue.message}`;
115
+ if (this.id) {
116
+ message += ` from ${this.id}`;
117
+ }
118
+ if (issue.path.length > 0) {
119
+ message += ` on path ${issue.path.join(".")}`;
120
+ }
121
+ return message;
122
+ }).join("\n");
123
+ }
124
+ prependPath(item) {
125
+ if (this.issues.length === 0) {
126
+ return this;
127
+ }
128
+ const issues = this.issues.map((issue) => {
129
+ return {
130
+ ...issue,
131
+ path: [item].concat(issue.path)
132
+ };
133
+ });
134
+ return new _JazzError(this.id, this.type, issues);
135
+ }
136
+ };
137
+
138
+ // src/subscribe/utils.ts
245
139
  import { RawAccount, RawGroup } from "cojson";
246
140
 
141
+ // src/coValues/registeredSchemas.ts
142
+ var RegisteredSchemas = {};
143
+
247
144
  // src/lib/cache.ts
248
145
  var weakMap = /* @__PURE__ */ new WeakMap();
249
146
  var coValuesCache = {
@@ -258,114 +155,492 @@ var coValuesCache = {
258
155
  }
259
156
  };
260
157
 
261
- // src/implementation/refs.ts
262
- var TRACE_ACCESSES = false;
263
- var Ref = class _Ref {
264
- constructor(id, controlledAccount, schema) {
158
+ // src/subscribe/utils.ts
159
+ function getOwnerFromRawValue(raw) {
160
+ let owner = raw instanceof RawGroup ? raw : raw.group;
161
+ return coValuesCache.get(
162
+ owner,
163
+ () => owner instanceof RawAccount ? RegisteredSchemas["Account"].fromRaw(owner) : RegisteredSchemas["Group"].fromRaw(owner)
164
+ );
165
+ }
166
+ function createCoValue(ref2, raw, subscriptionScope) {
167
+ const freshValueInstance = instantiateRefEncoded(ref2, raw);
168
+ Object.defineProperty(freshValueInstance, "_subscriptionScope", {
169
+ value: subscriptionScope,
170
+ writable: false,
171
+ enumerable: false,
172
+ configurable: false
173
+ });
174
+ return {
175
+ type: "loaded",
176
+ value: freshValueInstance,
177
+ id: subscriptionScope.id
178
+ };
179
+ }
180
+
181
+ // src/subscribe/SubscriptionScope.ts
182
+ var SubscriptionScope = class _SubscriptionScope {
183
+ constructor(node, resolve, id, schema) {
184
+ this.node = node;
265
185
  this.id = id;
266
- this.controlledAccount = controlledAccount;
267
186
  this.schema = schema;
268
- if (!isRefEncoded(schema)) {
269
- throw new Error("Ref must be constructed with a ref schema");
270
- }
187
+ this.childNodes = /* @__PURE__ */ new Map();
188
+ this.childValues = /* @__PURE__ */ new Map();
189
+ this.childErrors = /* @__PURE__ */ new Map();
190
+ this.validationErrors = /* @__PURE__ */ new Map();
191
+ this.dirty = false;
192
+ this.idsSubscribed = /* @__PURE__ */ new Set();
193
+ this.autoloaded = /* @__PURE__ */ new Set();
194
+ this.totalValidTransactions = 0;
195
+ this.silenceUpdates = false;
196
+ this.handleChildUpdate = (id, value, key) => {
197
+ if (value.type === "unloaded") {
198
+ return;
199
+ }
200
+ this.childValues.set(id, value);
201
+ if (value.type === "unavailable" || value.type === "unauthorized") {
202
+ this.childErrors.set(id, value.prependPath(key ?? id));
203
+ this.errorFromChildren = this.computeChildErrors();
204
+ } else if (this.errorFromChildren && this.childErrors.has(id)) {
205
+ this.childErrors.delete(id);
206
+ this.errorFromChildren = this.computeChildErrors();
207
+ }
208
+ if (this.shouldSendUpdates()) {
209
+ if (this.value.type === "loaded") {
210
+ this.updateValue(
211
+ createCoValue(this.schema, this.value.value._raw, this)
212
+ );
213
+ }
214
+ }
215
+ this.triggerUpdate();
216
+ };
217
+ this.subscribers = /* @__PURE__ */ new Set();
218
+ this.resolve = resolve;
219
+ this.value = { type: "unloaded", id };
220
+ this.subscription = new CoValueCoreSubscription(node, id, (value) => {
221
+ this.handleUpdate(value);
222
+ });
271
223
  }
272
- getNode() {
273
- return "node" in this.controlledAccount ? this.controlledAccount.node : this.controlledAccount._raw.core.node;
224
+ updateValue(value) {
225
+ this.value = value;
226
+ this.dirty = true;
227
+ }
228
+ handleUpdate(update) {
229
+ if (update === "unavailable") {
230
+ if (this.value.type === "unloaded") {
231
+ this.updateValue(
232
+ new JazzError(this.id, "unavailable", [
233
+ {
234
+ code: "unavailable",
235
+ message: "The value is unavailable",
236
+ params: {
237
+ id: this.id
238
+ },
239
+ path: []
240
+ }
241
+ ])
242
+ );
243
+ }
244
+ this.triggerUpdate();
245
+ return;
246
+ }
247
+ const owner = getOwnerFromRawValue(update);
248
+ const ruleset = update.core.verified.header.ruleset;
249
+ const hasAccess = ruleset.type === "group" || owner.myRole() !== void 0;
250
+ if (!hasAccess) {
251
+ if (this.value.type !== "unauthorized") {
252
+ this.updateValue(
253
+ new JazzError(this.id, "unauthorized", [
254
+ {
255
+ code: "unauthorized",
256
+ message: "The current user is not authorized to access this value",
257
+ params: {
258
+ id: this.id
259
+ },
260
+ path: []
261
+ }
262
+ ])
263
+ );
264
+ this.triggerUpdate();
265
+ }
266
+ return;
267
+ }
268
+ this.silenceUpdates = true;
269
+ if (this.value.type !== "loaded") {
270
+ this.updateValue(createCoValue(this.schema, update, this));
271
+ this.loadChildren();
272
+ } else {
273
+ const hasChanged = update.totalValidTransactions !== this.totalValidTransactions || // Checking the identity of the _raw value makes us cover the cases where the group
274
+ // has been updated and the coValues that don't update the totalValidTransactions value (e.g. FileStream)
275
+ this.value.value._raw !== update;
276
+ if (this.loadChildren()) {
277
+ this.updateValue(createCoValue(this.schema, update, this));
278
+ } else if (hasChanged) {
279
+ this.updateValue(createCoValue(this.schema, update, this));
280
+ }
281
+ }
282
+ this.totalValidTransactions = update.totalValidTransactions;
283
+ this.silenceUpdates = false;
284
+ this.triggerUpdate();
274
285
  }
275
- hasReadAccess() {
276
- const node = this.getNode();
277
- const raw = node.getLoaded(this.id);
278
- if (!raw) {
279
- return true;
286
+ computeChildErrors() {
287
+ let issues = [];
288
+ let errorType = "unavailable";
289
+ if (this.childErrors.size === 0 && this.validationErrors.size === 0) {
290
+ return void 0;
280
291
  }
281
- if (raw instanceof RawAccount || raw instanceof RawGroup) {
282
- return true;
292
+ for (const value of this.childErrors.values()) {
293
+ errorType = value.type;
294
+ if (value.issues) {
295
+ issues.push(...value.issues);
296
+ }
297
+ }
298
+ for (const value of this.validationErrors.values()) {
299
+ errorType = value.type;
300
+ if (value.issues) {
301
+ issues.push(...value.issues);
302
+ }
283
303
  }
284
- const group = raw.core.getGroup();
285
- if (group instanceof RawAccount) {
286
- if (node.account.id !== group.id) {
304
+ return new JazzError(this.id, errorType, issues);
305
+ }
306
+ shouldSendUpdates() {
307
+ if (this.value.type === "unloaded") return false;
308
+ if (this.value.type !== "loaded") return true;
309
+ for (const value of this.childValues.values()) {
310
+ if (value.type === "unloaded" && !this.autoloaded.has(value.id)) {
287
311
  return false;
288
312
  }
289
- } else if (group.myRole() === void 0) {
290
- return false;
291
313
  }
292
314
  return true;
293
315
  }
294
- getValueWithoutAccessCheck() {
295
- const node = this.getNode();
296
- const raw = node.getLoaded(this.id);
297
- if (raw) {
298
- return coValuesCache.get(
299
- raw,
300
- () => instantiateRefEncoded(this.schema, raw)
301
- );
302
- } else {
303
- return null;
316
+ triggerUpdate() {
317
+ if (!this.shouldSendUpdates()) return;
318
+ if (!this.dirty) return;
319
+ if (this.subscribers.size === 0) return;
320
+ if (this.silenceUpdates) return;
321
+ const error = this.errorFromChildren;
322
+ const value = this.value;
323
+ if (error) {
324
+ this.subscribers.forEach((listener) => listener(error));
325
+ } else if (value.type !== "unloaded") {
326
+ this.subscribers.forEach((listener) => listener(value));
304
327
  }
328
+ this.dirty = false;
305
329
  }
306
- get value() {
307
- if (!this.hasReadAccess()) {
308
- return null;
309
- }
310
- return this.getValueWithoutAccessCheck();
330
+ subscribe(listener) {
331
+ this.subscribers.add(listener);
332
+ return () => {
333
+ this.subscribers.delete(listener);
334
+ };
311
335
  }
312
- async loadHelper() {
313
- const node = "node" in this.controlledAccount ? this.controlledAccount.node : this.controlledAccount._raw.core.node;
314
- const raw = await node.load(this.id);
315
- if (raw === "unavailable") {
316
- return "unavailable";
317
- } else {
318
- return new _Ref(this.id, this.controlledAccount, this.schema).value;
336
+ setListener(listener) {
337
+ this.subscribers.add(listener);
338
+ this.triggerUpdate();
339
+ }
340
+ subscribeToKey(key) {
341
+ if (this.resolve === true || !this.resolve) {
342
+ this.resolve = {};
343
+ }
344
+ if (this.resolve.$each || key in this.resolve) {
345
+ return;
346
+ }
347
+ this.resolve[key] = true;
348
+ if (this.value.type !== "loaded") {
349
+ return;
350
+ }
351
+ const value = this.value.value;
352
+ this.silenceUpdates = true;
353
+ if (value._type === "CoMap" || value._type === "Account") {
354
+ const map = value;
355
+ const id = this.loadCoMapKey(map, key, true);
356
+ if (id) {
357
+ this.autoloaded.add(id);
358
+ }
359
+ } else if (value._type === "CoList") {
360
+ const list = value;
361
+ const id = this.loadCoListKey(list, key, true);
362
+ if (id) {
363
+ this.autoloaded.add(id);
364
+ }
319
365
  }
366
+ this.silenceUpdates = false;
320
367
  }
321
- syncLoad() {
322
- const node = "node" in this.controlledAccount ? this.controlledAccount.node : this.controlledAccount._raw.core.node;
323
- const entry = node.coValuesStore.get(
324
- this.id
368
+ subscribeToId(id, descriptor) {
369
+ if (this.idsSubscribed.has(id) || this.childValues.has(id)) {
370
+ return;
371
+ }
372
+ this.idsSubscribed.add(id);
373
+ this.autoloaded.add(id);
374
+ this.silenceUpdates = true;
375
+ this.childValues.set(id, { type: "unloaded", id });
376
+ const child = new _SubscriptionScope(
377
+ this.node,
378
+ true,
379
+ id,
380
+ descriptor
325
381
  );
326
- if (entry.highLevelState === "available") {
327
- return new _Ref(this.id, this.controlledAccount, this.schema).value;
382
+ this.childNodes.set(id, child);
383
+ child.setListener((value) => this.handleChildUpdate(id, value));
384
+ this.silenceUpdates = false;
385
+ }
386
+ loadChildren() {
387
+ const { resolve } = this;
388
+ if (this.value.type !== "loaded") {
389
+ return false;
328
390
  }
329
- return void 0;
391
+ const value = this.value.value;
392
+ const depth = typeof resolve !== "object" || resolve === null ? {} : resolve;
393
+ let hasChanged = false;
394
+ const idsToLoad = new Set(this.idsSubscribed);
395
+ const coValueType = value._type;
396
+ if (Object.keys(depth).length > 0) {
397
+ if (coValueType === "CoMap" || coValueType === "Account") {
398
+ const map = value;
399
+ const keys = "$each" in depth ? map._raw.keys() : Object.keys(depth);
400
+ for (const key of keys) {
401
+ const id = this.loadCoMapKey(map, key, depth[key] ?? depth.$each);
402
+ if (id) {
403
+ idsToLoad.add(id);
404
+ }
405
+ }
406
+ } else if (value._type === "CoList") {
407
+ const list = value;
408
+ const descriptor = list.getItemsDescriptor();
409
+ if (descriptor && isRefEncoded(descriptor)) {
410
+ list._raw.processNewTransactions();
411
+ const entries = list._raw.entries();
412
+ const keys = "$each" in depth ? Object.keys(entries) : Object.keys(depth);
413
+ for (const key of keys) {
414
+ const id = this.loadCoListKey(list, key, depth[key] ?? depth.$each);
415
+ if (id) {
416
+ idsToLoad.add(id);
417
+ }
418
+ }
419
+ }
420
+ } else if (value._type === "CoStream") {
421
+ const stream = value;
422
+ const descriptor = stream.getItemsDescriptor();
423
+ if (descriptor && isRefEncoded(descriptor)) {
424
+ for (const session of stream._raw.sessions()) {
425
+ const values = stream._raw.items[session] ?? [];
426
+ for (const [i, item] of values.entries()) {
427
+ const key = `${session}/${i}`;
428
+ if (!depth.$each && !depth[key]) {
429
+ continue;
430
+ }
431
+ const id = item.value;
432
+ if (id) {
433
+ idsToLoad.add(id);
434
+ this.loadChildNode(id, depth[key] ?? depth.$each, descriptor);
435
+ this.validationErrors.delete(key);
436
+ } else if (!descriptor.optional) {
437
+ this.validationErrors.set(
438
+ key,
439
+ new JazzError(void 0, "unavailable", [
440
+ {
441
+ code: "validationError",
442
+ message: `The ref on position ${key} requested on ${stream.constructor.name} is missing`,
443
+ params: {},
444
+ path: [key]
445
+ }
446
+ ])
447
+ );
448
+ }
449
+ }
450
+ }
451
+ }
452
+ }
453
+ }
454
+ this.errorFromChildren = this.computeChildErrors();
455
+ for (const id of this.childNodes.keys()) {
456
+ if (!idsToLoad.has(id)) {
457
+ hasChanged = true;
458
+ const childNode = this.childNodes.get(id);
459
+ if (childNode) {
460
+ childNode.destroy();
461
+ }
462
+ this.childNodes.delete(id);
463
+ this.childValues.delete(id);
464
+ }
465
+ }
466
+ return hasChanged;
330
467
  }
331
- async load() {
332
- const result = await this.loadHelper();
333
- if (result === "unavailable") {
468
+ loadCoMapKey(map, key, depth) {
469
+ const id = map._raw.get(key);
470
+ const descriptor = map.getDescriptor(key);
471
+ if (!descriptor) {
472
+ this.childErrors.set(
473
+ key,
474
+ new JazzError(void 0, "unavailable", [
475
+ {
476
+ code: "validationError",
477
+ message: `The ref ${key} requested on ${map.constructor.name} is not defined in the schema`,
478
+ params: {},
479
+ path: [key]
480
+ }
481
+ ])
482
+ );
334
483
  return void 0;
335
- } else {
336
- return result;
337
- }
338
- }
339
- accessFrom(fromScopeValue, key) {
340
- const subScope = subscriptionsScopes.get(fromScopeValue);
341
- subScope?.onRefAccessedOrSet(fromScopeValue.id, this.id);
342
- TRACE_ACCESSES && console.log(subScope?.scopeID, "accessing", fromScopeValue, key, this.id);
343
- if (this.value && subScope) {
344
- subscriptionsScopes.set(this.value, subScope);
345
- }
346
- if (subScope) {
347
- const cached = subScope.cachedValues[this.id];
348
- if (cached) {
349
- TRACE_ACCESSES && console.log("cached", cached);
350
- return cached;
351
- } else if (this.value !== null) {
352
- const freshValueInstance = instantiateRefEncoded(
353
- this.schema,
354
- this.value._raw
484
+ }
485
+ if (isRefEncoded(descriptor)) {
486
+ if (id) {
487
+ this.loadChildNode(id, depth, descriptor, key);
488
+ this.validationErrors.delete(key);
489
+ return id;
490
+ } else if (!descriptor.optional) {
491
+ this.validationErrors.set(
492
+ key,
493
+ new JazzError(void 0, "unavailable", [
494
+ {
495
+ code: "validationError",
496
+ message: `The ref ${key} requested on ${map.constructor.name} is missing`,
497
+ params: {},
498
+ path: [key]
499
+ }
500
+ ])
355
501
  );
356
- TRACE_ACCESSES && console.log("freshValueInstance", freshValueInstance);
357
- subScope.cachedValues[this.id] = freshValueInstance;
358
- subscriptionsScopes.set(freshValueInstance, subScope);
359
- return freshValueInstance;
360
- } else {
361
- return null;
362
502
  }
503
+ }
504
+ return void 0;
505
+ }
506
+ loadCoListKey(list, key, depth) {
507
+ const descriptor = list.getItemsDescriptor();
508
+ if (!descriptor || !isRefEncoded(descriptor)) {
509
+ return void 0;
510
+ }
511
+ const entries = list._raw.entries();
512
+ const entry = entries[Number(key)];
513
+ if (!entry) {
514
+ return void 0;
515
+ }
516
+ const id = entry.value;
517
+ if (id) {
518
+ this.loadChildNode(id, depth, descriptor, key);
519
+ this.validationErrors.delete(key);
520
+ return id;
521
+ } else if (!descriptor.optional) {
522
+ this.validationErrors.set(
523
+ key,
524
+ new JazzError(void 0, "unavailable", [
525
+ {
526
+ code: "validationError",
527
+ message: `The ref on position ${key} requested on ${list.constructor.name} is missing`,
528
+ params: {},
529
+ path: [key]
530
+ }
531
+ ])
532
+ );
533
+ }
534
+ return void 0;
535
+ }
536
+ loadChildNode(id, query, descriptor, key) {
537
+ if (this.childValues.has(id)) {
538
+ return;
539
+ }
540
+ this.childValues.set(id, { type: "unloaded", id });
541
+ const child = new _SubscriptionScope(
542
+ this.node,
543
+ query,
544
+ id,
545
+ descriptor
546
+ );
547
+ this.childNodes.set(id, child);
548
+ child.setListener((value) => this.handleChildUpdate(id, value, key));
549
+ }
550
+ destroy() {
551
+ this.subscription.unsubscribe();
552
+ this.subscribers.clear();
553
+ this.childNodes.forEach((child) => child.destroy());
554
+ }
555
+ };
556
+
557
+ // src/subscribe/index.ts
558
+ function getSubscriptionScope(value) {
559
+ const subscriptionScope = value._subscriptionScope;
560
+ if (subscriptionScope) {
561
+ return subscriptionScope;
562
+ }
563
+ const node = value._raw.core.node;
564
+ const resolve = true;
565
+ const id = value.id;
566
+ const newSubscriptionScope = new SubscriptionScope(node, resolve, id, {
567
+ ref: value.constructor,
568
+ optional: false
569
+ });
570
+ Object.defineProperty(value, "_subscriptionScope", {
571
+ value: subscriptionScope,
572
+ writable: false,
573
+ enumerable: false,
574
+ configurable: false
575
+ });
576
+ return newSubscriptionScope;
577
+ }
578
+ function accessChildByKey(parent, childId, key) {
579
+ const subscriptionScope = getSubscriptionScope(parent);
580
+ if (!subscriptionScope.childValues.has(childId)) {
581
+ subscriptionScope.subscribeToKey(key);
582
+ }
583
+ const value = subscriptionScope.childValues.get(childId);
584
+ if (value?.type === "loaded") {
585
+ return value.value;
586
+ } else {
587
+ return null;
588
+ }
589
+ }
590
+ function accessChildById(parent, childId, schema) {
591
+ const subscriptionScope = getSubscriptionScope(parent);
592
+ subscriptionScope.subscribeToId(childId, schema);
593
+ const value = subscriptionScope.childValues.get(childId);
594
+ if (value?.type === "loaded") {
595
+ return value.value;
596
+ } else {
597
+ return null;
598
+ }
599
+ }
600
+
601
+ // src/implementation/refs.ts
602
+ var Ref = class {
603
+ constructor(id, controlledAccount, schema, parent) {
604
+ this.id = id;
605
+ this.controlledAccount = controlledAccount;
606
+ this.schema = schema;
607
+ this.parent = parent;
608
+ if (!isRefEncoded(schema)) {
609
+ throw new Error("Ref must be constructed with a ref schema");
610
+ }
611
+ }
612
+ async load() {
613
+ const subscriptionScope = getSubscriptionScope(this.parent);
614
+ subscriptionScope.subscribeToId(this.id, this.schema);
615
+ const node = subscriptionScope.childNodes.get(this.id);
616
+ if (!node) {
617
+ return null;
618
+ }
619
+ const value = node.value;
620
+ if (value?.type === "loaded") {
621
+ return value.value;
363
622
  } else {
364
- return this.value;
623
+ return new Promise((resolve) => {
624
+ const unsubscribe = node.subscribe((value2) => {
625
+ if (value2?.type === "loaded") {
626
+ unsubscribe();
627
+ resolve(value2.value);
628
+ } else if (value2?.type === "unavailable") {
629
+ unsubscribe();
630
+ resolve(null);
631
+ } else if (value2?.type === "unauthorized") {
632
+ unsubscribe();
633
+ resolve(null);
634
+ }
635
+ });
636
+ });
365
637
  }
366
638
  }
639
+ get value() {
640
+ return accessChildById(this.parent, this.id, this.schema);
641
+ }
367
642
  };
368
- function makeRefs(getIdForKey, getKeysWithIds, controlledAccount, refSchemaForKey) {
643
+ function makeRefs(parent, getIdForKey, getKeysWithIds, controlledAccount, refSchemaForKey) {
369
644
  const refs = {};
370
645
  return new Proxy(refs, {
371
646
  get(_target, key) {
@@ -375,7 +650,8 @@ function makeRefs(getIdForKey, getKeysWithIds, controlledAccount, refSchemaForKe
375
650
  yield new Ref(
376
651
  getIdForKey(key2),
377
652
  controlledAccount,
378
- refSchemaForKey(key2)
653
+ refSchemaForKey(key2),
654
+ parent
379
655
  );
380
656
  }
381
657
  };
@@ -389,7 +665,8 @@ function makeRefs(getIdForKey, getKeysWithIds, controlledAccount, refSchemaForKe
389
665
  return new Ref(
390
666
  id,
391
667
  controlledAccount,
392
- refSchemaForKey(key)
668
+ refSchemaForKey(key),
669
+ parent
393
670
  );
394
671
  },
395
672
  ownKeys() {
@@ -498,119 +775,10 @@ function instantiateRefEncoded(schema, raw) {
498
775
  ).fromRaw(raw);
499
776
  }
500
777
 
501
- // src/implementation/subscriptionScope.ts
502
- var subscriptionsScopes = /* @__PURE__ */ new WeakMap();
503
- var SubscriptionScope = class {
504
- constructor(root, rootSchema, onUpdate) {
505
- this.scopeID = `scope-${Math.random().toString(36).slice(2)}`;
506
- this.entries = /* @__PURE__ */ new Map();
507
- this.scheduledUpdate = false;
508
- this.cachedValues = {};
509
- this.parents = {};
510
- this.syncResolution = false;
511
- this.unsubscribeAll = () => {
512
- for (const entry of this.entries.values()) {
513
- if (entry.state === "loaded") {
514
- entry.rawUnsub();
515
- } else {
516
- entry.immediatelyUnsub = true;
517
- }
518
- }
519
- this.entries.clear();
520
- };
521
- this.rootEntry = {
522
- state: "loaded",
523
- value: root._raw,
524
- rawUnsub: () => {
525
- }
526
- // placeholder
527
- };
528
- this.entries.set(root.id, this.rootEntry);
529
- subscriptionsScopes.set(root, this);
530
- this.subscriber = root._loadedAs;
531
- this.scheduleUpdate = () => {
532
- const value = rootSchema.fromRaw(this.rootEntry.value);
533
- subscriptionsScopes.set(value, this);
534
- onUpdate(value, this);
535
- };
536
- this.rootEntry.rawUnsub = root._raw.core.subscribe(
537
- (rawUpdate) => {
538
- if (!rawUpdate) return;
539
- this.rootEntry.value = rawUpdate;
540
- this.scheduleUpdate();
541
- }
542
- );
543
- }
544
- onRefAccessedOrSet(fromId, accessedOrSetId) {
545
- if (!accessedOrSetId) {
546
- return;
547
- }
548
- this.parents[accessedOrSetId] = this.parents[accessedOrSetId] || /* @__PURE__ */ new Set();
549
- this.parents[accessedOrSetId].add(fromId);
550
- if (!this.entries.has(accessedOrSetId)) {
551
- const loadingEntry = {
552
- state: "loading",
553
- immediatelyUnsub: false
554
- };
555
- this.entries.set(accessedOrSetId, loadingEntry);
556
- const node = this.subscriber._type === "Account" ? this.subscriber._raw.core.node : this.subscriber.node;
557
- loadCoValue(
558
- node,
559
- accessedOrSetId,
560
- (core) => {
561
- if (loadingEntry.state === "loading" && loadingEntry.immediatelyUnsub) {
562
- return;
563
- }
564
- if (core !== "unavailable") {
565
- const entry = {
566
- state: "loaded",
567
- rawUnsub: () => {
568
- }
569
- // placeholder
570
- };
571
- this.entries.set(accessedOrSetId, entry);
572
- const rawUnsub = core.subscribe((rawUpdate) => {
573
- if (!rawUpdate) return;
574
- this.invalidate(accessedOrSetId);
575
- this.scheduleUpdate();
576
- });
577
- entry.rawUnsub = rawUnsub;
578
- }
579
- },
580
- this.syncResolution
581
- );
582
- }
583
- }
584
- invalidate(id, seen = /* @__PURE__ */ new Set()) {
585
- if (seen.has(id)) return;
586
- delete this.cachedValues[id];
587
- seen.add(id);
588
- for (const parent of this.parents[id] || []) {
589
- this.invalidate(parent, seen);
590
- }
591
- }
592
- };
593
- function loadCoValue(node, id, callback, syncResolution) {
594
- const entry = node.coValuesStore.get(id);
595
- if (entry.isAvailable() && syncResolution) {
596
- callback(entry.core);
597
- } else {
598
- void node.loadCoValueCore(id).then((core) => {
599
- callback(core);
600
- });
601
- }
602
- }
603
-
604
778
  // src/implementation/createContext.ts
605
779
  import {
606
- ControlledAgent,
607
780
  LocalNode
608
781
  } from "cojson";
609
-
610
- // src/coValues/registeredSchemas.ts
611
- var RegisteredSchemas = {};
612
-
613
- // src/implementation/createContext.ts
614
782
  async function randomSessionProvider(accountID, crypto) {
615
783
  return {
616
784
  sessionID: crypto.newRandomSessionID(accountID),
@@ -737,7 +905,7 @@ async function createJazzContext(options) {
737
905
  await authSecretStorage.setWithoutNotify({
738
906
  accountID: context.account.id,
739
907
  secretSeed,
740
- accountSecret: context.node.account.agentSecret,
908
+ accountSecret: context.node.getCurrentAgent().agentSecret,
741
909
  provider: "anonymous"
742
910
  });
743
911
  }
@@ -752,10 +920,9 @@ async function createAnonymousJazzContext({
752
920
  crypto
753
921
  }) {
754
922
  const agentSecret = crypto.newRandomAgentSecret();
755
- const rawAgent = new ControlledAgent(agentSecret, crypto);
756
923
  const node = new LocalNode(
757
- rawAgent,
758
- crypto.newRandomSessionID(rawAgent.id),
924
+ agentSecret,
925
+ crypto.newRandomSessionID(crypto.getAgentID(agentSecret)),
759
926
  crypto
760
927
  );
761
928
  for (const peer of peersToLoadFrom) {
@@ -854,21 +1021,19 @@ function isCoValueClass(value) {
854
1021
  }
855
1022
  var CoValueBase = class {
856
1023
  get _owner() {
857
- const owner = this._raw.group instanceof RawAccount3 ? RegisteredSchemas["Account"].fromRaw(this._raw.group) : RegisteredSchemas["Group"].fromRaw(this._raw.group);
858
- const subScope = subscriptionsScopes.get(this);
859
- if (subScope) {
860
- subScope.onRefAccessedOrSet(this.id, owner.id);
861
- subscriptionsScopes.set(owner, subScope);
862
- }
1024
+ const owner = coValuesCache.get(
1025
+ this._raw.group,
1026
+ () => this._raw.group instanceof RawAccount3 ? RegisteredSchemas["Account"].fromRaw(this._raw.group) : RegisteredSchemas["Group"].fromRaw(this._raw.group)
1027
+ );
863
1028
  return owner;
864
1029
  }
865
1030
  /** @private */
866
1031
  get _loadedAs() {
867
- const rawAccount = this._raw.core.node.account;
868
- if (rawAccount instanceof RawAccount3) {
1032
+ const agent = this._raw.core.node.getCurrentAgent();
1033
+ if (agent instanceof ControlledAccount) {
869
1034
  return coValuesCache.get(
870
- rawAccount,
871
- () => RegisteredSchemas["Account"].fromRaw(rawAccount)
1035
+ agent.account,
1036
+ () => RegisteredSchemas["Account"].fromRaw(agent.account)
872
1037
  );
873
1038
  }
874
1039
  return new AnonymousJazzAgent(this._raw.core.node);
@@ -897,21 +1062,16 @@ var CoValueBase = class {
897
1062
  }
898
1063
  /** @category Type Helpers */
899
1064
  castAs(cl) {
900
- const casted = cl.fromRaw(this._raw);
901
- const subscriptionScope = subscriptionsScopes.get(this);
902
- if (subscriptionScope) {
903
- subscriptionsScopes.set(casted, subscriptionScope);
904
- }
905
- return casted;
1065
+ return cl.fromRaw(this._raw);
906
1066
  }
907
1067
  };
908
1068
  function loadCoValueWithoutMe(cls, id, options) {
909
- return loadCoValue2(cls, id, {
1069
+ return loadCoValue(cls, id, {
910
1070
  ...options,
911
1071
  loadAs: options?.loadAs ?? activeAccountContext.get()
912
1072
  });
913
1073
  }
914
- function loadCoValue2(cls, id, options) {
1074
+ function loadCoValue(cls, id, options) {
915
1075
  return new Promise((resolve) => {
916
1076
  subscribeToCoValue(
917
1077
  cls,
@@ -919,6 +1079,7 @@ function loadCoValue2(cls, id, options) {
919
1079
  {
920
1080
  resolve: options.resolve,
921
1081
  loadAs: options.loadAs,
1082
+ syncResolution: true,
922
1083
  onUnavailable: () => {
923
1084
  resolve(null);
924
1085
  },
@@ -934,7 +1095,7 @@ function loadCoValue2(cls, id, options) {
934
1095
  });
935
1096
  }
936
1097
  async function ensureCoValueLoaded(existing, options) {
937
- const response = await loadCoValue2(
1098
+ const response = await loadCoValue(
938
1099
  existing.constructor,
939
1100
  existing.id,
940
1101
  {
@@ -982,80 +1143,42 @@ function subscribeToCoValueWithoutMe(cls, id, options, listener) {
982
1143
  );
983
1144
  }
984
1145
  function subscribeToCoValue(cls, id, options, listener) {
985
- const ref2 = new Ref(id, options.loadAs, { ref: cls, optional: false });
1146
+ const loadAs = options.loadAs ?? activeAccountContext.get();
1147
+ const node = "node" in loadAs ? loadAs.node : loadAs._raw.core.node;
1148
+ const resolve = options.resolve ?? true;
986
1149
  let unsubscribed = false;
987
- let unsubscribe;
988
- function subscribe() {
989
- const value = ref2.getValueWithoutAccessCheck();
990
- if (!value) {
991
- options.onUnavailable?.();
992
- return;
993
- }
1150
+ const rootNode = new SubscriptionScope(node, resolve, id, {
1151
+ ref: cls,
1152
+ optional: false
1153
+ });
1154
+ const handleUpdate = (value) => {
994
1155
  if (unsubscribed) return;
995
- const subscription = new SubscriptionScope(
996
- value,
997
- cls,
998
- (update, subscription2) => {
999
- if (subscription2.syncResolution) return;
1000
- if (!ref2.hasReadAccess()) {
1001
- console.error(
1002
- "Not enough permissions to load / subscribe to CoValue",
1003
- id
1004
- );
1005
- options.onUnauthorized?.([]);
1006
- return;
1007
- }
1008
- let result;
1009
- try {
1010
- subscription2.syncResolution = true;
1011
- result = fulfillsDepth(options.resolve, update);
1012
- } catch (e) {
1013
- console.error(
1014
- "Failed to load / subscribe to CoValue",
1015
- e,
1016
- e instanceof Error ? e.stack : void 0
1017
- );
1018
- options.onUnavailable?.();
1019
- return;
1020
- } finally {
1021
- subscription2.syncResolution = false;
1022
- }
1023
- if (result.status === "unauthorized") {
1024
- console.error(
1025
- "Not enough permissions to load / subscribe to CoValue",
1026
- id,
1027
- "on path",
1028
- result.path.join("."),
1029
- "unaccessible value:",
1030
- result.id
1031
- );
1032
- options.onUnauthorized?.(result.path);
1033
- return;
1034
- }
1035
- if (result.status === "fulfilled") {
1036
- listener(update, subscription2.unsubscribeAll);
1037
- }
1038
- }
1039
- );
1040
- unsubscribe = subscription.unsubscribeAll;
1041
- }
1042
- const sync = options.syncResolution ? ref2.syncLoad() : void 0;
1043
- if (sync) {
1044
- subscribe();
1045
- } else {
1046
- ref2.load().then(() => subscribe()).catch((e) => {
1047
- console.error(
1048
- "Failed to load / subscribe to CoValue",
1049
- e,
1050
- e instanceof Error ? e.stack : void 0
1051
- );
1156
+ if (value.type === "unavailable") {
1052
1157
  options.onUnavailable?.();
1053
- });
1054
- }
1055
- return function unsubscribeAtAnyPoint() {
1056
- unsubscribed = true;
1057
- unsubscribe && unsubscribe();
1158
+ console.error(value.toString());
1159
+ } else if (value.type === "unauthorized") {
1160
+ options.onUnauthorized?.();
1161
+ console.error(value.toString());
1162
+ } else if (value.type === "loaded") {
1163
+ listener(value.value, unsubscribe);
1164
+ }
1058
1165
  };
1166
+ let shouldDefer = !options.syncResolution;
1167
+ rootNode.setListener((value) => {
1168
+ if (shouldDefer) {
1169
+ shouldDefer = false;
1170
+ Promise.resolve().then(() => {
1171
+ handleUpdate(value);
1172
+ });
1173
+ } else {
1174
+ handleUpdate(value);
1175
+ }
1176
+ });
1177
+ function unsubscribe() {
1178
+ unsubscribed = true;
1179
+ rootNode.destroy();
1180
+ }
1181
+ return unsubscribe;
1059
1182
  }
1060
1183
  function createCoValueObservable(initialValue = void 0) {
1061
1184
  let currentValue = initialValue;
@@ -1140,15 +1263,13 @@ function parseGroupCreateOptions(options) {
1140
1263
  }
1141
1264
 
1142
1265
  // src/coValues/inbox.ts
1143
- import {
1144
- RawAccount as RawAccount4
1145
- } from "cojson";
1266
+ import { RawAccount as RawAccount4 } from "cojson";
1146
1267
  function createInboxRoot(account) {
1147
1268
  if (!account.isLocalNodeOwner) {
1148
1269
  throw new Error("Account is not controlled");
1149
1270
  }
1150
1271
  const rawAccount = account._raw;
1151
- const group = rawAccount.createGroup();
1272
+ const group = rawAccount.core.node.createGroup();
1152
1273
  const messagesFeed = group.createStream();
1153
1274
  const inboxRoot = rawAccount.createMap();
1154
1275
  const processedFeed = rawAccount.createStream();
@@ -1224,7 +1345,7 @@ var Inbox = class _Inbox {
1224
1345
  new Error("Unable to load inbox message " + id)
1225
1346
  );
1226
1347
  }
1227
- return loadCoValue2(Schema, message.get("payload"), {
1348
+ return loadCoValue(Schema, message.get("payload"), {
1228
1349
  loadAs: account
1229
1350
  });
1230
1351
  }).then((value) => {
@@ -1369,7 +1490,7 @@ async function acceptInvite(invite, account) {
1369
1490
  if (!account.isLocalNodeOwner) {
1370
1491
  throw new Error("Account is not controlled");
1371
1492
  }
1372
- await account._raw.acceptInvite(id, inviteSecret);
1493
+ await account._raw.core.node.acceptInvite(id, inviteSecret);
1373
1494
  return id;
1374
1495
  }
1375
1496
  function getAccountIDfromSessionID(sessionID) {
@@ -1408,32 +1529,34 @@ var _CoMap = class _CoMap extends CoValueBase {
1408
1529
  **/
1409
1530
  get _refs() {
1410
1531
  return makeRefs(
1532
+ this,
1411
1533
  (key) => this._raw.get(key),
1412
1534
  () => {
1413
1535
  const keys = this._raw.keys().filter((key) => {
1414
- const schema = this._schema[key] || this._schema[ItemsSym];
1415
- return schema && schema !== "json" && isRefEncoded(schema);
1536
+ const descriptor = this.getDescriptor(key);
1537
+ return descriptor && descriptor !== "json" && isRefEncoded(descriptor);
1416
1538
  });
1417
1539
  return keys;
1418
1540
  },
1419
1541
  this._loadedAs,
1420
- (key) => this._schema[key] || this._schema[ItemsSym]
1542
+ (key) => this.getDescriptor(key)
1421
1543
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1422
1544
  );
1423
1545
  }
1424
1546
  /** @internal */
1425
1547
  getEditFromRaw(target, rawEdit, descriptor, key) {
1426
1548
  return {
1427
- value: descriptor === "json" ? rawEdit.value : "encoded" in descriptor ? rawEdit.value === null || rawEdit.value === void 0 ? rawEdit.value : descriptor.encoded.decode(rawEdit.value) : new Ref(
1549
+ value: descriptor === "json" ? rawEdit.value : "encoded" in descriptor ? rawEdit.value === null || rawEdit.value === void 0 ? rawEdit.value : descriptor.encoded.decode(rawEdit.value) : accessChildById(target, rawEdit.value, descriptor),
1550
+ ref: descriptor !== "json" && isRefEncoded(descriptor) ? new Ref(
1428
1551
  rawEdit.value,
1429
1552
  target._loadedAs,
1430
- descriptor
1431
- ).accessFrom(target, "_edits." + key + ".value"),
1432
- ref: descriptor !== "json" && isRefEncoded(descriptor) ? new Ref(rawEdit.value, target._loadedAs, descriptor) : void 0,
1433
- by: rawEdit.by && new Ref(rawEdit.by, target._loadedAs, {
1553
+ descriptor,
1554
+ target
1555
+ ) : void 0,
1556
+ by: rawEdit.by && accessChildById(target, rawEdit.by, {
1434
1557
  ref: RegisteredSchemas["Account"],
1435
1558
  optional: false
1436
- }).accessFrom(target, "_edits." + key + ".by"),
1559
+ }),
1437
1560
  madeAt: rawEdit.at,
1438
1561
  key
1439
1562
  };
@@ -1447,7 +1570,8 @@ var _CoMap = class _CoMap extends CoValueBase {
1447
1570
  get(_target, key) {
1448
1571
  const rawEdit = map._raw.lastEditAt(key);
1449
1572
  if (!rawEdit) return void 0;
1450
- const descriptor = map._schema[key];
1573
+ const descriptor = map.getDescriptor(key);
1574
+ if (!descriptor) return void 0;
1451
1575
  return {
1452
1576
  ...map.getEditFromRaw(map, rawEdit, descriptor, key),
1453
1577
  get all() {
@@ -1532,7 +1656,7 @@ var _CoMap = class _CoMap extends CoValueBase {
1532
1656
  };
1533
1657
  for (const key of this._raw.keys()) {
1534
1658
  const tKey = key;
1535
- const descriptor = this._schema[tKey] || this._schema[ItemsSym];
1659
+ const descriptor = this.getDescriptor(tKey);
1536
1660
  if (!descriptor) {
1537
1661
  continue;
1538
1662
  }
@@ -1572,7 +1696,7 @@ var _CoMap = class _CoMap extends CoValueBase {
1572
1696
  if (init)
1573
1697
  for (const key of Object.keys(init)) {
1574
1698
  const initValue = init[key];
1575
- const descriptor = this._schema[key] || this._schema[ItemsSym];
1699
+ const descriptor = this.getDescriptor(key);
1576
1700
  if (!descriptor) {
1577
1701
  continue;
1578
1702
  }
@@ -1591,6 +1715,9 @@ var _CoMap = class _CoMap extends CoValueBase {
1591
1715
  }
1592
1716
  return rawOwner.createMap(rawInit, null, "private", uniqueness);
1593
1717
  }
1718
+ getDescriptor(key) {
1719
+ return this._schema?.[key] || this._schema?.[ItemsSym];
1720
+ }
1594
1721
  /**
1595
1722
  * Declare a Record-like CoMap schema, by extending `CoMap.Record(...)` and passing the value schema using `co`. Keys are always `string`.
1596
1723
  *
@@ -1657,7 +1784,7 @@ var _CoMap = class _CoMap extends CoValueBase {
1657
1784
  meta: null,
1658
1785
  uniqueness: unique
1659
1786
  };
1660
- const crypto = as._type === "Anonymous" ? as.node.crypto : as._raw.core.crypto;
1787
+ const crypto = as._type === "Anonymous" ? as.node.crypto : as._raw.core.node.crypto;
1661
1788
  return cojsonInternals.idforHeader(header, crypto);
1662
1789
  }
1663
1790
  /**
@@ -1678,20 +1805,19 @@ var _CoMap = class _CoMap extends CoValueBase {
1678
1805
  for (const key in newValues) {
1679
1806
  if (Object.prototype.hasOwnProperty.call(newValues, key)) {
1680
1807
  const tKey = key;
1681
- const descriptor = this._schema[tKey] || this._schema[ItemsSym];
1682
- if (tKey in this._schema) {
1683
- const newValue = newValues[tKey];
1684
- const currentValue = this[tKey];
1685
- if (descriptor === "json" || "encoded" in descriptor) {
1686
- if (currentValue !== newValue) {
1687
- this[tKey] = newValue;
1688
- }
1689
- } else if (isRefEncoded(descriptor)) {
1690
- const currentId = currentValue?.id;
1691
- const newId = newValue?.id;
1692
- if (currentId !== newId) {
1693
- this[tKey] = newValue;
1694
- }
1808
+ const descriptor = this.getDescriptor(key);
1809
+ if (!descriptor) continue;
1810
+ const newValue = newValues[tKey];
1811
+ const currentValue = this[tKey];
1812
+ if (descriptor === "json" || "encoded" in descriptor) {
1813
+ if (currentValue !== newValue) {
1814
+ this[tKey] = newValue;
1815
+ }
1816
+ } else if (isRefEncoded(descriptor)) {
1817
+ const currentId = currentValue?.id;
1818
+ const newId = newValue?.id;
1819
+ if (currentId !== newId) {
1820
+ this[tKey] = newValue;
1695
1821
  }
1696
1822
  }
1697
1823
  }
@@ -1716,27 +1842,21 @@ var CoMapProxyHandler = {
1716
1842
  } else if (key in target) {
1717
1843
  return Reflect.get(target, key, receiver);
1718
1844
  } else {
1719
- const schema = target._schema;
1720
- if (!schema) {
1845
+ if (typeof key !== "string") {
1721
1846
  return void 0;
1722
1847
  }
1723
- const descriptor = schema[key] || schema[ItemsSym];
1724
- if (descriptor && typeof key === "string") {
1725
- const raw = target._raw.get(key);
1726
- if (descriptor === "json") {
1727
- return raw;
1728
- } else if ("encoded" in descriptor) {
1729
- return raw === void 0 ? void 0 : descriptor.encoded.decode(raw);
1730
- } else if (isRefEncoded(descriptor)) {
1731
- return raw === void 0 ? void 0 : new Ref(
1732
- raw,
1733
- target._loadedAs,
1734
- descriptor
1735
- ).accessFrom(receiver, key);
1736
- }
1737
- } else {
1848
+ const descriptor = target.getDescriptor(key);
1849
+ if (!descriptor) {
1738
1850
  return void 0;
1739
1851
  }
1852
+ const raw = target._raw.get(key);
1853
+ if (descriptor === "json") {
1854
+ return raw;
1855
+ } else if ("encoded" in descriptor) {
1856
+ return raw === void 0 ? void 0 : descriptor.encoded.decode(raw);
1857
+ } else if (isRefEncoded(descriptor)) {
1858
+ return raw === void 0 ? void 0 : accessChildByKey(target, raw, key);
1859
+ }
1740
1860
  }
1741
1861
  },
1742
1862
  set(target, key, value, receiver) {
@@ -1745,8 +1865,9 @@ var CoMapProxyHandler = {
1745
1865
  target.constructor._schema[key] = value[SchemaInit];
1746
1866
  return true;
1747
1867
  }
1748
- const descriptor = target._schema[key] || target._schema[ItemsSym];
1749
- if (descriptor && typeof key === "string") {
1868
+ const descriptor = target.getDescriptor(key);
1869
+ if (!descriptor) return false;
1870
+ if (typeof key === "string") {
1750
1871
  if (descriptor === "json") {
1751
1872
  target._raw.set(key, value);
1752
1873
  } else if ("encoded" in descriptor) {
@@ -1760,7 +1881,6 @@ var CoMapProxyHandler = {
1760
1881
  }
1761
1882
  } else if (value?.id) {
1762
1883
  target._raw.set(key, value.id);
1763
- subscriptionsScopes.get(target)?.onRefAccessedOrSet(target.id, value.id);
1764
1884
  } else {
1765
1885
  throw new Error(
1766
1886
  `Cannot set reference ${key} to a non-CoValue. Got ${value}`
@@ -1794,7 +1914,7 @@ var CoMapProxyHandler = {
1794
1914
  if (key in target) {
1795
1915
  return Reflect.getOwnPropertyDescriptor(target, key);
1796
1916
  } else {
1797
- const descriptor = target._schema[key] || target._schema[ItemsSym];
1917
+ const descriptor = target.getDescriptor(key);
1798
1918
  if (descriptor || key in target._raw.latest) {
1799
1919
  return {
1800
1920
  enumerable: true,
@@ -1805,7 +1925,7 @@ var CoMapProxyHandler = {
1805
1925
  }
1806
1926
  },
1807
1927
  has(target, key) {
1808
- const descriptor = target._schema?.[key] || target._schema?.[ItemsSym];
1928
+ const descriptor = target.getDescriptor(key);
1809
1929
  if (target._raw && typeof key === "string" && descriptor) {
1810
1930
  return target._raw.get(key) !== void 0;
1811
1931
  } else {
@@ -1813,7 +1933,7 @@ var CoMapProxyHandler = {
1813
1933
  }
1814
1934
  },
1815
1935
  deleteProperty(target, key) {
1816
- const descriptor = target._schema[key] || target._schema[ItemsSym];
1936
+ const descriptor = target.getDescriptor(key);
1817
1937
  if (typeof key === "string" && descriptor) {
1818
1938
  target._raw.delete(key);
1819
1939
  return true;
@@ -1853,8 +1973,8 @@ var Profile = class extends CoMap {
1853
1973
 
1854
1974
  // src/coValues/account.ts
1855
1975
  import {
1976
+ ControlledAccount as ControlledAccount2,
1856
1977
  LocalNode as LocalNode2,
1857
- RawAccount as RawAccount5,
1858
1978
  cojsonInternals as cojsonInternals2
1859
1979
  } from "cojson";
1860
1980
  var _Account = class _Account extends CoValueBase {
@@ -1866,12 +1986,23 @@ var _Account = class _Account extends CoValueBase {
1866
1986
  }
1867
1987
  get _loadedAs() {
1868
1988
  if (this.isLocalNodeOwner) return this;
1869
- const rawAccount = this._raw.core.node.account;
1870
- if (rawAccount instanceof RawAccount5) {
1871
- return coValuesCache.get(rawAccount, () => _Account.fromRaw(rawAccount));
1989
+ const agent = this._raw.core.node.getCurrentAgent();
1990
+ if (agent instanceof ControlledAccount2) {
1991
+ return coValuesCache.get(
1992
+ agent.account,
1993
+ () => _Account.fromRaw(agent.account)
1994
+ );
1872
1995
  }
1873
1996
  return new AnonymousJazzAgent(this._raw.core.node);
1874
1997
  }
1998
+ getDescriptor(key) {
1999
+ if (key === "profile") {
2000
+ return this._schema.profile;
2001
+ } else if (key === "root") {
2002
+ return this._schema.root;
2003
+ }
2004
+ return void 0;
2005
+ }
1875
2006
  get _refs() {
1876
2007
  const profileID = this._raw.get("profile");
1877
2008
  const rootID = this._raw.get("root");
@@ -1879,13 +2010,15 @@ var _Account = class _Account extends CoValueBase {
1879
2010
  profile: profileID && new Ref(
1880
2011
  profileID,
1881
2012
  this._loadedAs,
1882
- this._schema.profile
2013
+ this._schema.profile,
2014
+ this
1883
2015
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1884
2016
  ),
1885
2017
  root: rootID && new Ref(
1886
2018
  rootID,
1887
2019
  this._loadedAs,
1888
- this._schema.root
2020
+ this._schema.root,
2021
+ this
1889
2022
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1890
2023
  )
1891
2024
  };
@@ -1901,7 +2034,7 @@ var _Account = class _Account extends CoValueBase {
1901
2034
  if (!("fromRaw" in options)) {
1902
2035
  throw new Error("Can only construct account from raw or with .create()");
1903
2036
  }
1904
- this.isLocalNodeOwner = options.fromRaw.id == options.fromRaw.core.node.account.id;
2037
+ this.isLocalNodeOwner = options.fromRaw.id == options.fromRaw.core.node.getCurrentAgent().id;
1905
2038
  Object.defineProperties(this, {
1906
2039
  id: {
1907
2040
  value: options.fromRaw.id,
@@ -1933,10 +2066,15 @@ var _Account = class _Account extends CoValueBase {
1933
2066
  return [];
1934
2067
  }
1935
2068
  get members() {
1936
- const ref2 = new Ref(this.id, this._loadedAs, {
1937
- ref: () => this.constructor,
1938
- optional: false
1939
- });
2069
+ const ref2 = new Ref(
2070
+ this.id,
2071
+ this._loadedAs,
2072
+ {
2073
+ ref: () => this.constructor,
2074
+ optional: false
2075
+ },
2076
+ this
2077
+ );
1940
2078
  return [{ id: this.id, role: "admin", ref: ref2, account: this }];
1941
2079
  }
1942
2080
  canRead(value) {
@@ -1954,11 +2092,11 @@ var _Account = class _Account extends CoValueBase {
1954
2092
  if (!this.isLocalNodeOwner) {
1955
2093
  throw new Error("Only a controlled account can accept invites");
1956
2094
  }
1957
- await this._raw.acceptInvite(
2095
+ await this._raw.core.node.acceptInvite(
1958
2096
  valueID,
1959
2097
  inviteSecret
1960
2098
  );
1961
- return loadCoValue2(coValueClass, valueID, {
2099
+ return loadCoValue(coValueClass, valueID, {
1962
2100
  loadAs: this
1963
2101
  });
1964
2102
  }
@@ -1995,7 +2133,7 @@ var _Account = class _Account extends CoValueBase {
1995
2133
  }
1996
2134
  static fromNode(node) {
1997
2135
  return new this({
1998
- fromRaw: node.account
2136
+ fromRaw: node.expectCurrentAccount("jazz-tools/Account.fromNode")
1999
2137
  });
2000
2138
  }
2001
2139
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -2081,15 +2219,13 @@ _Account._schema = {
2081
2219
  var Account = _Account;
2082
2220
  var AccountAndGroupProxyHandler = {
2083
2221
  get(target, key, receiver) {
2084
- if (key === "profile") {
2085
- const ref2 = target._refs.profile;
2086
- return ref2 ? ref2.accessFrom(receiver, "profile") : (
2087
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
2088
- void 0
2089
- );
2090
- } else if (key === "root") {
2091
- const ref2 = target._refs.root;
2092
- return ref2 ? ref2.accessFrom(receiver, "root") : void 0;
2222
+ if (key === "profile" || key === "root") {
2223
+ const id = target._raw.get(key);
2224
+ if (id) {
2225
+ return accessChildByKey(target, id, key);
2226
+ } else {
2227
+ return void 0;
2228
+ }
2093
2229
  } else {
2094
2230
  return Reflect.get(target, key, receiver);
2095
2231
  }
@@ -2107,13 +2243,11 @@ var AccountAndGroupProxyHandler = {
2107
2243
  "trusting"
2108
2244
  );
2109
2245
  }
2110
- subscriptionsScopes.get(receiver)?.onRefAccessedOrSet(target.id, value.id);
2111
2246
  return true;
2112
2247
  } else if (key === "root") {
2113
2248
  if (value) {
2114
2249
  target._raw.set("root", value.id);
2115
2250
  }
2116
- subscriptionsScopes.get(receiver)?.onRefAccessedOrSet(target.id, value.id);
2117
2251
  return true;
2118
2252
  } else {
2119
2253
  return Reflect.set(target, key, value, receiver);
@@ -2219,6 +2353,9 @@ var _CoFeed = class _CoFeed extends CoValueBase {
2219
2353
  }
2220
2354
  return instance;
2221
2355
  }
2356
+ getItemsDescriptor() {
2357
+ return this._schema?.[ItemsSym];
2358
+ }
2222
2359
  /**
2223
2360
  * Push items to this `CoFeed`
2224
2361
  *
@@ -2330,9 +2467,10 @@ function entryFromRawEntry(accessFrom, rawEntry, loadedAs, accountID, itemField)
2330
2467
  } else if ("encoded" in itemField) {
2331
2468
  return itemField.encoded.decode(rawEntry.value);
2332
2469
  } else if (isRefEncoded(itemField)) {
2333
- return this.ref?.accessFrom(
2470
+ return accessChildById(
2334
2471
  accessFrom,
2335
- rawEntry.by + rawEntry.tx.sessionID + rawEntry.tx.txIndex + ".value"
2472
+ rawEntry.value,
2473
+ itemField
2336
2474
  );
2337
2475
  } else {
2338
2476
  throw new Error("Invalid item field schema");
@@ -2344,20 +2482,18 @@ function entryFromRawEntry(accessFrom, rawEntry, loadedAs, accountID, itemField)
2344
2482
  return new Ref(
2345
2483
  rawId,
2346
2484
  loadedAs,
2347
- itemField
2485
+ itemField,
2486
+ accessFrom
2348
2487
  );
2349
2488
  } else {
2350
2489
  return void 0;
2351
2490
  }
2352
2491
  },
2353
2492
  get by() {
2354
- return accountID && new Ref(accountID, loadedAs, {
2493
+ return accountID && accessChildById(accessFrom, accountID, {
2355
2494
  ref: RegisteredSchemas["Account"],
2356
2495
  optional: false
2357
- })?.accessFrom(
2358
- accessFrom,
2359
- rawEntry.by + rawEntry.tx.sessionID + rawEntry.tx.txIndex + ".by"
2360
- );
2496
+ });
2361
2497
  },
2362
2498
  madeAt: rawEntry.at,
2363
2499
  tx: rawEntry.tx
@@ -2648,11 +2784,8 @@ var FileStream = class extends CoValueBase {
2648
2784
  static load(id, options) {
2649
2785
  return loadCoValueWithoutMe(this, id, options);
2650
2786
  }
2651
- /**
2652
- * Subscribe to a `FileStream`, when you have an ID but don't have a `FileStream` instance yet
2653
- * @category Subscription & Loading
2654
- */
2655
- static subscribe(id, options, listener) {
2787
+ static subscribe(id, ...args) {
2788
+ const { options, listener } = parseSubscribeRestArgs(args);
2656
2789
  return subscribeToCoValueWithoutMe(this, id, options, listener);
2657
2790
  }
2658
2791
  /**
@@ -2673,7 +2806,7 @@ var FileStream = class extends CoValueBase {
2673
2806
  };
2674
2807
 
2675
2808
  // src/coValues/coList.ts
2676
- import { RawAccount as RawAccount6 } from "cojson";
2809
+ import { ControlledAccount as ControlledAccount3, RawAccount as RawAccount6 } from "cojson";
2677
2810
  import { calcPatch } from "fast-myers-diff";
2678
2811
  var _CoList = class _CoList extends Array {
2679
2812
  /**
@@ -2732,6 +2865,7 @@ var _CoList = class _CoList extends Array {
2732
2865
  **/
2733
2866
  get _refs() {
2734
2867
  return makeRefs(
2868
+ this,
2735
2869
  (idx) => this._raw.get(idx),
2736
2870
  () => Array.from({ length: this._raw.entries().length }, (_, idx) => idx),
2737
2871
  this._loadedAs,
@@ -2743,11 +2877,11 @@ var _CoList = class _CoList extends Array {
2743
2877
  throw new Error("Not implemented");
2744
2878
  }
2745
2879
  get _loadedAs() {
2746
- const rawAccount = this._raw.core.node.account;
2747
- if (rawAccount instanceof RawAccount6) {
2880
+ const agent = this._raw.core.node.getCurrentAgent();
2881
+ if (agent instanceof ControlledAccount3) {
2748
2882
  return coValuesCache.get(
2749
- rawAccount,
2750
- () => RegisteredSchemas["Account"].fromRaw(rawAccount)
2883
+ agent.account,
2884
+ () => RegisteredSchemas["Account"].fromRaw(agent.account)
2751
2885
  );
2752
2886
  }
2753
2887
  return new AnonymousJazzAgent(this._raw.core.node);
@@ -2755,6 +2889,9 @@ var _CoList = class _CoList extends Array {
2755
2889
  static get [(ItemsSym, Symbol.species)]() {
2756
2890
  return Array;
2757
2891
  }
2892
+ getItemsDescriptor() {
2893
+ return this._schema?.[ItemsSym];
2894
+ }
2758
2895
  constructor(options) {
2759
2896
  super();
2760
2897
  Object.defineProperty(this, "_instanceID", {
@@ -2964,12 +3101,7 @@ var _CoList = class _CoList extends Array {
2964
3101
  }
2965
3102
  /** @category Type Helpers */
2966
3103
  castAs(cl) {
2967
- const casted = cl.fromRaw(this._raw);
2968
- const subscriptionScope = subscriptionsScopes.get(this);
2969
- if (subscriptionScope) {
2970
- subscriptionsScopes.set(casted, subscriptionScope);
2971
- }
2972
- return casted;
3104
+ return cl.fromRaw(this._raw);
2973
3105
  }
2974
3106
  /**
2975
3107
  * Wait for the `CoList` to be uploaded to the other peers.
@@ -3001,11 +3133,7 @@ var CoListProxyHandler = {
3001
3133
  } else if ("encoded" in itemDescriptor) {
3002
3134
  return rawValue === void 0 ? void 0 : itemDescriptor.encoded.decode(rawValue);
3003
3135
  } else if (isRefEncoded(itemDescriptor)) {
3004
- return rawValue === void 0 ? void 0 : new Ref(
3005
- rawValue,
3006
- target._loadedAs,
3007
- itemDescriptor
3008
- ).accessFrom(receiver, Number(key));
3136
+ return rawValue === void 0 ? void 0 : accessChildByKey(target, rawValue, key);
3009
3137
  }
3010
3138
  } else if (key === "length") {
3011
3139
  return target._raw.entries().length;
@@ -3077,13 +3205,15 @@ var _Group = class _Group extends CoValueBase {
3077
3205
  profile: profileID && new Ref(
3078
3206
  profileID,
3079
3207
  this._loadedAs,
3080
- this._schema.profile
3208
+ this._schema.profile,
3209
+ this
3081
3210
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3082
3211
  ),
3083
3212
  root: rootID && new Ref(
3084
3213
  rootID,
3085
3214
  this._loadedAs,
3086
- this._schema.root
3215
+ this._schema.root,
3216
+ this
3087
3217
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3088
3218
  )
3089
3219
  };
@@ -3099,7 +3229,7 @@ var _Group = class _Group extends CoValueBase {
3099
3229
  if (!initOwner) throw new Error("No owner provided");
3100
3230
  if (initOwner._type === "Account" && isControlledAccount(initOwner)) {
3101
3231
  const rawOwner = initOwner._raw;
3102
- raw = rawOwner.createGroup();
3232
+ raw = rawOwner.core.node.createGroup();
3103
3233
  } else {
3104
3234
  throw new Error("Can only construct group as a controlled account");
3105
3235
  }
@@ -3139,18 +3269,16 @@ var _Group = class _Group extends CoValueBase {
3139
3269
  const ref2 = new Ref(
3140
3270
  accountID,
3141
3271
  this._loadedAs,
3142
- refEncodedAccountSchema
3272
+ refEncodedAccountSchema,
3273
+ this
3143
3274
  );
3144
- const accessRef = () => ref2.accessFrom(this, "members." + accountID);
3145
- if (!ref2.syncLoad()) {
3146
- console.warn("Account not loaded", accountID);
3147
- }
3275
+ const group = this;
3148
3276
  members.push({
3149
3277
  id: accountID,
3150
3278
  role,
3151
3279
  ref: ref2,
3152
3280
  get account() {
3153
- return accessRef();
3281
+ return accessChildById(group, accountID, refEncodedAccountSchema);
3154
3282
  }
3155
3283
  });
3156
3284
  }
@@ -3220,6 +3348,7 @@ function isAccountID(id) {
3220
3348
 
3221
3349
  // src/coValues/coPlainText.ts
3222
3350
  import {
3351
+ ControlledAccount as ControlledAccount4,
3223
3352
  RawAccount as RawAccount7,
3224
3353
  stringifyOpID
3225
3354
  } from "cojson";
@@ -3229,7 +3358,14 @@ var CoPlainText = class extends String {
3229
3358
  return this._raw.group instanceof RawAccount7 ? Account.fromRaw(this._raw.group) : Group.fromRaw(this._raw.group);
3230
3359
  }
3231
3360
  get _loadedAs() {
3232
- return Account.fromNode(this._raw.core.node);
3361
+ const agent = this._raw.core.node.getCurrentAgent();
3362
+ if (agent instanceof ControlledAccount4) {
3363
+ return coValuesCache.get(
3364
+ agent.account,
3365
+ () => RegisteredSchemas["Account"].fromRaw(agent.account)
3366
+ );
3367
+ }
3368
+ return new AnonymousJazzAgent(this._raw.core.node);
3233
3369
  }
3234
3370
  constructor(options) {
3235
3371
  super("fromRaw" in options ? options.fromRaw.toString() : options.text);
@@ -3343,11 +3479,6 @@ var ImageDefinition = class extends (_b = CoMap, _a = co.items, _b) {
3343
3479
  this[_a] = co.ref(FileStream);
3344
3480
  }
3345
3481
  highestResAvailable(options) {
3346
- if (!subscriptionsScopes.get(this)) {
3347
- console.warn(
3348
- "highestResAvailable() only makes sense when used within a subscription."
3349
- );
3350
- }
3351
3482
  const resolutions = Object.keys(this).filter(
3352
3483
  (key) => key.match(/^\d+x\d+$/)
3353
3484
  );
@@ -4000,10 +4131,10 @@ import { cojsonInternals as cojsonInternals6 } from "cojson";
4000
4131
  function createInviteLink(value, role, baseURL, valueHint) {
4001
4132
  const coValueCore = value._raw.core;
4002
4133
  let currentCoValue = coValueCore;
4003
- while (currentCoValue.header.ruleset.type === "ownedByGroup") {
4134
+ while (currentCoValue.verified.header.ruleset.type === "ownedByGroup") {
4004
4135
  currentCoValue = currentCoValue.getGroup().core;
4005
4136
  }
4006
- const { ruleset, meta } = currentCoValue.header;
4137
+ const { ruleset, meta } = currentCoValue.verified.header;
4007
4138
  if (ruleset.type !== "group" || meta?.type === "account") {
4008
4139
  throw new Error("Can't create invite link for object without group");
4009
4140
  }
@@ -4054,7 +4185,7 @@ export {
4054
4185
  activeAccountContext,
4055
4186
  AnonymousJazzAgent,
4056
4187
  CoValueBase,
4057
- loadCoValue2 as loadCoValue,
4188
+ loadCoValue,
4058
4189
  subscribeToCoValue,
4059
4190
  createCoValueObservable,
4060
4191
  Encoders,
@@ -4089,4 +4220,4 @@ export {
4089
4220
  consumeInviteLink
4090
4221
  };
4091
4222
  /* istanbul ignore file -- @preserve */
4092
- //# sourceMappingURL=chunk-GIZWJXSR.js.map
4223
+ //# sourceMappingURL=chunk-ITSHLDQB.js.map