jazz-tools 0.7.0-alpha.30 → 0.7.0-alpha.31

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. package/.turbo/turbo-build.log +43 -45
  2. package/CHANGELOG.md +6 -0
  3. package/dist/coValues/account.js +6 -6
  4. package/dist/coValues/account.js.map +1 -1
  5. package/dist/coValues/coList.js +8 -7
  6. package/dist/coValues/coList.js.map +1 -1
  7. package/dist/coValues/coMap.js +6 -3
  8. package/dist/coValues/coMap.js.map +1 -1
  9. package/dist/coValues/coStream.js +9 -3
  10. package/dist/coValues/coStream.js.map +1 -1
  11. package/dist/coValues/extensions/imageDef.js.map +1 -1
  12. package/dist/coValues/group.js +6 -2
  13. package/dist/coValues/group.js.map +1 -1
  14. package/dist/coValues/interfaces.js +1 -1
  15. package/dist/coValues/interfaces.js.map +1 -1
  16. package/dist/implementation/schema.js.map +1 -1
  17. package/dist/tests/coList.test.js +13 -13
  18. package/dist/tests/coList.test.js.map +1 -1
  19. package/dist/tests/coMap.test.js +22 -22
  20. package/dist/tests/coMap.test.js.map +1 -1
  21. package/dist/tests/coStream.test.js +9 -9
  22. package/dist/tests/coStream.test.js.map +1 -1
  23. package/dist/tests/groupsAndAccounts.test.js +6 -4
  24. package/dist/tests/groupsAndAccounts.test.js.map +1 -1
  25. package/package.json +1 -1
  26. package/src/coValues/account.ts +21 -38
  27. package/src/coValues/coList.ts +16 -11
  28. package/src/coValues/coMap.ts +15 -20
  29. package/src/coValues/coStream.ts +32 -17
  30. package/src/coValues/extensions/imageDef.ts +1 -1
  31. package/src/coValues/group.ts +32 -48
  32. package/src/coValues/interfaces.ts +1 -1
  33. package/src/implementation/schema.ts +1 -0
  34. package/src/tests/coList.test.ts +16 -16
  35. package/src/tests/coMap.test.ts +35 -35
  36. package/src/tests/coStream.test.ts +11 -11
  37. package/src/tests/groupsAndAccounts.test.ts +13 -9
@@ -33,12 +33,7 @@ import {
33
33
  } from "../internal.js";
34
34
  import type { Stream } from "effect/Stream";
35
35
 
36
- export class Account<
37
- Def extends { profile: Profile | null; root: CoMap | null } = {
38
- profile: Profile | null;
39
- root: CoMap | null;
40
- },
41
- >
36
+ export class Account
42
37
  extends CoValueBase
43
38
  implements CoValue<"Account", RawAccount | RawControlledAccount>
44
39
  {
@@ -69,23 +64,17 @@ export class Account<
69
64
  : Account.fromNode(this._raw.core.node);
70
65
  }
71
66
 
72
- profile!: NonNullable<Def["profile"]> | null;
73
- root!: NonNullable<Def["root"]> | null;
67
+ declare profile: Profile | null;
68
+ declare root: CoMap | null;
74
69
 
75
- get _refs(): {
76
- profile: NonNullable<Def["profile"]> extends Profile
77
- ? Ref<NonNullable<Def["profile"]>> | null
78
- : null;
79
- root: NonNullable<Def["root"]> extends CoMap
80
- ? Ref<NonNullable<Def["root"]>> | null
81
- : null;
82
- } {
70
+ get _refs() {
83
71
  const profileID = this._raw.get("profile") as unknown as
84
- | ID<NonNullable<Def["profile"]>>
72
+ | ID<NonNullable<this["profile"]>>
85
73
  | undefined;
86
74
  const rootID = this._raw.get("root") as unknown as
87
- | ID<NonNullable<Def["root"]>>
75
+ | ID<NonNullable<this["root"]>>
88
76
  | undefined;
77
+
89
78
  return {
90
79
  profile:
91
80
  profileID &&
@@ -93,35 +82,29 @@ export class Account<
93
82
  profileID,
94
83
  this._loadedAs,
95
84
  this._schema.profile as RefEncoded<
96
- NonNullable<Def["profile"]> & CoValue
85
+ NonNullable<this["profile"]> & CoValue
97
86
  >
98
- ) as any),
87
+ ) as any as NonNullable<this["profile"]> extends Profile
88
+ ? Ref<NonNullable<this["profile"]>> | null
89
+ : null),
99
90
  root:
100
91
  rootID &&
101
92
  (new Ref(
102
93
  rootID,
103
94
  this._loadedAs,
104
95
  this._schema.root as RefEncoded<
105
- NonNullable<Def["root"]> & CoValue
96
+ NonNullable<this["root"]> & CoValue
106
97
  >
107
- ) as any),
98
+ ) as any as NonNullable<this["root"]> extends CoMap
99
+ ? Ref<NonNullable<this["root"]>> | null
100
+ : null),
108
101
  };
109
102
  }
110
103
 
111
104
  isMe: boolean;
112
105
  sessionID: SessionID | undefined;
113
106
 
114
- constructor(init: undefined, options: { owner: Group | Account });
115
- constructor(
116
- init: undefined,
117
- options: { fromRaw: RawAccount | RawControlledAccount }
118
- );
119
- constructor(
120
- _init: undefined,
121
- options:
122
- | { fromRaw: RawAccount | RawControlledAccount }
123
- | { owner: Group | Account }
124
- ) {
107
+ constructor(options: { fromRaw: RawAccount | RawControlledAccount }) {
125
108
  super();
126
109
  if (!("fromRaw" in options)) {
127
110
  throw new Error(
@@ -191,7 +174,7 @@ export class Account<
191
174
  const { node } = await LocalNode.withNewlyCreatedAccount({
192
175
  ...options,
193
176
  migration: async (rawAccount, _node, creationProps) => {
194
- const account = new this(undefined, {
177
+ const account = new this({
195
178
  fromRaw: rawAccount,
196
179
  }) as A & Me;
197
180
 
@@ -217,7 +200,7 @@ export class Account<
217
200
  sessionID: options.sessionID,
218
201
  peersToLoadFrom: options.peersToLoadFrom,
219
202
  migration: async (rawAccount, _node, creationProps) => {
220
- const account = new this(undefined, {
203
+ const account = new this({
221
204
  fromRaw: rawAccount,
222
205
  }) as A & Me;
223
206
 
@@ -232,7 +215,7 @@ export class Account<
232
215
  this: SubclassedConstructor<A>,
233
216
  node: LocalNode
234
217
  ): A & Me {
235
- return new this(undefined, {
218
+ return new this({
236
219
  fromRaw: node.account as RawControlledAccount,
237
220
  }) as A & Me;
238
221
  }
@@ -250,9 +233,9 @@ export class Account<
250
233
 
251
234
  migrate(creationProps?: { name: string }): void | Promise<void> {
252
235
  if (creationProps) {
253
- const profileGroup = new Group({ owner: this });
236
+ const profileGroup = Group.create({ owner: this });
254
237
  profileGroup.addMember("everyone", "reader");
255
- this.profile = new Profile(
238
+ this.profile = Profile.create(
256
239
  { name: creationProps.name },
257
240
  { owner: profileGroup }
258
241
  );
@@ -11,6 +11,7 @@ import type {
11
11
  SubclassedConstructor,
12
12
  UnavailableError,
13
13
  IfCo,
14
+ UnCo,
14
15
  } from "../internal.js";
15
16
  import {
16
17
  Account,
@@ -32,6 +33,7 @@ export class CoList<Item = any>
32
33
  implements CoValue<"CoList", RawCoList>
33
34
  {
34
35
  static Of<Item>(item: IfCo<Item, Item>): typeof CoList<Item> {
36
+ // TODO: cache superclass for item class
35
37
  return class CoListOf extends CoList<Item> {
36
38
  [co.items] = item;
37
39
  };
@@ -107,21 +109,16 @@ export class CoList<Item = any>
107
109
  return Array;
108
110
  }
109
111
 
110
- constructor(_init: undefined, options: { fromRaw: RawCoList });
111
- constructor(init: Item[], options: { owner: Account | Group });
112
112
  constructor(
113
- init: Item[] | undefined,
114
- options?: { owner: Account | Group } | { fromRaw: RawCoList }
113
+ options:
114
+ | { init: Item[]; owner: Account | Group }
115
+ | { fromRaw: RawCoList }
115
116
  ) {
116
117
  super();
117
118
 
118
- if (!options) {
119
- throw new Error("Must provide options");
120
- }
121
-
122
- if (init && "owner" in options) {
119
+ if ("owner" in options) {
123
120
  this[InitValues] = {
124
- init,
121
+ init: options.init,
125
122
  owner: options.owner,
126
123
  };
127
124
  } else if ("fromRaw" in options) {
@@ -137,6 +134,14 @@ export class CoList<Item = any>
137
134
  return new Proxy(this, CoListProxyHandler as ProxyHandler<this>);
138
135
  }
139
136
 
137
+ static create<L extends CoList>(
138
+ this: SubclassedConstructor<L>,
139
+ items: UnCo<L[number]>[],
140
+ options: {owner: Account | Group}
141
+ ) {
142
+ return new this({ init: items, owner: options.owner });
143
+ }
144
+
140
145
  push(...items: Item[]): number;
141
146
  /** @private For exact type compatibility with Array superclass */
142
147
  push(...items: Item[]): number;
@@ -238,7 +243,7 @@ export class CoList<Item = any>
238
243
  this: SubclassedConstructor<V> & typeof CoList,
239
244
  raw: RawCoList
240
245
  ) {
241
- return new this(undefined, { fromRaw: raw });
246
+ return new this({ fromRaw: raw });
242
247
  }
243
248
 
244
249
  static loadEf = CoValueBase.loadEf as unknown as <V extends CoValue>(
@@ -9,6 +9,7 @@ import type {
9
9
  RefEncoded,
10
10
  IfCo,
11
11
  RefIfCoValue,
12
+ SubclassedConstructor,
12
13
  } from "../internal.js";
13
14
  import {
14
15
  Account,
@@ -23,11 +24,6 @@ import {
23
24
  isRefEncoded,
24
25
  } from "../internal.js";
25
26
 
26
- type DefaultFields = {
27
- [key: string]: any;
28
- [ItemsSym]?: any;
29
- };
30
-
31
27
  type CoMapEdit<V> = {
32
28
  value?: V;
33
29
  ref?: RefIfCoValue<V>;
@@ -40,10 +36,7 @@ type InitValuesFor<C extends CoMap> = {
40
36
  owner: Account | Group;
41
37
  };
42
38
 
43
- export class CoMap<Fields extends object = DefaultFields>
44
- extends CoValueBase
45
- implements CoValue<"CoMap", RawCoMap>
46
- {
39
+ export class CoMap extends CoValueBase implements CoValue<"CoMap", RawCoMap> {
47
40
  declare id: ID<this>;
48
41
  declare _type: "CoMap";
49
42
  static {
@@ -130,20 +123,14 @@ export class CoMap<Fields extends object = DefaultFields>
130
123
 
131
124
  [InitValues]?: any;
132
125
 
133
- constructor(_init: undefined, options: { fromRaw: RawCoMap });
134
126
  constructor(
135
- init: Simplify<CoMapInit<Fields>>,
136
- options: { owner: Account | Group }
137
- );
138
- constructor(
139
- init: Simplify<CoMapInit<Fields>> | undefined,
140
- options: { owner: Account | Group } | { fromRaw: RawCoMap }
127
+ options: { fromRaw: RawCoMap } | { init: any; owner: Account | Group }
141
128
  ) {
142
129
  super();
143
130
 
144
- if (init && "owner" in options) {
131
+ if ("owner" in options) {
145
132
  this[InitValues] = {
146
- init,
133
+ init: options.init,
147
134
  owner: options.owner,
148
135
  } as InitValuesFor<this>;
149
136
  } else if ("fromRaw" in options) {
@@ -161,6 +148,14 @@ export class CoMap<Fields extends object = DefaultFields>
161
148
  return new Proxy(this, CoMapProxyHandler as ProxyHandler<this>);
162
149
  }
163
150
 
151
+ static create<M extends CoMap>(
152
+ this: SubclassedConstructor<M>,
153
+ init: Simplify<CoMapInit<M>>,
154
+ options: { owner: Account | Group }
155
+ ) {
156
+ return new this({ init, owner: options.owner });
157
+ }
158
+
164
159
  toJSON() {
165
160
  const jsonedFields = this._raw.keys().map((key) => {
166
161
  const tKey = key as CoKeys<this>;
@@ -224,7 +219,7 @@ export class CoMap<Fields extends object = DefaultFields>
224
219
 
225
220
  static Record<Value>(value: IfCo<Value, Value>) {
226
221
  // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
227
- class RecordLikeCoMap extends CoMap<RecordLikeCoMap> {
222
+ class RecordLikeCoMap extends CoMap {
228
223
  [ItemsSym] = value;
229
224
  }
230
225
  // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
@@ -236,7 +231,7 @@ export class CoMap<Fields extends object = DefaultFields>
236
231
 
237
232
  export type CoKeys<Fields extends object> = Exclude<
238
233
  keyof Fields & string,
239
- keyof CoMap<Record<string, never>>
234
+ keyof CoMap
240
235
  >;
241
236
 
242
237
  export type CoMapInit<Fields extends object> = {
@@ -17,6 +17,8 @@ import type {
17
17
  ID,
18
18
  Me,
19
19
  IfCo,
20
+ SubclassedConstructor,
21
+ UnCo,
20
22
  } from "../internal.js";
21
23
  import {
22
24
  ItemsSym,
@@ -47,9 +49,7 @@ export class CoStream<Item = any>
47
49
  extends CoValueBase
48
50
  implements CoValue<"CoStream", RawCoStream>
49
51
  {
50
- static Of<Item>(
51
- item: IfCo<Item, Item>
52
- ): typeof CoStream<Item> {
52
+ static Of<Item>(item: IfCo<Item, Item>): typeof CoStream<Item> {
53
53
  return class CoStreamOf extends CoStream<Item> {
54
54
  [co.items] = item;
55
55
  };
@@ -85,11 +85,10 @@ export class CoStream<Item = any>
85
85
 
86
86
  [InitValues]?: any;
87
87
 
88
- constructor(_init: undefined, options: { fromRaw: RawCoStream });
89
- constructor(init: Item[], options: { owner: Account | Group });
90
88
  constructor(
91
- init: Item[] | undefined,
92
- options: { owner: Account | Group } | { fromRaw: RawCoStream }
89
+ options:
90
+ | { init: Item[]; owner: Account | Group }
91
+ | { fromRaw: RawCoStream }
93
92
  ) {
94
93
  super();
95
94
 
@@ -103,7 +102,7 @@ export class CoStream<Item = any>
103
102
  });
104
103
  } else {
105
104
  this[InitValues] = {
106
- init,
105
+ init: options.init,
107
106
  owner: options.owner,
108
107
  };
109
108
  }
@@ -111,6 +110,14 @@ export class CoStream<Item = any>
111
110
  return new Proxy(this, CoStreamProxyHandler as ProxyHandler<this>);
112
111
  }
113
112
 
113
+ static create<S extends CoStream>(
114
+ this: SubclassedConstructor<S>,
115
+ init: S extends CoStream<infer Item> ? UnCo<Item>[] : never,
116
+ options: { owner: Account | Group }
117
+ ) {
118
+ return new this({ init, owner: options.owner });
119
+ }
120
+
114
121
  push(...items: Item[]) {
115
122
  for (const item of items) {
116
123
  this.pushItem(item);
@@ -123,9 +130,7 @@ export class CoStream<Item = any>
123
130
  if (itemDescriptor === "json") {
124
131
  this._raw.push(item as JsonValue);
125
132
  } else if ("encoded" in itemDescriptor) {
126
- this._raw.push(
127
- encodeSync(itemDescriptor.encoded)(item)
128
- );
133
+ this._raw.push(encodeSync(itemDescriptor.encoded)(item));
129
134
  } else if (isRefEncoded(itemDescriptor)) {
130
135
  this._raw.push((item as unknown as CoValue).id);
131
136
  }
@@ -192,9 +197,7 @@ function entryFromRawEntry<Item>(
192
197
  ? (CoValue & Item) | null
193
198
  : Item;
194
199
  } else if ("encoded" in itemField) {
195
- return decodeSync(itemField.encoded)(
196
- rawEntry.value
197
- );
200
+ return decodeSync(itemField.encoded)(rawEntry.value);
198
201
  } else if (isRefEncoded(itemField)) {
199
202
  return this.ref?.accessFrom(
200
203
  accessFrom
@@ -292,7 +295,10 @@ export const CoStreamProxyHandler: ProxyHandler<CoStream> = {
292
295
 
293
296
  return entry;
294
297
  } else if (key === "perSession") {
295
- return new Proxy({}, CoStreamPerSessionProxyHandler(target, receiver));
298
+ return new Proxy(
299
+ {},
300
+ CoStreamPerSessionProxyHandler(target, receiver)
301
+ );
296
302
  } else {
297
303
  return Reflect.get(target, key, receiver);
298
304
  }
@@ -350,7 +356,10 @@ export const CoStreamProxyHandler: ProxyHandler<CoStream> = {
350
356
  },
351
357
  };
352
358
 
353
- const CoStreamPerSessionProxyHandler = (innerTarget: CoStream, accessFrom: CoStream): ProxyHandler<Record<string, never>> => ({
359
+ const CoStreamPerSessionProxyHandler = (
360
+ innerTarget: CoStream,
361
+ accessFrom: CoStream
362
+ ): ProxyHandler<Record<string, never>> => ({
354
363
  get(_target, key, receiver) {
355
364
  if (typeof key === "string" && key.includes("session")) {
356
365
  const sessionID = key as SessionID;
@@ -420,7 +429,6 @@ export class BinaryCoStream
420
429
  declare _raw: RawBinaryCoStream;
421
430
 
422
431
  constructor(
423
- _init: [] | undefined,
424
432
  options:
425
433
  | {
426
434
  owner: Account | Group;
@@ -449,6 +457,13 @@ export class BinaryCoStream
449
457
  });
450
458
  }
451
459
 
460
+ static create<S extends BinaryCoStream>(
461
+ this: SubclassedConstructor<S>,
462
+ options: { owner: Account | Group }
463
+ ) {
464
+ return new this(options);
465
+ }
466
+
452
467
  getChunks(options?: {
453
468
  allowUnfinished?: boolean;
454
469
  }):
@@ -5,7 +5,7 @@ import {
5
5
  subscriptionsScopes,
6
6
  } from "../../internal.js";
7
7
 
8
- export class ImageDefinition extends CoMap<ImageDefinition> {
8
+ export class ImageDefinition extends CoMap {
9
9
  originalSize = co.json<[number, number]>();
10
10
  placeholderDataURL? = co.string;
11
11
 
@@ -2,9 +2,9 @@ import type { AccountID, Everyone, RawGroup, Role } from "cojson";
2
2
  import type {
3
3
  CoValue,
4
4
  ID,
5
- JsonEncoded,
6
5
  RefEncoded,
7
6
  Schema,
7
+ SubclassedConstructor,
8
8
  } from "../internal.js";
9
9
  import {
10
10
  Account,
@@ -17,34 +17,11 @@ import {
17
17
  MembersSym,
18
18
  } from "../internal.js";
19
19
 
20
- export class Profile extends CoMap<{ name: co<string> }> {
20
+ export class Profile extends CoMap {
21
21
  name = co.string;
22
22
  }
23
23
 
24
- type GroupSchema<Def extends Group> = {
25
- profile: NonNullable<Def["profile"]> extends CoValue
26
- ? RefEncoded<NonNullable<Def["profile"]>>
27
- : JsonEncoded;
28
- root: NonNullable<Def["root"]> extends CoValue
29
- ? RefEncoded<NonNullable<Def["root"]>>
30
- : JsonEncoded;
31
- [MembersSym]: RefEncoded<NonNullable<Def[MembersSym]>>;
32
- };
33
-
34
- export class Group<
35
- Def extends {
36
- profile: Profile | null;
37
- root: CoMap | null;
38
- [MembersSym]: Account | null;
39
- } = {
40
- profile: Profile | null;
41
- root: CoMap | null;
42
- [MembersSym]: Account | null;
43
- },
44
- >
45
- extends CoValueBase
46
- implements CoValue<"Group", RawGroup>
47
- {
24
+ export class Group extends CoValueBase implements CoValue<"Group", RawGroup> {
48
25
  declare id: ID<this>;
49
26
  declare _type: "Group";
50
27
  static {
@@ -53,7 +30,11 @@ export class Group<
53
30
  declare _raw: RawGroup;
54
31
 
55
32
  static _schema: any;
56
- get _schema(): GroupSchema<this> {
33
+ get _schema(): {
34
+ profile: Schema;
35
+ root: Schema;
36
+ [MembersSym]: RefEncoded<Account>;
37
+ } {
57
38
  return (this.constructor as typeof Group)._schema;
58
39
  }
59
40
  static {
@@ -67,19 +48,16 @@ export class Group<
67
48
  });
68
49
  }
69
50
 
70
- declare profile: Def["profile"] | null;
71
- declare root: Def["root"] | null;
72
- declare [MembersSym]: Def[MembersSym] | null;
51
+ declare profile: Profile | null;
52
+ declare root: CoMap | null;
53
+ declare [MembersSym]: Account | null;
73
54
 
74
- get _refs(): {
75
- profile: Def["profile"] extends Profile ? Ref<Def["profile"]> : never;
76
- root: Def["root"] extends CoMap ? Ref<Def["root"]> : never;
77
- } {
55
+ get _refs() {
78
56
  const profileID = this._raw.get("profile") as unknown as
79
- | ID<NonNullable<Def["profile"]>>
57
+ | ID<NonNullable<this["profile"]>>
80
58
  | undefined;
81
59
  const rootID = this._raw.get("root") as unknown as
82
- | ID<NonNullable<Def["root"]>>
60
+ | ID<NonNullable<this["root"]>>
83
61
  | undefined;
84
62
  return {
85
63
  profile:
@@ -88,33 +66,32 @@ export class Group<
88
66
  profileID,
89
67
  this._loadedAs,
90
68
  this._schema.profile as RefEncoded<
91
- NonNullable<Def["profile"]>
69
+ NonNullable<this["profile"]>
92
70
  >
93
- ) as any),
71
+ ) as any as this["profile"] extends Profile
72
+ ? Ref<this["profile"]>
73
+ : never),
94
74
  root:
95
75
  rootID &&
96
76
  (new Ref(
97
77
  rootID,
98
78
  this._loadedAs,
99
- this._schema.root as RefEncoded<NonNullable<Def["root"]>>
100
- ) as any),
79
+ this._schema.root as RefEncoded<NonNullable<this["root"]>>
80
+ ) as any as this["root"] extends CoMap
81
+ ? Ref<this["root"]>
82
+ : never),
101
83
  };
102
84
  }
103
85
 
104
- constructor(options: { owner: Account | Group });
105
- constructor(init: any, options: { fromRaw: RawGroup });
106
- constructor(init: undefined, options: { owner: Account | Group });
107
- constructor(
108
- init: undefined | { owner: Account | Group },
109
- options?: { fromRaw: RawGroup } | { owner: Account | Group }
110
- ) {
86
+ /** @deprecated Don't use constructor directly, use .create */
87
+ constructor(options: { fromRaw: RawGroup } | { owner: Account | Group }) {
111
88
  super();
112
89
  let raw: RawGroup;
113
90
 
114
91
  if (options && "fromRaw" in options) {
115
92
  raw = options.fromRaw;
116
93
  } else {
117
- const initOwner = options?.owner || init?.owner;
94
+ const initOwner = options.owner;
118
95
  if (!initOwner) throw new Error("No owner provided");
119
96
  if (
120
97
  initOwner instanceof Account &&
@@ -143,6 +120,13 @@ export class Group<
143
120
  );
144
121
  }
145
122
 
123
+ static create<G extends Group>(
124
+ this: SubclassedConstructor<G>,
125
+ options: { owner: Account }
126
+ ) {
127
+ return new this(options);
128
+ }
129
+
146
130
  myRole(): Role | undefined {
147
131
  return this._raw.myRole();
148
132
  }
@@ -118,7 +118,7 @@ export class CoValueBase implements CoValue {
118
118
  this: SubclassedConstructor<V>,
119
119
  raw: RawCoValue
120
120
  ): V {
121
- return new this(undefined, { fromRaw: raw });
121
+ return new this({ fromRaw: raw });
122
122
  }
123
123
 
124
124
  static loadEf<V extends CoValue>(
@@ -9,6 +9,7 @@ export type IfCo<C, R> = C extends infer _A | infer B
9
9
  ? R
10
10
  : never
11
11
  : never;
12
+ export type UnCo<T> = T extends co<infer A> ? A : T;
12
13
 
13
14
  export const co = {
14
15
  string: {
@@ -22,7 +22,7 @@ describe("Simple CoList operations", async () => {
22
22
 
23
23
  class TestList extends CoList.Of(co.string) {}
24
24
 
25
- const list = new TestList(["bread", "butter", "onion"], { owner: me });
25
+ const list = TestList.create(["bread", "butter", "onion"], { owner: me });
26
26
 
27
27
  test("Construction", () => {
28
28
  expect(list[0]).toBe("bread");
@@ -39,7 +39,7 @@ describe("Simple CoList operations", async () => {
39
39
 
40
40
  describe("Mutation", () => {
41
41
  test("assignment", () => {
42
- const list = new TestList(["bread", "butter", "onion"], {
42
+ const list = TestList.create(["bread", "butter", "onion"], {
43
43
  owner: me,
44
44
  });
45
45
  list[1] = "margarine";
@@ -52,7 +52,7 @@ describe("Simple CoList operations", async () => {
52
52
  });
53
53
 
54
54
  test("push", () => {
55
- const list = new TestList(["bread", "butter", "onion"], {
55
+ const list = TestList.create(["bread", "butter", "onion"], {
56
56
  owner: me,
57
57
  });
58
58
  list.push("cheese");
@@ -66,7 +66,7 @@ describe("Simple CoList operations", async () => {
66
66
  });
67
67
 
68
68
  test("unshift", () => {
69
- const list = new TestList(["bread", "butter", "onion"], {
69
+ const list = TestList.create(["bread", "butter", "onion"], {
70
70
  owner: me,
71
71
  });
72
72
  list.unshift("lettuce");
@@ -80,7 +80,7 @@ describe("Simple CoList operations", async () => {
80
80
  });
81
81
 
82
82
  test("pop", () => {
83
- const list = new TestList(["bread", "butter", "onion"], {
83
+ const list = TestList.create(["bread", "butter", "onion"], {
84
84
  owner: me,
85
85
  });
86
86
  expect(list.pop()).toBe("onion");
@@ -89,7 +89,7 @@ describe("Simple CoList operations", async () => {
89
89
  });
90
90
 
91
91
  test("shift", () => {
92
- const list = new TestList(["bread", "butter", "onion"], {
92
+ const list = TestList.create(["bread", "butter", "onion"], {
93
93
  owner: me,
94
94
  });
95
95
  expect(list.shift()).toBe("bread");
@@ -98,7 +98,7 @@ describe("Simple CoList operations", async () => {
98
98
  });
99
99
 
100
100
  test("splice", () => {
101
- const list = new TestList(["bread", "butter", "onion"], {
101
+ const list = TestList.create(["bread", "butter", "onion"], {
102
102
  owner: me,
103
103
  });
104
104
  list.splice(1, 1, "salt", "pepper");
@@ -129,14 +129,14 @@ describe("CoList resolution", async () => {
129
129
  creationProps: { name: "Hermes Puggington" },
130
130
  });
131
131
 
132
- const list = new TestList(
132
+ const list = TestList.create(
133
133
  [
134
- new NestedList(
135
- [new TwiceNestedList(["a", "b"], { owner: me })],
134
+ NestedList.create(
135
+ [TwiceNestedList.create(["a", "b"], { owner: me })],
136
136
  { owner: me }
137
137
  ),
138
- new NestedList(
139
- [new TwiceNestedList(["c", "d"], { owner: me })],
138
+ NestedList.create(
139
+ [TwiceNestedList.create(["c", "d"], { owner: me })],
140
140
  { owner: me }
141
141
  ),
142
142
  ],
@@ -196,8 +196,8 @@ describe("CoList resolution", async () => {
196
196
  expect(loadedList?.[0]?._refs[0]?.id).toEqual(list[0]?.[0]?.id);
197
197
  expect(loadedList?.[0]?._refs[0]?.value).toEqual(loadedTwiceNestedList);
198
198
 
199
- const otherNestedList = new NestedList(
200
- [new TwiceNestedList(["e", "f"], { owner: meOnSecondPeer })],
199
+ const otherNestedList = NestedList.create(
200
+ [TwiceNestedList.create(["e", "f"], { owner: meOnSecondPeer })],
201
201
  { owner: meOnSecondPeer }
202
202
  );
203
203
 
@@ -257,11 +257,11 @@ describe("CoList resolution", async () => {
257
257
 
258
258
  // When assigning a new nested value, we get an update
259
259
 
260
- const newTwiceNestedList = new TwiceNestedList(["y", "z"], {
260
+ const newTwiceNestedList = TwiceNestedList.create(["y", "z"], {
261
261
  owner: meOnSecondPeer,
262
262
  });
263
263
 
264
- const newNestedList = new NestedList([newTwiceNestedList], {
264
+ const newNestedList = NestedList.create([newTwiceNestedList], {
265
265
  owner: meOnSecondPeer,
266
266
  });
267
267