jazz-tools 0.7.0-alpha.6 → 0.7.0-alpha.8

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