jazz-tools 0.13.17 → 0.13.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/CHANGELOG.md +17 -0
  3. package/dist/{chunk-PYBQOYML.js → chunk-4HBHY4I7.js} +735 -595
  4. package/dist/chunk-4HBHY4I7.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 +1 -0
  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 +43 -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 +11 -7
  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 +536 -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 +6 -6
  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 +614 -42
  78. package/src/tests/utils.ts +8 -6
  79. package/dist/chunk-PYBQOYML.js.map +0 -1
  80. package/dist/implementation/subscriptionScope.d.ts +0 -34
  81. package/dist/implementation/subscriptionScope.d.ts.map +0 -1
  82. 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,498 @@ 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.autoloadedKeys = /* @__PURE__ */ new Set();
195
+ this.totalValidTransactions = 0;
196
+ this.silenceUpdates = false;
197
+ this.handleChildUpdate = (id, value, key) => {
198
+ if (value.type === "unloaded") {
199
+ return;
200
+ }
201
+ this.childValues.set(id, value);
202
+ if (value.type === "unavailable" || value.type === "unauthorized") {
203
+ this.childErrors.set(id, value.prependPath(key ?? id));
204
+ this.errorFromChildren = this.computeChildErrors();
205
+ } else if (this.errorFromChildren && this.childErrors.has(id)) {
206
+ this.childErrors.delete(id);
207
+ this.errorFromChildren = this.computeChildErrors();
208
+ }
209
+ if (this.shouldSendUpdates()) {
210
+ if (this.value.type === "loaded") {
211
+ this.updateValue(
212
+ createCoValue(this.schema, this.value.value._raw, this)
213
+ );
214
+ }
215
+ }
216
+ this.triggerUpdate();
217
+ };
218
+ this.subscribers = /* @__PURE__ */ new Set();
219
+ this.resolve = resolve;
220
+ this.value = { type: "unloaded", id };
221
+ this.subscription = new CoValueCoreSubscription(node, id, (value) => {
222
+ this.handleUpdate(value);
223
+ });
271
224
  }
272
- getNode() {
273
- return "node" in this.controlledAccount ? this.controlledAccount.node : this.controlledAccount._raw.core.node;
225
+ updateValue(value) {
226
+ this.value = value;
227
+ this.dirty = true;
228
+ }
229
+ handleUpdate(update) {
230
+ if (update === "unavailable") {
231
+ if (this.value.type === "unloaded") {
232
+ this.updateValue(
233
+ new JazzError(this.id, "unavailable", [
234
+ {
235
+ code: "unavailable",
236
+ message: "The value is unavailable",
237
+ params: {
238
+ id: this.id
239
+ },
240
+ path: []
241
+ }
242
+ ])
243
+ );
244
+ }
245
+ this.triggerUpdate();
246
+ return;
247
+ }
248
+ const owner = getOwnerFromRawValue(update);
249
+ const ruleset = update.core.verified.header.ruleset;
250
+ const hasAccess = ruleset.type === "group" || owner.myRole() !== void 0;
251
+ if (!hasAccess) {
252
+ if (this.value.type !== "unauthorized") {
253
+ this.updateValue(
254
+ new JazzError(this.id, "unauthorized", [
255
+ {
256
+ code: "unauthorized",
257
+ message: "The current user is not authorized to access this value",
258
+ params: {
259
+ id: this.id
260
+ },
261
+ path: []
262
+ }
263
+ ])
264
+ );
265
+ this.triggerUpdate();
266
+ }
267
+ return;
268
+ }
269
+ this.silenceUpdates = true;
270
+ if (this.value.type !== "loaded") {
271
+ this.updateValue(createCoValue(this.schema, update, this));
272
+ this.loadChildren();
273
+ } else {
274
+ const hasChanged = update.totalValidTransactions !== this.totalValidTransactions || // Checking the identity of the _raw value makes us cover the cases where the group
275
+ // has been updated and the coValues that don't update the totalValidTransactions value (e.g. FileStream)
276
+ this.value.value._raw !== update;
277
+ if (this.loadChildren()) {
278
+ this.updateValue(createCoValue(this.schema, update, this));
279
+ } else if (hasChanged) {
280
+ this.updateValue(createCoValue(this.schema, update, this));
281
+ }
282
+ }
283
+ this.totalValidTransactions = update.totalValidTransactions;
284
+ this.silenceUpdates = false;
285
+ this.triggerUpdate();
274
286
  }
275
- hasReadAccess() {
276
- const node = this.getNode();
277
- const raw = node.getLoaded(this.id);
278
- if (!raw) {
279
- return true;
287
+ computeChildErrors() {
288
+ let issues = [];
289
+ let errorType = "unavailable";
290
+ if (this.childErrors.size === 0 && this.validationErrors.size === 0) {
291
+ return void 0;
280
292
  }
281
- if (raw instanceof RawAccount || raw instanceof RawGroup) {
282
- return true;
293
+ for (const [key, value] of this.childErrors.entries()) {
294
+ if (this.autoloaded.has(key)) {
295
+ continue;
296
+ }
297
+ errorType = value.type;
298
+ if (value.issues) {
299
+ issues.push(...value.issues);
300
+ }
301
+ }
302
+ for (const value of this.validationErrors.values()) {
303
+ errorType = value.type;
304
+ if (value.issues) {
305
+ issues.push(...value.issues);
306
+ }
307
+ }
308
+ if (issues.length) {
309
+ return new JazzError(this.id, errorType, issues);
283
310
  }
284
- const group = raw.core.getGroup();
285
- if (group instanceof RawAccount) {
286
- if (node.account.id !== group.id) {
311
+ return void 0;
312
+ }
313
+ shouldSendUpdates() {
314
+ if (this.value.type === "unloaded") return false;
315
+ if (this.value.type !== "loaded") return true;
316
+ for (const value of this.childValues.values()) {
317
+ if (value.type === "unloaded" && !this.autoloaded.has(value.id)) {
287
318
  return false;
288
319
  }
289
- } else if (group.myRole() === void 0) {
290
- return false;
291
320
  }
292
321
  return true;
293
322
  }
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;
323
+ triggerUpdate() {
324
+ if (!this.shouldSendUpdates()) return;
325
+ if (!this.dirty) return;
326
+ if (this.subscribers.size === 0) return;
327
+ if (this.silenceUpdates) return;
328
+ const error = this.errorFromChildren;
329
+ const value = this.value;
330
+ if (error) {
331
+ this.subscribers.forEach((listener) => listener(error));
332
+ } else if (value.type !== "unloaded") {
333
+ this.subscribers.forEach((listener) => listener(value));
304
334
  }
335
+ this.dirty = false;
305
336
  }
306
- get value() {
307
- if (!this.hasReadAccess()) {
308
- return null;
309
- }
310
- return this.getValueWithoutAccessCheck();
337
+ subscribe(listener) {
338
+ this.subscribers.add(listener);
339
+ return () => {
340
+ this.subscribers.delete(listener);
341
+ };
311
342
  }
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;
343
+ setListener(listener) {
344
+ this.subscribers.add(listener);
345
+ this.triggerUpdate();
346
+ }
347
+ subscribeToKey(key) {
348
+ if (this.resolve === true || !this.resolve) {
349
+ this.resolve = {};
350
+ }
351
+ if (this.resolve.$each || key in this.resolve) {
352
+ return;
353
+ }
354
+ this.resolve[key] = true;
355
+ this.autoloadedKeys.add(key);
356
+ if (this.value.type !== "loaded") {
357
+ return;
358
+ }
359
+ const value = this.value.value;
360
+ this.silenceUpdates = true;
361
+ if (value._type === "CoMap" || value._type === "Account") {
362
+ const map = value;
363
+ this.loadCoMapKey(map, key, true);
364
+ } else if (value._type === "CoList") {
365
+ const list = value;
366
+ this.loadCoListKey(list, key, true);
319
367
  }
368
+ this.silenceUpdates = false;
320
369
  }
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
370
+ subscribeToId(id, descriptor) {
371
+ if (this.idsSubscribed.has(id) || this.childValues.has(id)) {
372
+ return;
373
+ }
374
+ this.idsSubscribed.add(id);
375
+ this.autoloaded.add(id);
376
+ this.silenceUpdates = true;
377
+ this.childValues.set(id, { type: "unloaded", id });
378
+ const child = new _SubscriptionScope(
379
+ this.node,
380
+ true,
381
+ id,
382
+ descriptor
325
383
  );
326
- if (entry.highLevelState === "available") {
327
- return new _Ref(this.id, this.controlledAccount, this.schema).value;
384
+ this.childNodes.set(id, child);
385
+ child.setListener((value) => this.handleChildUpdate(id, value));
386
+ this.silenceUpdates = false;
387
+ }
388
+ loadChildren() {
389
+ const { resolve } = this;
390
+ if (this.value.type !== "loaded") {
391
+ return false;
328
392
  }
329
- return void 0;
393
+ const value = this.value.value;
394
+ const depth = typeof resolve !== "object" || resolve === null ? {} : resolve;
395
+ let hasChanged = false;
396
+ const idsToLoad = new Set(this.idsSubscribed);
397
+ const coValueType = value._type;
398
+ if (Object.keys(depth).length > 0) {
399
+ if (coValueType === "CoMap" || coValueType === "Account") {
400
+ const map = value;
401
+ const keys = "$each" in depth ? map._raw.keys() : Object.keys(depth);
402
+ for (const key of keys) {
403
+ const id = this.loadCoMapKey(map, key, depth[key] ?? depth.$each);
404
+ if (id) {
405
+ idsToLoad.add(id);
406
+ }
407
+ }
408
+ } else if (value._type === "CoList") {
409
+ const list = value;
410
+ const descriptor = list.getItemsDescriptor();
411
+ if (descriptor && isRefEncoded(descriptor)) {
412
+ list._raw.processNewTransactions();
413
+ const entries = list._raw.entries();
414
+ const keys = "$each" in depth ? Object.keys(entries) : Object.keys(depth);
415
+ for (const key of keys) {
416
+ const id = this.loadCoListKey(list, key, depth[key] ?? depth.$each);
417
+ if (id) {
418
+ idsToLoad.add(id);
419
+ }
420
+ }
421
+ }
422
+ } else if (value._type === "CoStream") {
423
+ const stream = value;
424
+ const descriptor = stream.getItemsDescriptor();
425
+ if (descriptor && isRefEncoded(descriptor)) {
426
+ for (const session of stream._raw.sessions()) {
427
+ const values = stream._raw.items[session] ?? [];
428
+ for (const [i, item] of values.entries()) {
429
+ const key = `${session}/${i}`;
430
+ if (!depth.$each && !depth[key]) {
431
+ continue;
432
+ }
433
+ const id = item.value;
434
+ if (id) {
435
+ idsToLoad.add(id);
436
+ this.loadChildNode(id, depth[key] ?? depth.$each, descriptor);
437
+ this.validationErrors.delete(key);
438
+ } else if (!descriptor.optional) {
439
+ this.validationErrors.set(
440
+ key,
441
+ new JazzError(void 0, "unavailable", [
442
+ {
443
+ code: "validationError",
444
+ message: `The ref on position ${key} requested on ${stream.constructor.name} is missing`,
445
+ params: {},
446
+ path: [key]
447
+ }
448
+ ])
449
+ );
450
+ }
451
+ }
452
+ }
453
+ }
454
+ }
455
+ }
456
+ this.errorFromChildren = this.computeChildErrors();
457
+ for (const id of this.childNodes.keys()) {
458
+ if (!idsToLoad.has(id)) {
459
+ hasChanged = true;
460
+ const childNode = this.childNodes.get(id);
461
+ if (childNode) {
462
+ childNode.destroy();
463
+ }
464
+ this.childNodes.delete(id);
465
+ this.childValues.delete(id);
466
+ }
467
+ }
468
+ return hasChanged;
330
469
  }
331
- async load() {
332
- const result = await this.loadHelper();
333
- if (result === "unavailable") {
470
+ loadCoMapKey(map, key, depth) {
471
+ const id = map._raw.get(key);
472
+ const descriptor = map.getDescriptor(key);
473
+ if (!descriptor) {
474
+ this.childErrors.set(
475
+ key,
476
+ new JazzError(void 0, "unavailable", [
477
+ {
478
+ code: "validationError",
479
+ message: `The ref ${key} requested on ${map.constructor.name} is not defined in the schema`,
480
+ params: {},
481
+ path: [key]
482
+ }
483
+ ])
484
+ );
334
485
  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
486
+ }
487
+ if (isRefEncoded(descriptor)) {
488
+ if (id) {
489
+ this.loadChildNode(id, depth, descriptor, key);
490
+ this.validationErrors.delete(key);
491
+ return id;
492
+ } else if (!descriptor.optional) {
493
+ this.validationErrors.set(
494
+ key,
495
+ new JazzError(void 0, "unavailable", [
496
+ {
497
+ code: "validationError",
498
+ message: `The ref ${key} requested on ${map.constructor.name} is missing`,
499
+ params: {},
500
+ path: [key]
501
+ }
502
+ ])
355
503
  );
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
504
  }
505
+ }
506
+ return void 0;
507
+ }
508
+ loadCoListKey(list, key, depth) {
509
+ const descriptor = list.getItemsDescriptor();
510
+ if (!descriptor || !isRefEncoded(descriptor)) {
511
+ return void 0;
512
+ }
513
+ const entries = list._raw.entries();
514
+ const entry = entries[Number(key)];
515
+ if (!entry) {
516
+ return void 0;
517
+ }
518
+ const id = entry.value;
519
+ if (id) {
520
+ this.loadChildNode(id, depth, descriptor, key);
521
+ this.validationErrors.delete(key);
522
+ return id;
523
+ } else if (!descriptor.optional) {
524
+ this.validationErrors.set(
525
+ key,
526
+ new JazzError(void 0, "unavailable", [
527
+ {
528
+ code: "validationError",
529
+ message: `The ref on position ${key} requested on ${list.constructor.name} is missing`,
530
+ params: {},
531
+ path: [key]
532
+ }
533
+ ])
534
+ );
535
+ }
536
+ return void 0;
537
+ }
538
+ loadChildNode(id, query, descriptor, key) {
539
+ if (this.childValues.has(id)) {
540
+ return;
541
+ }
542
+ if (key && this.autoloadedKeys.has(key)) {
543
+ this.autoloaded.add(id);
544
+ }
545
+ const resolve = typeof query === "object" && query !== null ? { ...query } : query;
546
+ this.childValues.set(id, { type: "unloaded", id });
547
+ const child = new _SubscriptionScope(
548
+ this.node,
549
+ resolve,
550
+ id,
551
+ descriptor
552
+ );
553
+ this.childNodes.set(id, child);
554
+ child.setListener((value) => this.handleChildUpdate(id, value, key));
555
+ }
556
+ destroy() {
557
+ this.subscription.unsubscribe();
558
+ this.subscribers.clear();
559
+ this.childNodes.forEach((child) => child.destroy());
560
+ }
561
+ };
562
+
563
+ // src/subscribe/index.ts
564
+ function getSubscriptionScope(value) {
565
+ const subscriptionScope = value._subscriptionScope;
566
+ if (subscriptionScope) {
567
+ return subscriptionScope;
568
+ }
569
+ const node = value._raw.core.node;
570
+ const resolve = true;
571
+ const id = value.id;
572
+ const newSubscriptionScope = new SubscriptionScope(node, resolve, id, {
573
+ ref: value.constructor,
574
+ optional: false
575
+ });
576
+ Object.defineProperty(value, "_subscriptionScope", {
577
+ value: subscriptionScope,
578
+ writable: false,
579
+ enumerable: false,
580
+ configurable: false
581
+ });
582
+ return newSubscriptionScope;
583
+ }
584
+ function accessChildByKey(parent, childId, key) {
585
+ const subscriptionScope = getSubscriptionScope(parent);
586
+ if (!subscriptionScope.childValues.has(childId)) {
587
+ subscriptionScope.subscribeToKey(key);
588
+ }
589
+ const value = subscriptionScope.childValues.get(childId);
590
+ if (value?.type === "loaded") {
591
+ return value.value;
592
+ } else {
593
+ return null;
594
+ }
595
+ }
596
+ function accessChildById(parent, childId, schema) {
597
+ const subscriptionScope = getSubscriptionScope(parent);
598
+ subscriptionScope.subscribeToId(childId, schema);
599
+ const value = subscriptionScope.childValues.get(childId);
600
+ if (value?.type === "loaded") {
601
+ return value.value;
602
+ } else {
603
+ return null;
604
+ }
605
+ }
606
+
607
+ // src/implementation/refs.ts
608
+ var Ref = class {
609
+ constructor(id, controlledAccount, schema, parent) {
610
+ this.id = id;
611
+ this.controlledAccount = controlledAccount;
612
+ this.schema = schema;
613
+ this.parent = parent;
614
+ if (!isRefEncoded(schema)) {
615
+ throw new Error("Ref must be constructed with a ref schema");
616
+ }
617
+ }
618
+ async load() {
619
+ const subscriptionScope = getSubscriptionScope(this.parent);
620
+ subscriptionScope.subscribeToId(this.id, this.schema);
621
+ const node = subscriptionScope.childNodes.get(this.id);
622
+ if (!node) {
623
+ return null;
624
+ }
625
+ const value = node.value;
626
+ if (value?.type === "loaded") {
627
+ return value.value;
363
628
  } else {
364
- return this.value;
629
+ return new Promise((resolve) => {
630
+ const unsubscribe = node.subscribe((value2) => {
631
+ if (value2?.type === "loaded") {
632
+ unsubscribe();
633
+ resolve(value2.value);
634
+ } else if (value2?.type === "unavailable") {
635
+ unsubscribe();
636
+ resolve(null);
637
+ } else if (value2?.type === "unauthorized") {
638
+ unsubscribe();
639
+ resolve(null);
640
+ }
641
+ });
642
+ });
365
643
  }
366
644
  }
645
+ get value() {
646
+ return accessChildById(this.parent, this.id, this.schema);
647
+ }
367
648
  };
368
- function makeRefs(getIdForKey, getKeysWithIds, controlledAccount, refSchemaForKey) {
649
+ function makeRefs(parent, getIdForKey, getKeysWithIds, controlledAccount, refSchemaForKey) {
369
650
  const refs = {};
370
651
  return new Proxy(refs, {
371
652
  get(_target, key) {
@@ -375,7 +656,8 @@ function makeRefs(getIdForKey, getKeysWithIds, controlledAccount, refSchemaForKe
375
656
  yield new Ref(
376
657
  getIdForKey(key2),
377
658
  controlledAccount,
378
- refSchemaForKey(key2)
659
+ refSchemaForKey(key2),
660
+ parent
379
661
  );
380
662
  }
381
663
  };
@@ -389,7 +671,8 @@ function makeRefs(getIdForKey, getKeysWithIds, controlledAccount, refSchemaForKe
389
671
  return new Ref(
390
672
  id,
391
673
  controlledAccount,
392
- refSchemaForKey(key)
674
+ refSchemaForKey(key),
675
+ parent
393
676
  );
394
677
  },
395
678
  ownKeys() {
@@ -498,119 +781,10 @@ function instantiateRefEncoded(schema, raw) {
498
781
  ).fromRaw(raw);
499
782
  }
500
783
 
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
784
  // src/implementation/createContext.ts
605
785
  import {
606
- ControlledAgent,
607
786
  LocalNode
608
787
  } from "cojson";
609
-
610
- // src/coValues/registeredSchemas.ts
611
- var RegisteredSchemas = {};
612
-
613
- // src/implementation/createContext.ts
614
788
  async function randomSessionProvider(accountID, crypto) {
615
789
  return {
616
790
  sessionID: crypto.newRandomSessionID(accountID),
@@ -737,7 +911,7 @@ async function createJazzContext(options) {
737
911
  await authSecretStorage.setWithoutNotify({
738
912
  accountID: context.account.id,
739
913
  secretSeed,
740
- accountSecret: context.node.account.agentSecret,
914
+ accountSecret: context.node.getCurrentAgent().agentSecret,
741
915
  provider: "anonymous"
742
916
  });
743
917
  }
@@ -752,10 +926,9 @@ async function createAnonymousJazzContext({
752
926
  crypto
753
927
  }) {
754
928
  const agentSecret = crypto.newRandomAgentSecret();
755
- const rawAgent = new ControlledAgent(agentSecret, crypto);
756
929
  const node = new LocalNode(
757
- rawAgent,
758
- crypto.newRandomSessionID(rawAgent.id),
930
+ agentSecret,
931
+ crypto.newRandomSessionID(crypto.getAgentID(agentSecret)),
759
932
  crypto
760
933
  );
761
934
  for (const peer of peersToLoadFrom) {
@@ -854,21 +1027,19 @@ function isCoValueClass(value) {
854
1027
  }
855
1028
  var CoValueBase = class {
856
1029
  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
- }
1030
+ const owner = coValuesCache.get(
1031
+ this._raw.group,
1032
+ () => this._raw.group instanceof RawAccount3 ? RegisteredSchemas["Account"].fromRaw(this._raw.group) : RegisteredSchemas["Group"].fromRaw(this._raw.group)
1033
+ );
863
1034
  return owner;
864
1035
  }
865
1036
  /** @private */
866
1037
  get _loadedAs() {
867
- const rawAccount = this._raw.core.node.account;
868
- if (rawAccount instanceof RawAccount3) {
1038
+ const agent = this._raw.core.node.getCurrentAgent();
1039
+ if (agent instanceof ControlledAccount) {
869
1040
  return coValuesCache.get(
870
- rawAccount,
871
- () => RegisteredSchemas["Account"].fromRaw(rawAccount)
1041
+ agent.account,
1042
+ () => RegisteredSchemas["Account"].fromRaw(agent.account)
872
1043
  );
873
1044
  }
874
1045
  return new AnonymousJazzAgent(this._raw.core.node);
@@ -897,21 +1068,16 @@ var CoValueBase = class {
897
1068
  }
898
1069
  /** @category Type Helpers */
899
1070
  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;
1071
+ return cl.fromRaw(this._raw);
906
1072
  }
907
1073
  };
908
1074
  function loadCoValueWithoutMe(cls, id, options) {
909
- return loadCoValue2(cls, id, {
1075
+ return loadCoValue(cls, id, {
910
1076
  ...options,
911
1077
  loadAs: options?.loadAs ?? activeAccountContext.get()
912
1078
  });
913
1079
  }
914
- function loadCoValue2(cls, id, options) {
1080
+ function loadCoValue(cls, id, options) {
915
1081
  return new Promise((resolve) => {
916
1082
  subscribeToCoValue(
917
1083
  cls,
@@ -919,6 +1085,7 @@ function loadCoValue2(cls, id, options) {
919
1085
  {
920
1086
  resolve: options.resolve,
921
1087
  loadAs: options.loadAs,
1088
+ syncResolution: true,
922
1089
  onUnavailable: () => {
923
1090
  resolve(null);
924
1091
  },
@@ -934,7 +1101,7 @@ function loadCoValue2(cls, id, options) {
934
1101
  });
935
1102
  }
936
1103
  async function ensureCoValueLoaded(existing, options) {
937
- const response = await loadCoValue2(
1104
+ const response = await loadCoValue(
938
1105
  existing.constructor,
939
1106
  existing.id,
940
1107
  {
@@ -982,80 +1149,42 @@ function subscribeToCoValueWithoutMe(cls, id, options, listener) {
982
1149
  );
983
1150
  }
984
1151
  function subscribeToCoValue(cls, id, options, listener) {
985
- const ref2 = new Ref(id, options.loadAs, { ref: cls, optional: false });
1152
+ const loadAs = options.loadAs ?? activeAccountContext.get();
1153
+ const node = "node" in loadAs ? loadAs.node : loadAs._raw.core.node;
1154
+ const resolve = options.resolve ?? true;
986
1155
  let unsubscribed = false;
987
- let unsubscribe;
988
- function subscribe() {
989
- const value = ref2.getValueWithoutAccessCheck();
990
- if (!value) {
991
- options.onUnavailable?.();
992
- return;
993
- }
1156
+ const rootNode = new SubscriptionScope(node, resolve, id, {
1157
+ ref: cls,
1158
+ optional: false
1159
+ });
1160
+ const handleUpdate = (value) => {
994
1161
  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
- );
1162
+ if (value.type === "unavailable") {
1052
1163
  options.onUnavailable?.();
1053
- });
1054
- }
1055
- return function unsubscribeAtAnyPoint() {
1056
- unsubscribed = true;
1057
- unsubscribe && unsubscribe();
1164
+ console.error(value.toString());
1165
+ } else if (value.type === "unauthorized") {
1166
+ options.onUnauthorized?.();
1167
+ console.error(value.toString());
1168
+ } else if (value.type === "loaded") {
1169
+ listener(value.value, unsubscribe);
1170
+ }
1058
1171
  };
1172
+ let shouldDefer = !options.syncResolution;
1173
+ rootNode.setListener((value) => {
1174
+ if (shouldDefer) {
1175
+ shouldDefer = false;
1176
+ Promise.resolve().then(() => {
1177
+ handleUpdate(value);
1178
+ });
1179
+ } else {
1180
+ handleUpdate(value);
1181
+ }
1182
+ });
1183
+ function unsubscribe() {
1184
+ unsubscribed = true;
1185
+ rootNode.destroy();
1186
+ }
1187
+ return unsubscribe;
1059
1188
  }
1060
1189
  function createCoValueObservable(initialValue = void 0) {
1061
1190
  let currentValue = initialValue;
@@ -1140,15 +1269,13 @@ function parseGroupCreateOptions(options) {
1140
1269
  }
1141
1270
 
1142
1271
  // src/coValues/inbox.ts
1143
- import {
1144
- RawAccount as RawAccount4
1145
- } from "cojson";
1272
+ import { RawAccount as RawAccount4 } from "cojson";
1146
1273
  function createInboxRoot(account) {
1147
1274
  if (!account.isLocalNodeOwner) {
1148
1275
  throw new Error("Account is not controlled");
1149
1276
  }
1150
1277
  const rawAccount = account._raw;
1151
- const group = rawAccount.createGroup();
1278
+ const group = rawAccount.core.node.createGroup();
1152
1279
  const messagesFeed = group.createStream();
1153
1280
  const inboxRoot = rawAccount.createMap();
1154
1281
  const processedFeed = rawAccount.createStream();
@@ -1224,7 +1351,7 @@ var Inbox = class _Inbox {
1224
1351
  new Error("Unable to load inbox message " + id)
1225
1352
  );
1226
1353
  }
1227
- return loadCoValue2(Schema, message.get("payload"), {
1354
+ return loadCoValue(Schema, message.get("payload"), {
1228
1355
  loadAs: account
1229
1356
  });
1230
1357
  }).then((value) => {
@@ -1369,7 +1496,7 @@ async function acceptInvite(invite, account) {
1369
1496
  if (!account.isLocalNodeOwner) {
1370
1497
  throw new Error("Account is not controlled");
1371
1498
  }
1372
- await account._raw.acceptInvite(id, inviteSecret);
1499
+ await account._raw.core.node.acceptInvite(id, inviteSecret);
1373
1500
  return id;
1374
1501
  }
1375
1502
  function getAccountIDfromSessionID(sessionID) {
@@ -1408,32 +1535,34 @@ var _CoMap = class _CoMap extends CoValueBase {
1408
1535
  **/
1409
1536
  get _refs() {
1410
1537
  return makeRefs(
1538
+ this,
1411
1539
  (key) => this._raw.get(key),
1412
1540
  () => {
1413
1541
  const keys = this._raw.keys().filter((key) => {
1414
- const schema = this._schema[key] || this._schema[ItemsSym];
1415
- return schema && schema !== "json" && isRefEncoded(schema);
1542
+ const descriptor = this.getDescriptor(key);
1543
+ return descriptor && descriptor !== "json" && isRefEncoded(descriptor);
1416
1544
  });
1417
1545
  return keys;
1418
1546
  },
1419
1547
  this._loadedAs,
1420
- (key) => this._schema[key] || this._schema[ItemsSym]
1548
+ (key) => this.getDescriptor(key)
1421
1549
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1422
1550
  );
1423
1551
  }
1424
1552
  /** @internal */
1425
1553
  getEditFromRaw(target, rawEdit, descriptor, key) {
1426
1554
  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(
1555
+ 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),
1556
+ ref: descriptor !== "json" && isRefEncoded(descriptor) ? new Ref(
1428
1557
  rawEdit.value,
1429
1558
  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, {
1559
+ descriptor,
1560
+ target
1561
+ ) : void 0,
1562
+ by: rawEdit.by && accessChildById(target, rawEdit.by, {
1434
1563
  ref: RegisteredSchemas["Account"],
1435
1564
  optional: false
1436
- }).accessFrom(target, "_edits." + key + ".by"),
1565
+ }),
1437
1566
  madeAt: rawEdit.at,
1438
1567
  key
1439
1568
  };
@@ -1447,7 +1576,8 @@ var _CoMap = class _CoMap extends CoValueBase {
1447
1576
  get(_target, key) {
1448
1577
  const rawEdit = map._raw.lastEditAt(key);
1449
1578
  if (!rawEdit) return void 0;
1450
- const descriptor = map._schema[key];
1579
+ const descriptor = map.getDescriptor(key);
1580
+ if (!descriptor) return void 0;
1451
1581
  return {
1452
1582
  ...map.getEditFromRaw(map, rawEdit, descriptor, key),
1453
1583
  get all() {
@@ -1532,7 +1662,7 @@ var _CoMap = class _CoMap extends CoValueBase {
1532
1662
  };
1533
1663
  for (const key of this._raw.keys()) {
1534
1664
  const tKey = key;
1535
- const descriptor = this._schema[tKey] || this._schema[ItemsSym];
1665
+ const descriptor = this.getDescriptor(tKey);
1536
1666
  if (!descriptor) {
1537
1667
  continue;
1538
1668
  }
@@ -1572,7 +1702,7 @@ var _CoMap = class _CoMap extends CoValueBase {
1572
1702
  if (init)
1573
1703
  for (const key of Object.keys(init)) {
1574
1704
  const initValue = init[key];
1575
- const descriptor = this._schema[key] || this._schema[ItemsSym];
1705
+ const descriptor = this.getDescriptor(key);
1576
1706
  if (!descriptor) {
1577
1707
  continue;
1578
1708
  }
@@ -1591,6 +1721,9 @@ var _CoMap = class _CoMap extends CoValueBase {
1591
1721
  }
1592
1722
  return rawOwner.createMap(rawInit, null, "private", uniqueness);
1593
1723
  }
1724
+ getDescriptor(key) {
1725
+ return this._schema?.[key] || this._schema?.[ItemsSym];
1726
+ }
1594
1727
  /**
1595
1728
  * Declare a Record-like CoMap schema, by extending `CoMap.Record(...)` and passing the value schema using `co`. Keys are always `string`.
1596
1729
  *
@@ -1657,7 +1790,7 @@ var _CoMap = class _CoMap extends CoValueBase {
1657
1790
  meta: null,
1658
1791
  uniqueness: unique
1659
1792
  };
1660
- const crypto = as._type === "Anonymous" ? as.node.crypto : as._raw.core.crypto;
1793
+ const crypto = as._type === "Anonymous" ? as.node.crypto : as._raw.core.node.crypto;
1661
1794
  return cojsonInternals.idforHeader(header, crypto);
1662
1795
  }
1663
1796
  /**
@@ -1678,20 +1811,19 @@ var _CoMap = class _CoMap extends CoValueBase {
1678
1811
  for (const key in newValues) {
1679
1812
  if (Object.prototype.hasOwnProperty.call(newValues, key)) {
1680
1813
  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
- }
1814
+ const descriptor = this.getDescriptor(key);
1815
+ if (!descriptor) continue;
1816
+ const newValue = newValues[tKey];
1817
+ const currentValue = this[tKey];
1818
+ if (descriptor === "json" || "encoded" in descriptor) {
1819
+ if (currentValue !== newValue) {
1820
+ this[tKey] = newValue;
1821
+ }
1822
+ } else if (isRefEncoded(descriptor)) {
1823
+ const currentId = currentValue?.id;
1824
+ const newId = newValue?.id;
1825
+ if (currentId !== newId) {
1826
+ this[tKey] = newValue;
1695
1827
  }
1696
1828
  }
1697
1829
  }
@@ -1716,27 +1848,21 @@ var CoMapProxyHandler = {
1716
1848
  } else if (key in target) {
1717
1849
  return Reflect.get(target, key, receiver);
1718
1850
  } else {
1719
- const schema = target._schema;
1720
- if (!schema) {
1851
+ if (typeof key !== "string") {
1721
1852
  return void 0;
1722
1853
  }
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 {
1854
+ const descriptor = target.getDescriptor(key);
1855
+ if (!descriptor) {
1738
1856
  return void 0;
1739
1857
  }
1858
+ const raw = target._raw.get(key);
1859
+ if (descriptor === "json") {
1860
+ return raw;
1861
+ } else if ("encoded" in descriptor) {
1862
+ return raw === void 0 ? void 0 : descriptor.encoded.decode(raw);
1863
+ } else if (isRefEncoded(descriptor)) {
1864
+ return raw === void 0 ? void 0 : accessChildByKey(target, raw, key);
1865
+ }
1740
1866
  }
1741
1867
  },
1742
1868
  set(target, key, value, receiver) {
@@ -1745,8 +1871,9 @@ var CoMapProxyHandler = {
1745
1871
  target.constructor._schema[key] = value[SchemaInit];
1746
1872
  return true;
1747
1873
  }
1748
- const descriptor = target._schema[key] || target._schema[ItemsSym];
1749
- if (descriptor && typeof key === "string") {
1874
+ const descriptor = target.getDescriptor(key);
1875
+ if (!descriptor) return false;
1876
+ if (typeof key === "string") {
1750
1877
  if (descriptor === "json") {
1751
1878
  target._raw.set(key, value);
1752
1879
  } else if ("encoded" in descriptor) {
@@ -1760,7 +1887,6 @@ var CoMapProxyHandler = {
1760
1887
  }
1761
1888
  } else if (value?.id) {
1762
1889
  target._raw.set(key, value.id);
1763
- subscriptionsScopes.get(target)?.onRefAccessedOrSet(target.id, value.id);
1764
1890
  } else {
1765
1891
  throw new Error(
1766
1892
  `Cannot set reference ${key} to a non-CoValue. Got ${value}`
@@ -1794,7 +1920,7 @@ var CoMapProxyHandler = {
1794
1920
  if (key in target) {
1795
1921
  return Reflect.getOwnPropertyDescriptor(target, key);
1796
1922
  } else {
1797
- const descriptor = target._schema[key] || target._schema[ItemsSym];
1923
+ const descriptor = target.getDescriptor(key);
1798
1924
  if (descriptor || key in target._raw.latest) {
1799
1925
  return {
1800
1926
  enumerable: true,
@@ -1805,7 +1931,7 @@ var CoMapProxyHandler = {
1805
1931
  }
1806
1932
  },
1807
1933
  has(target, key) {
1808
- const descriptor = target._schema?.[key] || target._schema?.[ItemsSym];
1934
+ const descriptor = target.getDescriptor(key);
1809
1935
  if (target._raw && typeof key === "string" && descriptor) {
1810
1936
  return target._raw.get(key) !== void 0;
1811
1937
  } else {
@@ -1813,7 +1939,7 @@ var CoMapProxyHandler = {
1813
1939
  }
1814
1940
  },
1815
1941
  deleteProperty(target, key) {
1816
- const descriptor = target._schema[key] || target._schema[ItemsSym];
1942
+ const descriptor = target.getDescriptor(key);
1817
1943
  if (typeof key === "string" && descriptor) {
1818
1944
  target._raw.delete(key);
1819
1945
  return true;
@@ -1853,8 +1979,8 @@ var Profile = class extends CoMap {
1853
1979
 
1854
1980
  // src/coValues/account.ts
1855
1981
  import {
1982
+ ControlledAccount as ControlledAccount2,
1856
1983
  LocalNode as LocalNode2,
1857
- RawAccount as RawAccount5,
1858
1984
  cojsonInternals as cojsonInternals2
1859
1985
  } from "cojson";
1860
1986
  var _Account = class _Account extends CoValueBase {
@@ -1866,12 +1992,23 @@ var _Account = class _Account extends CoValueBase {
1866
1992
  }
1867
1993
  get _loadedAs() {
1868
1994
  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));
1995
+ const agent = this._raw.core.node.getCurrentAgent();
1996
+ if (agent instanceof ControlledAccount2) {
1997
+ return coValuesCache.get(
1998
+ agent.account,
1999
+ () => _Account.fromRaw(agent.account)
2000
+ );
1872
2001
  }
1873
2002
  return new AnonymousJazzAgent(this._raw.core.node);
1874
2003
  }
2004
+ getDescriptor(key) {
2005
+ if (key === "profile") {
2006
+ return this._schema.profile;
2007
+ } else if (key === "root") {
2008
+ return this._schema.root;
2009
+ }
2010
+ return void 0;
2011
+ }
1875
2012
  get _refs() {
1876
2013
  const profileID = this._raw.get("profile");
1877
2014
  const rootID = this._raw.get("root");
@@ -1879,13 +2016,15 @@ var _Account = class _Account extends CoValueBase {
1879
2016
  profile: profileID && new Ref(
1880
2017
  profileID,
1881
2018
  this._loadedAs,
1882
- this._schema.profile
2019
+ this._schema.profile,
2020
+ this
1883
2021
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1884
2022
  ),
1885
2023
  root: rootID && new Ref(
1886
2024
  rootID,
1887
2025
  this._loadedAs,
1888
- this._schema.root
2026
+ this._schema.root,
2027
+ this
1889
2028
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1890
2029
  )
1891
2030
  };
@@ -1901,7 +2040,7 @@ var _Account = class _Account extends CoValueBase {
1901
2040
  if (!("fromRaw" in options)) {
1902
2041
  throw new Error("Can only construct account from raw or with .create()");
1903
2042
  }
1904
- this.isLocalNodeOwner = options.fromRaw.id == options.fromRaw.core.node.account.id;
2043
+ this.isLocalNodeOwner = options.fromRaw.id == options.fromRaw.core.node.getCurrentAgent().id;
1905
2044
  Object.defineProperties(this, {
1906
2045
  id: {
1907
2046
  value: options.fromRaw.id,
@@ -1933,10 +2072,15 @@ var _Account = class _Account extends CoValueBase {
1933
2072
  return [];
1934
2073
  }
1935
2074
  get members() {
1936
- const ref2 = new Ref(this.id, this._loadedAs, {
1937
- ref: () => this.constructor,
1938
- optional: false
1939
- });
2075
+ const ref2 = new Ref(
2076
+ this.id,
2077
+ this._loadedAs,
2078
+ {
2079
+ ref: () => this.constructor,
2080
+ optional: false
2081
+ },
2082
+ this
2083
+ );
1940
2084
  return [{ id: this.id, role: "admin", ref: ref2, account: this }];
1941
2085
  }
1942
2086
  canRead(value) {
@@ -1954,11 +2098,11 @@ var _Account = class _Account extends CoValueBase {
1954
2098
  if (!this.isLocalNodeOwner) {
1955
2099
  throw new Error("Only a controlled account can accept invites");
1956
2100
  }
1957
- await this._raw.acceptInvite(
2101
+ await this._raw.core.node.acceptInvite(
1958
2102
  valueID,
1959
2103
  inviteSecret
1960
2104
  );
1961
- return loadCoValue2(coValueClass, valueID, {
2105
+ return loadCoValue(coValueClass, valueID, {
1962
2106
  loadAs: this
1963
2107
  });
1964
2108
  }
@@ -1995,7 +2139,7 @@ var _Account = class _Account extends CoValueBase {
1995
2139
  }
1996
2140
  static fromNode(node) {
1997
2141
  return new this({
1998
- fromRaw: node.account
2142
+ fromRaw: node.expectCurrentAccount("jazz-tools/Account.fromNode")
1999
2143
  });
2000
2144
  }
2001
2145
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -2081,15 +2225,13 @@ _Account._schema = {
2081
2225
  var Account = _Account;
2082
2226
  var AccountAndGroupProxyHandler = {
2083
2227
  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;
2228
+ if (key === "profile" || key === "root") {
2229
+ const id = target._raw.get(key);
2230
+ if (id) {
2231
+ return accessChildByKey(target, id, key);
2232
+ } else {
2233
+ return void 0;
2234
+ }
2093
2235
  } else {
2094
2236
  return Reflect.get(target, key, receiver);
2095
2237
  }
@@ -2107,13 +2249,11 @@ var AccountAndGroupProxyHandler = {
2107
2249
  "trusting"
2108
2250
  );
2109
2251
  }
2110
- subscriptionsScopes.get(receiver)?.onRefAccessedOrSet(target.id, value.id);
2111
2252
  return true;
2112
2253
  } else if (key === "root") {
2113
2254
  if (value) {
2114
2255
  target._raw.set("root", value.id);
2115
2256
  }
2116
- subscriptionsScopes.get(receiver)?.onRefAccessedOrSet(target.id, value.id);
2117
2257
  return true;
2118
2258
  } else {
2119
2259
  return Reflect.set(target, key, value, receiver);
@@ -2219,6 +2359,9 @@ var _CoFeed = class _CoFeed extends CoValueBase {
2219
2359
  }
2220
2360
  return instance;
2221
2361
  }
2362
+ getItemsDescriptor() {
2363
+ return this._schema?.[ItemsSym];
2364
+ }
2222
2365
  /**
2223
2366
  * Push items to this `CoFeed`
2224
2367
  *
@@ -2330,9 +2473,10 @@ function entryFromRawEntry(accessFrom, rawEntry, loadedAs, accountID, itemField)
2330
2473
  } else if ("encoded" in itemField) {
2331
2474
  return itemField.encoded.decode(rawEntry.value);
2332
2475
  } else if (isRefEncoded(itemField)) {
2333
- return this.ref?.accessFrom(
2476
+ return accessChildById(
2334
2477
  accessFrom,
2335
- rawEntry.by + rawEntry.tx.sessionID + rawEntry.tx.txIndex + ".value"
2478
+ rawEntry.value,
2479
+ itemField
2336
2480
  );
2337
2481
  } else {
2338
2482
  throw new Error("Invalid item field schema");
@@ -2344,20 +2488,18 @@ function entryFromRawEntry(accessFrom, rawEntry, loadedAs, accountID, itemField)
2344
2488
  return new Ref(
2345
2489
  rawId,
2346
2490
  loadedAs,
2347
- itemField
2491
+ itemField,
2492
+ accessFrom
2348
2493
  );
2349
2494
  } else {
2350
2495
  return void 0;
2351
2496
  }
2352
2497
  },
2353
2498
  get by() {
2354
- return accountID && new Ref(accountID, loadedAs, {
2499
+ return accountID && accessChildById(accessFrom, accountID, {
2355
2500
  ref: RegisteredSchemas["Account"],
2356
2501
  optional: false
2357
- })?.accessFrom(
2358
- accessFrom,
2359
- rawEntry.by + rawEntry.tx.sessionID + rawEntry.tx.txIndex + ".by"
2360
- );
2502
+ });
2361
2503
  },
2362
2504
  madeAt: rawEntry.at,
2363
2505
  tx: rawEntry.tx
@@ -2670,7 +2812,7 @@ var FileStream = class extends CoValueBase {
2670
2812
  };
2671
2813
 
2672
2814
  // src/coValues/coList.ts
2673
- import { RawAccount as RawAccount6 } from "cojson";
2815
+ import { ControlledAccount as ControlledAccount3, RawAccount as RawAccount6 } from "cojson";
2674
2816
  import { calcPatch } from "fast-myers-diff";
2675
2817
  var _CoList = class _CoList extends Array {
2676
2818
  /**
@@ -2729,6 +2871,7 @@ var _CoList = class _CoList extends Array {
2729
2871
  **/
2730
2872
  get _refs() {
2731
2873
  return makeRefs(
2874
+ this,
2732
2875
  (idx) => this._raw.get(idx),
2733
2876
  () => Array.from({ length: this._raw.entries().length }, (_, idx) => idx),
2734
2877
  this._loadedAs,
@@ -2740,11 +2883,11 @@ var _CoList = class _CoList extends Array {
2740
2883
  throw new Error("Not implemented");
2741
2884
  }
2742
2885
  get _loadedAs() {
2743
- const rawAccount = this._raw.core.node.account;
2744
- if (rawAccount instanceof RawAccount6) {
2886
+ const agent = this._raw.core.node.getCurrentAgent();
2887
+ if (agent instanceof ControlledAccount3) {
2745
2888
  return coValuesCache.get(
2746
- rawAccount,
2747
- () => RegisteredSchemas["Account"].fromRaw(rawAccount)
2889
+ agent.account,
2890
+ () => RegisteredSchemas["Account"].fromRaw(agent.account)
2748
2891
  );
2749
2892
  }
2750
2893
  return new AnonymousJazzAgent(this._raw.core.node);
@@ -2752,6 +2895,9 @@ var _CoList = class _CoList extends Array {
2752
2895
  static get [(ItemsSym, Symbol.species)]() {
2753
2896
  return Array;
2754
2897
  }
2898
+ getItemsDescriptor() {
2899
+ return this._schema?.[ItemsSym];
2900
+ }
2755
2901
  constructor(options) {
2756
2902
  super();
2757
2903
  Object.defineProperty(this, "_instanceID", {
@@ -2961,12 +3107,7 @@ var _CoList = class _CoList extends Array {
2961
3107
  }
2962
3108
  /** @category Type Helpers */
2963
3109
  castAs(cl) {
2964
- const casted = cl.fromRaw(this._raw);
2965
- const subscriptionScope = subscriptionsScopes.get(this);
2966
- if (subscriptionScope) {
2967
- subscriptionsScopes.set(casted, subscriptionScope);
2968
- }
2969
- return casted;
3110
+ return cl.fromRaw(this._raw);
2970
3111
  }
2971
3112
  /**
2972
3113
  * Wait for the `CoList` to be uploaded to the other peers.
@@ -2998,11 +3139,7 @@ var CoListProxyHandler = {
2998
3139
  } else if ("encoded" in itemDescriptor) {
2999
3140
  return rawValue === void 0 ? void 0 : itemDescriptor.encoded.decode(rawValue);
3000
3141
  } else if (isRefEncoded(itemDescriptor)) {
3001
- return rawValue === void 0 ? void 0 : new Ref(
3002
- rawValue,
3003
- target._loadedAs,
3004
- itemDescriptor
3005
- ).accessFrom(receiver, Number(key));
3142
+ return rawValue === void 0 ? void 0 : accessChildByKey(target, rawValue, key);
3006
3143
  }
3007
3144
  } else if (key === "length") {
3008
3145
  return target._raw.entries().length;
@@ -3074,13 +3211,15 @@ var _Group = class _Group extends CoValueBase {
3074
3211
  profile: profileID && new Ref(
3075
3212
  profileID,
3076
3213
  this._loadedAs,
3077
- this._schema.profile
3214
+ this._schema.profile,
3215
+ this
3078
3216
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3079
3217
  ),
3080
3218
  root: rootID && new Ref(
3081
3219
  rootID,
3082
3220
  this._loadedAs,
3083
- this._schema.root
3221
+ this._schema.root,
3222
+ this
3084
3223
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3085
3224
  )
3086
3225
  };
@@ -3096,7 +3235,7 @@ var _Group = class _Group extends CoValueBase {
3096
3235
  if (!initOwner) throw new Error("No owner provided");
3097
3236
  if (initOwner._type === "Account" && isControlledAccount(initOwner)) {
3098
3237
  const rawOwner = initOwner._raw;
3099
- raw = rawOwner.createGroup();
3238
+ raw = rawOwner.core.node.createGroup();
3100
3239
  } else {
3101
3240
  throw new Error("Can only construct group as a controlled account");
3102
3241
  }
@@ -3136,18 +3275,16 @@ var _Group = class _Group extends CoValueBase {
3136
3275
  const ref2 = new Ref(
3137
3276
  accountID,
3138
3277
  this._loadedAs,
3139
- refEncodedAccountSchema
3278
+ refEncodedAccountSchema,
3279
+ this
3140
3280
  );
3141
- const accessRef = () => ref2.accessFrom(this, "members." + accountID);
3142
- if (!ref2.syncLoad()) {
3143
- console.warn("Account not loaded", accountID);
3144
- }
3281
+ const group = this;
3145
3282
  members.push({
3146
3283
  id: accountID,
3147
3284
  role,
3148
3285
  ref: ref2,
3149
3286
  get account() {
3150
- return accessRef();
3287
+ return accessChildById(group, accountID, refEncodedAccountSchema);
3151
3288
  }
3152
3289
  });
3153
3290
  }
@@ -3217,6 +3354,7 @@ function isAccountID(id) {
3217
3354
 
3218
3355
  // src/coValues/coPlainText.ts
3219
3356
  import {
3357
+ ControlledAccount as ControlledAccount4,
3220
3358
  RawAccount as RawAccount7,
3221
3359
  stringifyOpID
3222
3360
  } from "cojson";
@@ -3226,7 +3364,14 @@ var CoPlainText = class extends String {
3226
3364
  return this._raw.group instanceof RawAccount7 ? Account.fromRaw(this._raw.group) : Group.fromRaw(this._raw.group);
3227
3365
  }
3228
3366
  get _loadedAs() {
3229
- return Account.fromNode(this._raw.core.node);
3367
+ const agent = this._raw.core.node.getCurrentAgent();
3368
+ if (agent instanceof ControlledAccount4) {
3369
+ return coValuesCache.get(
3370
+ agent.account,
3371
+ () => RegisteredSchemas["Account"].fromRaw(agent.account)
3372
+ );
3373
+ }
3374
+ return new AnonymousJazzAgent(this._raw.core.node);
3230
3375
  }
3231
3376
  constructor(options) {
3232
3377
  super("fromRaw" in options ? options.fromRaw.toString() : options.text);
@@ -3340,11 +3485,6 @@ var ImageDefinition = class extends (_b = CoMap, _a = co.items, _b) {
3340
3485
  this[_a] = co.ref(FileStream);
3341
3486
  }
3342
3487
  highestResAvailable(options) {
3343
- if (!subscriptionsScopes.get(this)) {
3344
- console.warn(
3345
- "highestResAvailable() only makes sense when used within a subscription."
3346
- );
3347
- }
3348
3488
  const resolutions = Object.keys(this).filter(
3349
3489
  (key) => key.match(/^\d+x\d+$/)
3350
3490
  );
@@ -3997,10 +4137,10 @@ import { cojsonInternals as cojsonInternals6 } from "cojson";
3997
4137
  function createInviteLink(value, role, baseURL, valueHint) {
3998
4138
  const coValueCore = value._raw.core;
3999
4139
  let currentCoValue = coValueCore;
4000
- while (currentCoValue.header.ruleset.type === "ownedByGroup") {
4140
+ while (currentCoValue.verified.header.ruleset.type === "ownedByGroup") {
4001
4141
  currentCoValue = currentCoValue.getGroup().core;
4002
4142
  }
4003
- const { ruleset, meta } = currentCoValue.header;
4143
+ const { ruleset, meta } = currentCoValue.verified.header;
4004
4144
  if (ruleset.type !== "group" || meta?.type === "account") {
4005
4145
  throw new Error("Can't create invite link for object without group");
4006
4146
  }
@@ -4051,7 +4191,7 @@ export {
4051
4191
  activeAccountContext,
4052
4192
  AnonymousJazzAgent,
4053
4193
  CoValueBase,
4054
- loadCoValue2 as loadCoValue,
4194
+ loadCoValue,
4055
4195
  subscribeToCoValue,
4056
4196
  createCoValueObservable,
4057
4197
  Encoders,
@@ -4086,4 +4226,4 @@ export {
4086
4226
  consumeInviteLink
4087
4227
  };
4088
4228
  /* istanbul ignore file -- @preserve */
4089
- //# sourceMappingURL=chunk-PYBQOYML.js.map
4229
+ //# sourceMappingURL=chunk-4HBHY4I7.js.map