jazz-tools 0.7.0-alpha.1 → 0.7.0-alpha.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. package/.turbo/turbo-build.log +79 -9
  2. package/CHANGELOG.md +74 -0
  3. package/dist/coValues/account.js +63 -30
  4. package/dist/coValues/account.js.map +1 -1
  5. package/dist/coValues/coList.js +143 -93
  6. package/dist/coValues/coList.js.map +1 -1
  7. package/dist/coValues/coMap.js +145 -159
  8. package/dist/coValues/coMap.js.map +1 -1
  9. package/dist/coValues/coStream.js +140 -66
  10. package/dist/coValues/coStream.js.map +1 -1
  11. package/dist/coValues/extensions/imageDef.js +9 -11
  12. package/dist/coValues/extensions/imageDef.js.map +1 -1
  13. package/dist/coValues/group.js +14 -39
  14. package/dist/coValues/group.js.map +1 -1
  15. package/dist/coValues/interfaces.js +6 -3
  16. package/dist/coValues/interfaces.js.map +1 -1
  17. package/dist/implementation/refs.js +13 -10
  18. package/dist/implementation/refs.js.map +1 -1
  19. package/dist/implementation/schema.js +36 -1
  20. package/dist/implementation/schema.js.map +1 -1
  21. package/dist/index.js +4 -19
  22. package/dist/index.js.map +1 -1
  23. package/dist/tests/coList.test.js +5 -9
  24. package/dist/tests/coList.test.js.map +1 -1
  25. package/dist/tests/coMap.test.js +107 -61
  26. package/dist/tests/coMap.test.js.map +1 -1
  27. package/dist/tests/coStream.test.js +51 -56
  28. package/dist/tests/coStream.test.js.map +1 -1
  29. package/package.json +2 -2
  30. package/src/coValues/account.ts +94 -64
  31. package/src/coValues/coList.ts +186 -115
  32. package/src/coValues/coMap.ts +226 -260
  33. package/src/coValues/coStream.ts +190 -111
  34. package/src/coValues/extensions/imageDef.ts +12 -16
  35. package/src/coValues/group.ts +27 -75
  36. package/src/coValues/interfaces.ts +10 -8
  37. package/src/implementation/refs.ts +43 -18
  38. package/src/implementation/schema.ts +86 -31
  39. package/src/index.ts +10 -25
  40. package/src/tests/coList.test.ts +5 -9
  41. package/src/tests/coMap.test.ts +86 -74
  42. package/src/tests/coStream.test.ts +66 -71
@@ -11,59 +11,80 @@ import type {
11
11
  import { cojsonInternals } from "cojson";
12
12
  import type {
13
13
  CoValue,
14
- EnsureItemNullable,
15
- FieldDescriptor,
16
- FieldDescriptorFor,
14
+ ValidItem,
15
+ Schema,
16
+ SchemaFor,
17
17
  Group,
18
18
  ID,
19
19
  Me,
20
+ IfCo,
20
21
  } from "../internal.js";
21
- import { Account, CoValueBase, ValueRef, inspect } from "../internal.js";
22
- import { Schema } from "@effect/schema";
22
+ import {
23
+ ItemsSym,
24
+ Account,
25
+ CoValueBase,
26
+ Ref,
27
+ inspect,
28
+ co,
29
+ InitValues,
30
+ SchemaInit,
31
+ isRefEncoded,
32
+ } from "../internal.js";
33
+ import { Schema as EffectSchema } from "@effect/schema";
23
34
 
24
35
  export type CoStreamEntry<Item> = {
25
36
  value: NonNullable<Item> extends CoValue ? NonNullable<Item> | null : Item;
26
- ref?: NonNullable<Item> extends CoValue
27
- ? ValueRef<NonNullable<Item>>
28
- : never;
37
+ ref?: NonNullable<Item> extends CoValue ? Ref<NonNullable<Item>> : never;
29
38
  by?: Account;
30
39
  madeAt: Date;
31
40
  tx: CojsonInternalTypes.TransactionID;
32
41
  };
33
42
 
34
- export class CoStream<Item extends EnsureItemNullable<Item, "Co.Stream"> = any>
43
+ export class CoStream<Item extends ValidItem<Item, "CoStream"> = any>
35
44
  extends CoValueBase
36
45
  implements CoValue<"CoStream", RawCoStream>
37
46
  {
38
- id!: ID<this>;
39
- _type!: "CoStream";
47
+ static Of<Item extends ValidItem<Item, "CoStream"> = any>(
48
+ item: IfCo<Item, Item>
49
+ ): typeof CoStream<Item> {
50
+ return class CoStreamOf extends CoStream<Item> {
51
+ [co.items] = item;
52
+ };
53
+ }
54
+
55
+ declare id: ID<this>;
56
+ declare _type: "CoStream";
40
57
  static {
41
58
  this.prototype._type = "CoStream";
42
59
  }
43
- _raw!: RawCoStream;
60
+ declare _raw: RawCoStream;
44
61
 
45
62
  /** @internal This is only a marker type and doesn't exist at runtime */
46
- _item!: Item;
63
+ [ItemsSym]!: Item;
47
64
  static _schema: any;
48
65
  get _schema(): {
49
- _item: FieldDescriptorFor<Item>;
66
+ [ItemsSym]: SchemaFor<Item>;
50
67
  } {
51
68
  return (this.constructor as typeof CoStream)._schema;
52
69
  }
53
70
 
54
- by: {
55
- [key: ID<Account>]: CoStreamEntry<Item>;
56
- } = {};
71
+ [key: ID<Account>]: CoStreamEntry<Item>;
72
+
57
73
  get byMe(): CoStreamEntry<Item> | undefined {
58
- return this.by[this._loadedAs.id];
74
+ return this[this._loadedAs.id];
59
75
  }
60
- in: {
76
+ perSession!: {
61
77
  [key: SessionID]: CoStreamEntry<Item>;
62
- } = {};
78
+ };
63
79
  get inCurrentSession(): CoStreamEntry<Item> | undefined {
64
- return this.in[this._loadedAs.sessionID];
80
+ return this.perSession[this._loadedAs.sessionID];
65
81
  }
66
82
 
83
+ [InitValues]?: {
84
+ init?: Item[];
85
+ owner: Account | Group;
86
+ };
87
+
67
88
  constructor(_init: undefined, options: { fromRaw: RawCoStream });
68
89
  constructor(init: Item[], options: { owner: Account | Group });
69
90
  constructor(
@@ -72,120 +93,62 @@ export class CoStream<Item extends EnsureItemNullable<Item, "Co.Stream"> = any>
72
93
  ) {
73
94
  super();
74
95
 
75
- let raw: RawCoStream;
76
-
77
96
  if ("fromRaw" in options) {
78
- raw = options.fromRaw;
79
- } else {
80
- const rawOwner = options.owner._raw;
81
-
82
- raw = rawOwner.createStream();
83
- }
84
-
85
- Object.defineProperties(this, {
86
- id: {
87
- value: raw.id,
88
- enumerable: false,
89
- },
90
- _raw: { value: raw, enumerable: false },
91
- });
92
-
93
- if (init !== undefined) {
94
- for (const item of init) {
95
- this.pushItem(item);
96
- }
97
- }
98
-
99
- this.updateEntries();
100
- }
101
-
102
- private updateEntries() {
103
- for (const accountID of this._raw.accounts()) {
104
- Object.defineProperty(this.by, accountID, {
105
- get: () => {
106
- const rawEntry = this._raw.lastItemBy(accountID);
107
-
108
- if (!rawEntry) return;
109
- return entryFromRawEntry(
110
- this,
111
- rawEntry,
112
- this._loadedAs,
113
- accountID as unknown as ID<Account>,
114
- this._schema._item
115
- );
97
+ Object.defineProperties(this, {
98
+ id: {
99
+ value: options.fromRaw.id,
100
+ enumerable: false,
116
101
  },
117
- configurable: true,
118
- enumerable: true,
102
+ _raw: { value: options.fromRaw, enumerable: false },
119
103
  });
104
+ } else {
105
+ this[InitValues] = {
106
+ init,
107
+ owner: options.owner,
108
+ };
120
109
  }
121
110
 
122
- for (const sessionID of this._raw.sessions()) {
123
- Object.defineProperty(this.in, sessionID, {
124
- get: () => {
125
- const rawEntry = this._raw.lastItemIn(
126
- sessionID as unknown as SessionID
127
- );
128
-
129
- if (!rawEntry) return;
130
- const by =
131
- cojsonInternals.accountOrAgentIDfromSessionID(
132
- sessionID
133
- );
134
- return entryFromRawEntry(
135
- this,
136
- rawEntry,
137
- this._loadedAs,
138
- cojsonInternals.isAccountID(by)
139
- ? (by as unknown as ID<Account>)
140
- : undefined,
141
- this._schema._item
142
- );
143
- },
144
- configurable: true,
145
- enumerable: true,
146
- });
147
- }
111
+ return new Proxy(this, CoStreamProxyHandler as ProxyHandler<this>);
148
112
  }
149
113
 
150
114
  push(...items: Item[]) {
151
115
  for (const item of items) {
152
116
  this.pushItem(item);
153
117
  }
154
- this.updateEntries();
155
118
  }
156
119
 
157
120
  private pushItem(item: Item) {
158
- const itemDescriptor = this._schema._item as FieldDescriptor;
121
+ const itemDescriptor = this._schema[ItemsSym] as Schema;
159
122
 
160
123
  if (itemDescriptor === "json") {
161
124
  this._raw.push(item as JsonValue);
162
125
  } else if ("encoded" in itemDescriptor) {
163
- this._raw.push(Schema.encodeSync(itemDescriptor.encoded)(item));
164
- } else if ("ref" in itemDescriptor) {
126
+ this._raw.push(EffectSchema.encodeSync(itemDescriptor.encoded)(item));
127
+ } else if (isRefEncoded(itemDescriptor)) {
165
128
  this._raw.push((item as unknown as CoValue).id);
166
129
  }
167
130
  }
168
131
 
169
132
  toJSON() {
170
- const itemDescriptor = this._schema._item as FieldDescriptor;
133
+ const itemDescriptor = this._schema[ItemsSym] as Schema;
171
134
  const mapper =
172
135
  itemDescriptor === "json"
173
136
  ? (v: unknown) => v
174
137
  : "encoded" in itemDescriptor
175
- ? Schema.encodeSync(itemDescriptor.encoded)
138
+ ? EffectSchema.encodeSync(itemDescriptor.encoded)
176
139
  : (v: unknown) => v && (v as CoValue).id;
177
140
 
178
141
  return {
179
142
  id: this.id,
180
143
  _type: this._type,
181
- by: Object.fromEntries(
182
- Object.entries(this.by).map(([account, entry]) => [
144
+ ...Object.fromEntries(
145
+ Object.entries(this).map(([account, entry]) => [
183
146
  account,
184
147
  mapper(entry.value),
185
148
  ])
186
149
  ),
187
150
  in: Object.fromEntries(
188
- Object.entries(this.in).map(([session, entry]) => [
151
+ Object.entries(this.perSession).map(([session, entry]) => [
189
152
  session,
190
153
  mapper(entry.value),
191
154
  ])
@@ -197,9 +160,9 @@ export class CoStream<Item extends EnsureItemNullable<Item, "Co.Stream"> = any>
197
160
  return this.toJSON();
198
161
  }
199
162
 
200
- static encoding<V extends CoStream>(
163
+ static schema<V extends CoStream>(
201
164
  this: { new (...args: any): V } & typeof CoStream,
202
- def: { _item: V["_schema"]["_item"] }
165
+ def: { [ItemsSym]: V["_schema"][ItemsSym] }
203
166
  ) {
204
167
  this._schema ||= {};
205
168
  Object.assign(this._schema, def);
@@ -216,32 +179,32 @@ function entryFromRawEntry<Item>(
216
179
  },
217
180
  loadedAs: Account & Me,
218
181
  accountID: ID<Account> | undefined,
219
- itemField: FieldDescriptor
182
+ itemField: Schema
220
183
  ) {
221
184
  return {
222
185
  get value(): Item | undefined {
223
186
  if (itemField === "json") {
224
187
  return rawEntry.value as Item;
225
188
  } else if ("encoded" in itemField) {
226
- return Schema.decodeSync(itemField.encoded)(rawEntry.value);
227
- } else if ("ref" in itemField) {
189
+ return EffectSchema.decodeSync(itemField.encoded)(rawEntry.value);
190
+ } else if (isRefEncoded(itemField)) {
228
191
  return this.ref?.accessFrom(accessFrom) as Item;
229
192
  }
230
193
  },
231
194
  get ref() {
232
- if (itemField !== "json" && "ref" in itemField) {
195
+ if (itemField !== "json" && isRefEncoded(itemField)) {
233
196
  const rawId = rawEntry.value;
234
- return new ValueRef(
197
+ return new Ref(
235
198
  rawId as unknown as ID<CoValue>,
236
199
  loadedAs,
237
- itemField.ref()
200
+ itemField
238
201
  );
239
202
  }
240
203
  },
241
204
  get by() {
242
205
  return (
243
206
  accountID &&
244
- new ValueRef(
207
+ new Ref(
245
208
  accountID as unknown as ID<Account>,
246
209
  loadedAs,
247
210
  Account
@@ -253,16 +216,132 @@ function entryFromRawEntry<Item>(
253
216
  };
254
217
  }
255
218
 
219
+ function init(stream: CoStream) {
220
+ const init = stream[InitValues];
221
+ if (!init) return;
222
+
223
+ const raw = init.owner._raw.createStream();
224
+
225
+ Object.defineProperties(stream, {
226
+ id: {
227
+ value: raw.id,
228
+ enumerable: false,
229
+ },
230
+ _raw: { value: raw, enumerable: false },
231
+ });
232
+
233
+ if (init.init) {
234
+ stream.push(...init.init);
235
+ }
236
+
237
+ delete stream[InitValues];
238
+ }
239
+
240
+ export const CoStreamProxyHandler: ProxyHandler<CoStream> = {
241
+ get(target, key, receiver) {
242
+ if (typeof key === "string" && key.startsWith("co_")) {
243
+ const rawEntry = target._raw.lastItemBy(key as AccountID);
244
+
245
+ if (!rawEntry) return;
246
+ return entryFromRawEntry(
247
+ receiver,
248
+ rawEntry,
249
+ target._loadedAs,
250
+ key as unknown as ID<Account>,
251
+ target._schema[ItemsSym]
252
+ );
253
+ } else if (key === "perSession") {
254
+ return new Proxy(receiver, CoStreamPerSessionProxyHandler);
255
+ } else {
256
+ return Reflect.get(target, key, receiver);
257
+ }
258
+ },
259
+ set(target, key, value, receiver) {
260
+ if (
261
+ key === ItemsSym &&
262
+ typeof value === "object" &&
263
+ SchemaInit in value
264
+ ) {
265
+ (target.constructor as typeof CoStream)._schema ||= {};
266
+ (target.constructor as typeof CoStream)._schema[ItemsSym] =
267
+ value[SchemaInit];
268
+ init(target);
269
+ return true;
270
+ } else {
271
+ return Reflect.set(target, key, value, receiver);
272
+ }
273
+ },
274
+ defineProperty(target, key, descriptor) {
275
+ if (
276
+ descriptor.value &&
277
+ key === ItemsSym &&
278
+ typeof descriptor.value === "object" &&
279
+ SchemaInit in descriptor.value
280
+ ) {
281
+ (target.constructor as typeof CoStream)._schema ||= {};
282
+ (target.constructor as typeof CoStream)._schema[ItemsSym] =
283
+ descriptor.value[SchemaInit];
284
+ init(target);
285
+ return true;
286
+ } else {
287
+ return Reflect.defineProperty(target, key, descriptor);
288
+ }
289
+ },
290
+ ownKeys(target) {
291
+ const keys = Reflect.ownKeys(target);
292
+
293
+ for (const accountID of target._raw.accounts()) {
294
+ keys.push(accountID);
295
+ }
296
+
297
+ return keys;
298
+ },
299
+ getOwnPropertyDescriptor(target, key) {
300
+ if (typeof key === "string" && key.startsWith("co_")) {
301
+ return {
302
+ configurable: true,
303
+ enumerable: true,
304
+ writable: false,
305
+ };
306
+ } else {
307
+ return Reflect.getOwnPropertyDescriptor(target, key);
308
+ }
309
+ },
310
+ };
311
+
312
+ const CoStreamPerSessionProxyHandler: ProxyHandler<CoStream> = {
313
+ get(target, key, receiver) {
314
+ if (typeof key === "string" && key.includes("session")) {
315
+ const sessionID = key as SessionID;
316
+ const rawEntry = target._raw.lastItemIn(sessionID);
317
+
318
+ if (!rawEntry) return;
319
+ const by = cojsonInternals.accountOrAgentIDfromSessionID(sessionID);
320
+ return entryFromRawEntry(
321
+ target,
322
+ rawEntry,
323
+ target._loadedAs,
324
+ cojsonInternals.isAccountID(by)
325
+ ? (by as unknown as ID<Account>)
326
+ : undefined,
327
+ target._schema[ItemsSym]
328
+ );
329
+ } else {
330
+ return Reflect.get(target, key, receiver);
331
+ }
332
+ },
333
+ };
334
+
256
335
  export class BinaryCoStream
257
336
  extends CoValueBase
258
337
  implements CoValue<"BinaryCoStream", RawBinaryCoStream>
259
338
  {
260
- id!: ID<this>;
261
- _type!: "BinaryCoStream";
262
- _raw!: RawBinaryCoStream;
339
+ declare id: ID<this>;
340
+ declare _type: "BinaryCoStream";
341
+ declare _raw: RawBinaryCoStream;
263
342
 
264
343
  constructor(
265
- init: [] | undefined,
344
+ _init: [] | undefined,
266
345
  options:
267
346
  | {
268
347
  owner: Account | Group;
@@ -1,22 +1,18 @@
1
- import { BinaryCoStream, CoMap, indexSignature, subscriptionsScopes } from '../../internal.js'
1
+ import {
2
+ BinaryCoStream,
3
+ CoMap,
4
+ co,
5
+ subscriptionsScopes,
6
+ } from "../../internal.js";
2
7
 
3
8
  export class ImageDefinition extends CoMap<ImageDefinition> {
4
- declare originalSize: [number, number]
5
- declare placeholderDataURL?: string
9
+ originalSize = co.json<[number, number]>();
10
+ placeholderDataURL? = co.string;
6
11
 
7
- [res: `${number}x${number}`]: BinaryCoStream | null;
8
- declare [indexSignature]: BinaryCoStream | null
12
+ [co.items] = co.ref(BinaryCoStream);
13
+ [res: `${number}x${number}`]: co<BinaryCoStream | null>;
9
14
 
10
- static {
11
- this.prototype._schema
12
- this.encoding({
13
- originalSize: "json",
14
- placeholderDataURL: "json",
15
- [indexSignature]: {ref: () => BinaryCoStream},
16
- })
17
- }
18
-
19
- get _highestResAvailable():
15
+ get highestResAvailable():
20
16
  | { res: `${number}x${number}`; stream: BinaryCoStream }
21
17
  | undefined {
22
18
  if (!subscriptionsScopes.get(this)) {
@@ -56,4 +52,4 @@ export class ImageDefinition extends CoMap<ImageDefinition> {
56
52
  }
57
53
  );
58
54
  }
59
- }
55
+ }
@@ -1,25 +1,17 @@
1
- import type { CoID, Everyone, RawCoMap, RawGroup, Role } from "cojson";
2
- import type {
3
- CoValue,
4
- CoValueClass,
5
- ID,
6
- PrimitiveField,
7
- RefField,
8
- } from "../internal.js";
1
+ import type { Everyone, RawGroup, Role } from "cojson";
2
+ import type { CoValue, ID, JsonEncoded, RefEncoded } from "../internal.js";
9
3
  import {
10
4
  Account,
11
5
  CoMap,
12
6
  CoValueBase,
13
- ValueRef,
7
+ Ref,
8
+ co,
14
9
  isControlledAccount,
10
+ AccountAndGroupProxyHandler,
15
11
  } from "../internal.js";
16
12
 
17
- export class Profile extends CoMap<{ name: string }> {
18
- declare name: string;
19
-
20
- static {
21
- this.encoding({ name: "json" } as any);
22
- }
13
+ export class Profile extends CoMap<{ name: co<string> }> {
14
+ name = co.string;
23
15
  }
24
16
 
25
17
  export class Group<
@@ -31,21 +23,21 @@ export class Group<
31
23
  extends CoValueBase
32
24
  implements CoValue<"Group", RawGroup>
33
25
  {
34
- id!: ID<this>;
35
- _type!: "Group";
26
+ declare id: ID<this>;
27
+ declare _type: "Group";
36
28
  static {
37
29
  this.prototype._type = "Group";
38
30
  }
39
- _raw!: RawGroup;
31
+ declare _raw: RawGroup;
40
32
 
41
33
  static _schema: any;
42
34
  get _schema(): {
43
35
  profile: Def["profile"] extends CoValue
44
- ? RefField<Def["profile"]>
45
- : PrimitiveField;
36
+ ? RefEncoded<Def["profile"]>
37
+ : JsonEncoded;
46
38
  root: Def["root"] extends CoValue
47
- ? RefField<Def["root"]>
48
- : PrimitiveField;
39
+ ? RefEncoded<Def["root"]>
40
+ : JsonEncoded;
49
41
  } {
50
42
  return (this.constructor as typeof Group)._schema;
51
43
  }
@@ -66,10 +58,8 @@ export class Group<
66
58
  root!: Def["root"] extends CoMap ? Def["root"] | null : undefined;
67
59
 
68
60
  get _refs(): {
69
- profile: Def["profile"] extends Profile
70
- ? ValueRef<Def["profile"]>
71
- : never;
72
- root: Def["root"] extends CoMap ? ValueRef<Def["root"]> : never;
61
+ profile: Def["profile"] extends Profile ? Ref<Def["profile"]> : never;
62
+ root: Def["root"] extends CoMap ? Ref<Def["root"]> : never;
73
63
  } {
74
64
  const profileID = this._raw.get("profile") as unknown as
75
65
  | ID<NonNullable<Def["profile"]>>
@@ -80,23 +70,19 @@ export class Group<
80
70
  return {
81
71
  profile:
82
72
  profileID &&
83
- (new ValueRef(
73
+ (new Ref(
84
74
  profileID,
85
75
  this._loadedAs,
86
- (
87
- this._schema.profile as RefField<
88
- NonNullable<Def["profile"]>
89
- >
90
- ).ref()
76
+ this._schema.profile as RefEncoded<
77
+ NonNullable<Def["profile"]>
78
+ >
91
79
  ) as any),
92
80
  root:
93
81
  rootID &&
94
- (new ValueRef(
82
+ (new Ref(
95
83
  rootID,
96
84
  this._loadedAs,
97
- (
98
- this._schema.root as RefField<NonNullable<Def["root"]>>
99
- ).ref()
85
+ this._schema.root as RefEncoded<NonNullable<Def["root"]>>
100
86
  ) as any),
101
87
  };
102
88
  }
@@ -135,35 +121,12 @@ export class Group<
135
121
  enumerable: false,
136
122
  },
137
123
  _raw: { value: raw, enumerable: false },
138
- profile: {
139
- get: () => {
140
- const ref = this._refs.profile;
141
- return ref ? ref.accessFrom(this) : (undefined as any);
142
- },
143
- set: (value: Def["profile"] | null) => {
144
- if (value) {
145
- this._raw.set(
146
- "profile",
147
- value.id as unknown as CoID<RawCoMap>
148
- );
149
- }
150
- },
151
- },
152
- root: {
153
- get: () => {
154
- const ref = this._refs.root;
155
- return ref ? ref.accessFrom(this) : (undefined as any);
156
- },
157
- set: (value: Def["root"] | null) => {
158
- if (value) {
159
- this._raw.set(
160
- "root",
161
- value.id as unknown as CoID<RawCoMap>
162
- );
163
- }
164
- },
165
- },
166
124
  });
125
+
126
+ return new Proxy(
127
+ this,
128
+ AccountAndGroupProxyHandler as ProxyHandler<this>
129
+ );
167
130
  }
168
131
 
169
132
  myRole(): Role | undefined {
@@ -173,15 +136,4 @@ export class Group<
173
136
  addMember(member: Everyone | Account, role: Role) {
174
137
  this._raw.addMember(member === "everyone" ? member : member._raw, role);
175
138
  }
176
-
177
- static define<V extends Account>(
178
- this: CoValueClass<V> & typeof Account,
179
- fields: {
180
- profile: V["_schema"]["profile"];
181
- root: V["_schema"]["root"];
182
- }
183
- ) {
184
- this._schema ||= {};
185
- Object.assign(this._schema, fields);
186
- }
187
139
  }
@@ -7,7 +7,7 @@ import {
7
7
  AccountCtx,
8
8
  Group,
9
9
  SubscriptionScope,
10
- ValueRef,
10
+ Ref,
11
11
  inspect,
12
12
  } from "../internal.js";
13
13
 
@@ -15,10 +15,7 @@ export type SubclassedConstructor<T> = {
15
15
  new (...args: any[]): T;
16
16
  };
17
17
 
18
- export interface CoValueClass<
19
- Value extends CoValue = CoValue,
20
- Init = any,
21
- > {
18
+ export interface CoValueClass<Value extends CoValue = CoValue, Init = any> {
22
19
  /** @category Construction and loading */
23
20
  new (init: Init, options: { owner: Account | Group }): Value;
24
21
 
@@ -81,10 +78,13 @@ export interface CoValue<Type extends string = string, Raw = any> {
81
78
  export function isCoValue(value: any): value is CoValue {
82
79
  return value && value._type !== undefined;
83
80
  }
81
+ export function isCoValueClass(value: any): value is CoValueClass {
82
+ return typeof value === "function" && value.fromRaw !== undefined;
83
+ }
84
84
 
85
85
  /** @category Schemas & CoValues - Abstract interfaces */
86
86
  export type ID<T> = CojsonInternalTypes.RawCoID & {
87
- readonly __type: T;
87
+ __type(_: never): T;
88
88
  };
89
89
 
90
90
  export class CoValueBase implements CoValue {
@@ -117,7 +117,9 @@ export class CoValueBase implements CoValue {
117
117
  ): Effect.Effect<V, UnavailableError, AccountCtx> {
118
118
  return Effect.gen(this, function* (_) {
119
119
  const account = yield* _(AccountCtx);
120
- return yield* _(new ValueRef(id as ID<V>, account, this).loadEf());
120
+ return yield* _(
121
+ new Ref(id as ID<V>, account, this as CoValueClass<V>).loadEf()
122
+ );
121
123
  });
122
124
  }
123
125
 
@@ -129,7 +131,7 @@ export class CoValueBase implements CoValue {
129
131
  onProgress?: (progress: number) => void;
130
132
  }
131
133
  ): Promise<V | undefined> {
132
- return new ValueRef(id as ID<V>, options.as, this).load(
134
+ return new Ref(id as ID<V>, options.as, this as CoValueClass<V>).load(
133
135
  options?.onProgress && { onProgress: options.onProgress }
134
136
  );
135
137
  }