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

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 +8 -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 +86 -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 +178 -217
  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 +67 -51
  41. package/src/tests/coStream.test.ts +61 -66
@@ -11,21 +11,39 @@ import type {
11
11
  RefEncoded,
12
12
  SubclassedConstructor,
13
13
  UnavailableError,
14
+ IsVal,
14
15
  } from "../internal.js";
15
16
  import {
16
17
  Account,
17
18
  CoValueBase,
18
19
  Group,
20
+ InitValues,
21
+ ItemsSym,
19
22
  Ref,
23
+ SchemaInit,
24
+ val,
20
25
  inspect,
21
26
  makeRefs,
22
27
  } from "../internal.js";
23
28
  import { Schema } from "@effect/schema";
24
29
 
25
- export class CoList<Item extends ValidItem<Item, "Co.List"> = any>
30
+ export class CoList<Item extends ValidItem<Item, "CoList"> = any>
26
31
  extends Array<Item>
27
32
  implements CoValue<"CoList", RawCoList>
28
33
  {
34
+ static Of<Item extends ValidItem<Item, "CoList"> = any>(
35
+ item: IsVal<Item, Item>
36
+ ): typeof CoList<Item> {
37
+ return class CoListOf extends CoList<Item> {
38
+ [val.items] = item;
39
+ };
40
+ }
41
+
42
+ /** @deprecated Use UPPERCASE `CoList.Of` instead! */
43
+ static of(..._args: never): never {
44
+ throw new Error("Can't use Array.of with CoLists");
45
+ }
46
+
29
47
  id!: ID<this>;
30
48
  _type!: "CoList";
31
49
  static {
@@ -33,9 +51,11 @@ export class CoList<Item extends ValidItem<Item, "Co.List"> = any>
33
51
  }
34
52
  _raw!: RawCoList;
35
53
 
54
+ /** @internal This is only a marker type and doesn't exist at runtime */
55
+ [ItemsSym]!: Item;
36
56
  static _encoding: any;
37
57
  get _encoding(): {
38
- _item: EncodingFor<Item>;
58
+ [ItemsSym]: EncodingFor<Item>;
39
59
  } {
40
60
  return (this.constructor as typeof CoList)._encoding;
41
61
  }
@@ -53,9 +73,7 @@ export class CoList<Item extends ValidItem<Item, "Co.List"> = any>
53
73
  } & {
54
74
  length: number;
55
75
  [Symbol.iterator](): IterableIterator<
56
- NonNullable<Item> extends CoValue
57
- ? Ref<NonNullable<Item>>
58
- : never
76
+ NonNullable<Item> extends CoValue ? Ref<NonNullable<Item>> : never
59
77
  >;
60
78
  } {
61
79
  return makeRefs<number>(
@@ -66,7 +84,7 @@ export class CoList<Item extends ValidItem<Item, "Co.List"> = any>
66
84
  (_, idx) => idx
67
85
  ),
68
86
  this._loadedAs,
69
- (_idx) => (this._encoding._item as RefEncoded<CoValue>).ref()
87
+ (_idx) => this._encoding[ItemsSym] as RefEncoded<CoValue>
70
88
  ) as any;
71
89
  }
72
90
 
@@ -85,71 +103,53 @@ export class CoList<Item extends ValidItem<Item, "Co.List"> = any>
85
103
  return Account.fromNode(this._raw.core.node);
86
104
  }
87
105
 
106
+ [InitValues]?: {
107
+ init: Item[];
108
+ owner: Account | Group;
109
+ };
110
+
111
+ static get [Symbol.species]() {
112
+ return Array;
113
+ }
114
+
88
115
  constructor(_init: undefined, options: { fromRaw: RawCoList });
89
116
  constructor(init: Item[], options: { owner: Account | Group });
90
- constructor(init: number);
91
117
  constructor(
92
- init: Item[] | undefined | number,
118
+ init: Item[] | undefined,
93
119
  options?: { owner: Account | Group } | { fromRaw: RawCoList }
94
120
  ) {
95
- if (typeof init === "number") {
96
- // this might be called from an intrinsic, like map, trying to create an empty array
97
- // passing `0` as the only parameter
98
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
- return new Array(init) as any;
100
- }
101
-
102
121
  super();
103
122
 
104
123
  if (!options) {
105
124
  throw new Error("Must provide options");
106
125
  }
107
126
 
108
- let raw: RawCoList;
109
-
110
- if ("fromRaw" in options) {
111
- raw = options.fromRaw;
112
- } else {
113
- const rawOwner = options.owner._raw;
114
-
115
- const rawInit = init && this.toRawItems(init);
116
-
117
- raw = rawOwner.createList(rawInit);
127
+ if (init && "owner" in options) {
128
+ this[InitValues] = {
129
+ init,
130
+ owner: options.owner,
131
+ };
132
+ } else if ("fromRaw" in options) {
133
+ Object.defineProperties(this, {
134
+ id: {
135
+ value: options.fromRaw.id,
136
+ enumerable: false,
137
+ },
138
+ _raw: { value: options.fromRaw, enumerable: false },
139
+ });
118
140
  }
119
141
 
120
- Object.defineProperties(this, {
121
- id: {
122
- value: raw.id,
123
- enumerable: false,
124
- },
125
- _raw: { value: raw, enumerable: false },
126
- });
127
-
128
- return new Proxy(this, CoListProxyHandler<Item>(this._encoding._item));
129
- }
130
-
131
- private toRawItems(items: Item[]) {
132
- const itemDescriptor = this._encoding._item as Encoding;
133
- const rawItems =
134
- itemDescriptor === "json"
135
- ? items
136
- : "encoded" in itemDescriptor
137
- ? items?.map((e) =>
138
- Schema.encodeSync(itemDescriptor.encoded)(e)
139
- )
140
- : "ref" in itemDescriptor
141
- ? items?.map((v) => (v as unknown as CoValue).id)
142
- : (() => {
143
- throw new Error("Invalid element descriptor");
144
- })();
145
- return rawItems;
142
+ return new Proxy(this, CoListProxyHandler as ProxyHandler<this>);
146
143
  }
147
144
 
148
145
  push(...items: Item[]): number;
149
146
  /** @private For exact type compatibility with Array superclass */
150
147
  push(...items: Item[]): number;
151
148
  push(...items: Item[]): number {
152
- for (const item of this.toRawItems(items as Item[])) {
149
+ for (const item of toRawItems(
150
+ items as Item[],
151
+ this._encoding[ItemsSym]
152
+ )) {
153
153
  this._raw.append(item);
154
154
  }
155
155
 
@@ -160,7 +160,10 @@ export class CoList<Item extends ValidItem<Item, "Co.List"> = any>
160
160
  /** @private For exact type compatibility with Array superclass */
161
161
  unshift(...items: Item[]): number;
162
162
  unshift(...items: Item[]): number {
163
- for (const item of this.toRawItems(items as Item[])) {
163
+ for (const item of toRawItems(
164
+ items as Item[],
165
+ this._encoding[ItemsSym]
166
+ )) {
164
167
  this._raw.prepend(item);
165
168
  }
166
169
 
@@ -197,7 +200,10 @@ export class CoList<Item extends ValidItem<Item, "Co.List"> = any>
197
200
  }
198
201
 
199
202
  let appendAfter = start;
200
- for (const item of this.toRawItems(items as Item[])) {
203
+ for (const item of toRawItems(
204
+ items as Item[],
205
+ this._encoding[ItemsSym]
206
+ )) {
201
207
  this._raw.append(item, appendAfter);
202
208
  appendAfter++;
203
209
  }
@@ -206,7 +212,7 @@ export class CoList<Item extends ValidItem<Item, "Co.List"> = any>
206
212
  }
207
213
 
208
214
  toJSON() {
209
- const itemDescriptor = this._encoding._item as Encoding;
215
+ const itemDescriptor = this._encoding[ItemsSym] as Encoding;
210
216
  if (itemDescriptor === "json") {
211
217
  return this._raw.asArray();
212
218
  } else if ("encoded" in itemDescriptor) {
@@ -265,63 +271,120 @@ export class CoList<Item extends ValidItem<Item, "Co.List"> = any>
265
271
 
266
272
  static encoding<V extends CoList>(
267
273
  this: { new (...args: any): V } & typeof CoList,
268
- def: { _item: V["_encoding"]["_item"] }
274
+ def: { [ItemsSym]: V["_encoding"][ItemsSym] }
269
275
  ) {
270
276
  this._encoding ||= {};
271
277
  Object.assign(this._encoding, def);
272
278
  }
273
279
  }
274
280
 
275
- function CoListProxyHandler<Item extends ValidItem<Item, "Co.List">>(
276
- itemDescriptor: Encoding
277
- ): ProxyHandler<CoList<Item>> {
278
- return {
279
- get(target, key, receiver) {
280
- if (typeof key === "string" && !isNaN(+key)) {
281
- const rawValue = target._raw.get(Number(key));
282
- if (itemDescriptor === "json") {
283
- return rawValue;
284
- } else if ("encoded" in itemDescriptor) {
285
- return rawValue === undefined
286
- ? undefined
287
- : Schema.decodeSync(itemDescriptor.encoded)(rawValue);
288
- } else if ("ref" in itemDescriptor) {
289
- return rawValue === undefined
290
- ? undefined
291
- : new Ref(
292
- rawValue as unknown as ID<CoValue>,
293
- target._loadedAs,
294
- itemDescriptor.ref()
295
- ).accessFrom(receiver);
296
- }
297
- } else if (key === "length") {
298
- return target._raw.entries().length;
299
- } else {
300
- return Reflect.get(target, key, receiver);
301
- }
302
- },
303
- set(target, key, value, receiver) {
304
- if (typeof key === "string" && !isNaN(+key)) {
305
- let rawValue;
306
- if (itemDescriptor === "json") {
307
- rawValue = value;
308
- } else if ("encoded" in itemDescriptor) {
309
- rawValue = Schema.encodeSync(itemDescriptor.encoded)(value);
310
- } else if ("ref" in itemDescriptor) {
311
- rawValue = value.id;
312
- }
313
- target._raw.replace(Number(key), rawValue);
314
- return true;
315
- } else {
316
- return Reflect.set(target, key, value, receiver);
281
+ function toRawItems<Item>(items: Item[], itemDescriptor: Encoding) {
282
+ const rawItems =
283
+ itemDescriptor === "json"
284
+ ? items
285
+ : "encoded" in itemDescriptor
286
+ ? items?.map((e) => Schema.encodeSync(itemDescriptor.encoded)(e))
287
+ : "ref" in itemDescriptor
288
+ ? items?.map((v) => (v as unknown as CoValue).id)
289
+ : (() => {
290
+ throw new Error("Invalid element descriptor");
291
+ })();
292
+ return rawItems;
293
+ }
294
+
295
+ function init(list: CoList) {
296
+ if (list[InitValues]) {
297
+ const { init, owner } = list[InitValues];
298
+ const raw = owner._raw.createList(
299
+ toRawItems(init, list._encoding[ItemsSym])
300
+ );
301
+
302
+ Object.defineProperties(list, {
303
+ id: {
304
+ value: raw.id,
305
+ enumerable: false,
306
+ },
307
+ _raw: { value: raw, enumerable: false },
308
+ });
309
+ delete list[InitValues];
310
+ }
311
+ }
312
+
313
+ const CoListProxyHandler: ProxyHandler<CoList> = {
314
+ get(target, key, receiver) {
315
+ if (typeof key === "string" && !isNaN(+key)) {
316
+ const itemDescriptor = target._encoding[ItemsSym] as Encoding;
317
+ const rawValue = target._raw.get(Number(key));
318
+ if (itemDescriptor === "json") {
319
+ return rawValue;
320
+ } else if ("encoded" in itemDescriptor) {
321
+ return rawValue === undefined
322
+ ? undefined
323
+ : Schema.decodeSync(itemDescriptor.encoded)(rawValue);
324
+ } else if ("ref" in itemDescriptor) {
325
+ return rawValue === undefined
326
+ ? undefined
327
+ : new Ref(
328
+ rawValue as unknown as ID<CoValue>,
329
+ target._loadedAs,
330
+ itemDescriptor
331
+ ).accessFrom(receiver);
317
332
  }
318
- },
319
- has(target, key) {
320
- if (typeof key === "string" && !isNaN(+key)) {
321
- return Number(key) < target._raw.entries().length;
322
- } else {
323
- return Reflect.has(target, key);
333
+ } else if (key === "length") {
334
+ return target._raw.entries().length;
335
+ } else {
336
+ return Reflect.get(target, key, receiver);
337
+ }
338
+ },
339
+ set(target, key, value, receiver) {
340
+ if (
341
+ key === ItemsSym &&
342
+ typeof value === "object" &&
343
+ SchemaInit in value
344
+ ) {
345
+ (target.constructor as typeof CoList)._encoding ||= {};
346
+ (target.constructor as typeof CoList)._encoding[ItemsSym] =
347
+ value[SchemaInit];
348
+ init(target);
349
+ return true;
350
+ }
351
+ if (typeof key === "string" && !isNaN(+key)) {
352
+ const itemDescriptor = target._encoding[ItemsSym] as Encoding;
353
+ let rawValue;
354
+ if (itemDescriptor === "json") {
355
+ rawValue = value;
356
+ } else if ("encoded" in itemDescriptor) {
357
+ rawValue = Schema.encodeSync(itemDescriptor.encoded)(value);
358
+ } else if ("ref" in itemDescriptor) {
359
+ rawValue = value.id;
324
360
  }
325
- },
326
- };
327
- }
361
+ target._raw.replace(Number(key), rawValue);
362
+ return true;
363
+ } else {
364
+ return Reflect.set(target, key, value, receiver);
365
+ }
366
+ },
367
+ defineProperty(target, key, descriptor) {
368
+ if (
369
+ descriptor.value &&
370
+ key === ItemsSym &&
371
+ typeof descriptor.value === "object" &&
372
+ SchemaInit in descriptor.value
373
+ ) {
374
+ (target.constructor as typeof CoList)._encoding ||= {};
375
+ (target.constructor as typeof CoList)._encoding[ItemsSym] =
376
+ descriptor.value[SchemaInit];
377
+ init(target);
378
+ return true;
379
+ } else {
380
+ return Reflect.defineProperty(target, key, descriptor);
381
+ }
382
+ },
383
+ has(target, key) {
384
+ if (typeof key === "string" && !isNaN(+key)) {
385
+ return Number(key) < target._raw.entries().length;
386
+ } else {
387
+ return Reflect.has(target, key);
388
+ }
389
+ },
390
+ };