jazz-tools 0.7.0-alpha.0

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 (85) hide show
  1. package/.eslintrc.cjs +24 -0
  2. package/.turbo/turbo-build.log +24 -0
  3. package/CHANGELOG.md +42 -0
  4. package/LICENSE.txt +19 -0
  5. package/README.md +3 -0
  6. package/dist/coValueInterfaces.js +8 -0
  7. package/dist/coValueInterfaces.js.map +1 -0
  8. package/dist/coValues/account/account.js +11 -0
  9. package/dist/coValues/account/account.js.map +1 -0
  10. package/dist/coValues/account/accountOf.js +150 -0
  11. package/dist/coValues/account/accountOf.js.map +1 -0
  12. package/dist/coValues/account/migration.js +4 -0
  13. package/dist/coValues/account/migration.js.map +1 -0
  14. package/dist/coValues/coList/coList.js +2 -0
  15. package/dist/coValues/coList/coList.js.map +1 -0
  16. package/dist/coValues/coList/coListOf.js +235 -0
  17. package/dist/coValues/coList/coListOf.js.map +1 -0
  18. package/dist/coValues/coList/internalDocs.js +2 -0
  19. package/dist/coValues/coList/internalDocs.js.map +1 -0
  20. package/dist/coValues/coMap/coMap.js +2 -0
  21. package/dist/coValues/coMap/coMap.js.map +1 -0
  22. package/dist/coValues/coMap/coMapOf.js +262 -0
  23. package/dist/coValues/coMap/coMapOf.js.map +1 -0
  24. package/dist/coValues/coMap/internalDocs.js +2 -0
  25. package/dist/coValues/coMap/internalDocs.js.map +1 -0
  26. package/dist/coValues/coStream/coStream.js +2 -0
  27. package/dist/coValues/coStream/coStream.js.map +1 -0
  28. package/dist/coValues/coStream/coStreamOf.js +244 -0
  29. package/dist/coValues/coStream/coStreamOf.js.map +1 -0
  30. package/dist/coValues/construction.js +34 -0
  31. package/dist/coValues/construction.js.map +1 -0
  32. package/dist/coValues/extensions/imageDef.js +36 -0
  33. package/dist/coValues/extensions/imageDef.js.map +1 -0
  34. package/dist/coValues/group/group.js +2 -0
  35. package/dist/coValues/group/group.js.map +1 -0
  36. package/dist/coValues/group/groupOf.js +109 -0
  37. package/dist/coValues/group/groupOf.js.map +1 -0
  38. package/dist/coValues/resolution.js +66 -0
  39. package/dist/coValues/resolution.js.map +1 -0
  40. package/dist/errors.js +2 -0
  41. package/dist/errors.js.map +1 -0
  42. package/dist/index.js +31 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/refs.js +95 -0
  45. package/dist/refs.js.map +1 -0
  46. package/dist/schemaHelpers.js +14 -0
  47. package/dist/schemaHelpers.js.map +1 -0
  48. package/dist/subscriptionScope.js +81 -0
  49. package/dist/subscriptionScope.js.map +1 -0
  50. package/dist/tests/coList.test.js +207 -0
  51. package/dist/tests/coList.test.js.map +1 -0
  52. package/dist/tests/coMap.test.js +238 -0
  53. package/dist/tests/coMap.test.js.map +1 -0
  54. package/dist/tests/coStream.test.js +263 -0
  55. package/dist/tests/coStream.test.js.map +1 -0
  56. package/dist/tests/types.test.js +33 -0
  57. package/dist/tests/types.test.js.map +1 -0
  58. package/package.json +23 -0
  59. package/src/coValueInterfaces.ts +105 -0
  60. package/src/coValues/account/account.ts +106 -0
  61. package/src/coValues/account/accountOf.ts +284 -0
  62. package/src/coValues/account/migration.ts +12 -0
  63. package/src/coValues/coList/coList.ts +57 -0
  64. package/src/coValues/coList/coListOf.ts +377 -0
  65. package/src/coValues/coList/internalDocs.ts +1 -0
  66. package/src/coValues/coMap/coMap.ts +110 -0
  67. package/src/coValues/coMap/coMapOf.ts +451 -0
  68. package/src/coValues/coMap/internalDocs.ts +1 -0
  69. package/src/coValues/coStream/coStream.ts +63 -0
  70. package/src/coValues/coStream/coStreamOf.ts +404 -0
  71. package/src/coValues/construction.ts +110 -0
  72. package/src/coValues/extensions/imageDef.ts +51 -0
  73. package/src/coValues/group/group.ts +27 -0
  74. package/src/coValues/group/groupOf.ts +183 -0
  75. package/src/coValues/resolution.ts +111 -0
  76. package/src/errors.ts +1 -0
  77. package/src/index.ts +68 -0
  78. package/src/refs.ts +128 -0
  79. package/src/schemaHelpers.ts +72 -0
  80. package/src/subscriptionScope.ts +118 -0
  81. package/src/tests/coList.test.ts +283 -0
  82. package/src/tests/coMap.test.ts +357 -0
  83. package/src/tests/coStream.test.ts +415 -0
  84. package/src/tests/types.test.ts +37 -0
  85. package/tsconfig.json +15 -0
@@ -0,0 +1,377 @@
1
+ import {
2
+ CoValueCore,
3
+ JsonValue,
4
+ RawAccount,
5
+ RawCoList,
6
+ cojsonInternals,
7
+ } from "cojson";
8
+ import { CoValueSchema, ID, inspect } from "../../coValueInterfaces.js";
9
+ import { SchemaWithOutput } from "../../schemaHelpers.js";
10
+ import { CoListBase, CoListSchema } from "./coList.js";
11
+ import { AST, Schema } from "@effect/schema";
12
+ import { AnyAccount, ControlledAccount } from "../account/account.js";
13
+ import { AnyGroup } from "../group/group.js";
14
+ import {
15
+ constructorOfSchemaSym,
16
+ propertyIsCoValueSchema,
17
+ } from "../resolution.js";
18
+ import { ValueRef, makeRefs } from "../../refs.js";
19
+ import { Account, controlledAccountFromNode } from "../account/accountOf.js";
20
+ import { subscriptionsScopes } from "../../subscriptionScope.js";
21
+ import { SharedCoValueConstructor } from "../construction.js";
22
+ import { pipeArguments } from "effect/Pipeable";
23
+ import { Group } from "../group/groupOf.js";
24
+ import { Stream } from "effect";
25
+ import { UnavailableError } from "../../errors.js";
26
+
27
+ export function CoListOf<
28
+ Item extends CoValueSchema | SchemaWithOutput<JsonValue>,
29
+ >(itemSchema: Item) {
30
+ const decodeItem = Schema.decodeSync(itemSchema);
31
+ const encodeItem = Schema.encodeSync(itemSchema);
32
+
33
+ class CoListOfItem
34
+ extends Array<
35
+ Item extends CoValueSchema
36
+ ? Schema.Schema.To<Item> | undefined
37
+ : Schema.Schema.To<Item>
38
+ >
39
+ implements CoListBase<Item>
40
+ {
41
+ static get ast() {
42
+ return AST.setAnnotation(
43
+ Schema.instanceOf(this).ast,
44
+ constructorOfSchemaSym,
45
+ this
46
+ );
47
+ }
48
+ static [Schema.TypeId]: Schema.Schema.Variance<
49
+ CoListOfItem,
50
+ CoListOfItem,
51
+ never
52
+ >[Schema.TypeId];
53
+ static pipe() {
54
+ // eslint-disable-next-line prefer-rest-params
55
+ return pipeArguments(this, arguments);
56
+ }
57
+ static type = "CoList" as const;
58
+
59
+ id!: ID<this>;
60
+ _type!: "CoList";
61
+ _owner!: AnyAccount | AnyGroup;
62
+ _refs!: CoListBase<Item>["_refs"];
63
+ _edits!: CoListBase<Item>["_edits"];
64
+ _raw!: RawCoList;
65
+ _loadedAs!: ControlledAccount;
66
+ _schema!: typeof CoListOfItem;
67
+
68
+ constructor(_init: undefined, options: { fromRaw: RawCoList });
69
+ constructor(
70
+ init: Schema.Schema.From<Item>[],
71
+ options: { owner: AnyAccount | AnyGroup }
72
+ );
73
+ constructor(init: number);
74
+ constructor(
75
+ init: Schema.Schema.From<Item>[] | undefined | number,
76
+ options?: { owner: AnyAccount | AnyGroup } | { fromRaw: RawCoList }
77
+ ) {
78
+ if (typeof init === "number") {
79
+ // this might be called from an intrinsic, like map, trying to create an empty array
80
+ // passing `0` as the only parameter
81
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
82
+ return new Array(init) as any;
83
+ }
84
+
85
+ super();
86
+
87
+ const itemsAreCoValues = propertyIsCoValueSchema(itemSchema);
88
+
89
+ if (!options) {
90
+ throw new Error("Must provide options");
91
+ }
92
+
93
+ let raw: RawCoList;
94
+
95
+ if ("fromRaw" in options) {
96
+ raw = options.fromRaw;
97
+ } else {
98
+ const rawOwner = options.owner._raw;
99
+
100
+ const rawInit = itemsAreCoValues
101
+ ? init?.map((item) => item.id)
102
+ : init?.map((item) => encodeItem(item));
103
+
104
+ raw = rawOwner.createList(rawInit);
105
+ }
106
+
107
+ const refs = itemsAreCoValues
108
+ ? makeRefs<{ [key: number]: Schema.Schema.To<Item> }>(
109
+ (idx) => raw.get(idx),
110
+ () =>
111
+ Array.from(
112
+ { length: raw.entries().length },
113
+ (_, idx) => idx
114
+ ),
115
+ controlledAccountFromNode(raw.core.node),
116
+ (_idx) => itemSchema
117
+ )
118
+ : [];
119
+
120
+ const getEdits = () =>
121
+ new Proxy(this, {
122
+ get: (target, key, receiver) => {
123
+ if (typeof key === "string" && !isNaN(+key)) {
124
+ const rawEdit = raw.editAt(Number(key));
125
+ if (!rawEdit) return undefined;
126
+
127
+ return {
128
+ get value() {
129
+ if (itemsAreCoValues) {
130
+ return this.ref?.accessFrom(receiver);
131
+ } else {
132
+ return (
133
+ rawEdit?.value &&
134
+ decodeItem(rawEdit?.value)
135
+ );
136
+ }
137
+ },
138
+
139
+ get ref() {
140
+ if (itemsAreCoValues) {
141
+ return (
142
+ rawEdit?.value &&
143
+ new ValueRef(
144
+ rawEdit?.value as ID<CoListOfItem>,
145
+ receiver._loadedAs,
146
+ itemSchema
147
+ )
148
+ );
149
+ }
150
+ },
151
+
152
+ get by() {
153
+ if (
154
+ cojsonInternals.isAccountID(rawEdit.by)
155
+ ) {
156
+ return new ValueRef(
157
+ rawEdit.by as unknown as ID<AnyAccount>,
158
+ receiver._loadedAs,
159
+ Account
160
+ ).accessFrom(receiver);
161
+ }
162
+ },
163
+
164
+ madeAt: rawEdit.at,
165
+ tx: rawEdit.tx,
166
+ };
167
+ } else if (key === "length") {
168
+ return raw.entries().length;
169
+ }
170
+ return Reflect.get(target, key, receiver);
171
+ },
172
+ });
173
+
174
+ Object.defineProperties(this, {
175
+ id: { value: raw.id, enumerable: false },
176
+ _type: { value: "CoList", enumerable: false },
177
+ _owner: {
178
+ get: () =>
179
+ raw.group instanceof RawAccount
180
+ ? Account.fromRaw(raw.group)
181
+ : Group.fromRaw(raw.group),
182
+ enumerable: false,
183
+ },
184
+ _refs: { value: refs, enumerable: false },
185
+ _edits: { get: getEdits, enumerable: false },
186
+ _raw: { value: raw, enumerable: false },
187
+ _loadedAs: {
188
+ get: () => controlledAccountFromNode(raw.core.node),
189
+ enumerable: false,
190
+ },
191
+ _schema: { value: this.constructor, enumerable: false },
192
+ });
193
+
194
+ return new Proxy(this, {
195
+ get(target, key, receiver) {
196
+ if (typeof key === "string" && !isNaN(+key)) {
197
+ if (itemsAreCoValues) {
198
+ return target._refs[Number(key)]?.accessFrom(
199
+ receiver
200
+ );
201
+ } else {
202
+ return decodeItem(raw.get(Number(key)));
203
+ }
204
+ } else if (key === "length") {
205
+ return raw.entries().length;
206
+ }
207
+ const prop = Reflect.get(target, key, receiver);
208
+ if (typeof prop === "function") {
209
+ return prop.bind(receiver);
210
+ }
211
+ return prop;
212
+ },
213
+ set(target, key, value, receiver) {
214
+ if (typeof key === "string" && !isNaN(+key)) {
215
+ if (itemsAreCoValues) {
216
+ raw.replace(Number(key), value.id);
217
+ subscriptionsScopes
218
+ .get(receiver)
219
+ ?.onRefAccessedOrSet(value.id);
220
+ return true;
221
+ } else {
222
+ raw.replace(
223
+ Number(key),
224
+ encodeItem(value) as JsonValue
225
+ );
226
+ return true;
227
+ }
228
+ } else {
229
+ return Reflect.set(target, key, value);
230
+ }
231
+ },
232
+ has(target, key) {
233
+ if (typeof key === "string" && !isNaN(+key)) {
234
+ return Number(key) < raw.entries().length;
235
+ } else {
236
+ return Reflect.has(target, key);
237
+ }
238
+ },
239
+ });
240
+ }
241
+
242
+ static fromRaw(raw: RawCoList): CoListOfItem {
243
+ return new CoListOfItem(undefined, { fromRaw: raw });
244
+ }
245
+
246
+ push(
247
+ ...items: (Item extends CoValueSchema
248
+ ? Schema.Schema.To<Item> | undefined
249
+ : Schema.Schema.To<Item>)[]
250
+ ): number {
251
+ let rawItems;
252
+ if (propertyIsCoValueSchema(itemSchema)) {
253
+ rawItems = items.map((item) => item.id);
254
+ } else {
255
+ rawItems = items.map((item) => encodeItem(item));
256
+ }
257
+
258
+ for (const item of rawItems) {
259
+ this._raw.append(item);
260
+ }
261
+
262
+ return this._raw.entries().length;
263
+ }
264
+
265
+ unshift(
266
+ ...items: (Item extends CoValueSchema
267
+ ? Schema.Schema.To<Item> | undefined
268
+ : Schema.Schema.To<Item>)[]
269
+ ): number {
270
+ let rawItems;
271
+ if (propertyIsCoValueSchema(itemSchema)) {
272
+ rawItems = items.map((item) => item.id);
273
+ } else {
274
+ rawItems = items.map((item) => encodeItem(item));
275
+ }
276
+
277
+ for (const item of rawItems) {
278
+ this._raw.prepend(item);
279
+ }
280
+
281
+ return this._raw.entries().length;
282
+ }
283
+
284
+ pop(): Schema.Schema.To<Item> | undefined {
285
+ const last = this[this.length - 1];
286
+
287
+ this._raw.delete(this.length - 1);
288
+
289
+ return last;
290
+ }
291
+
292
+ shift(): Schema.Schema.To<Item> | undefined {
293
+ const first = this[0];
294
+
295
+ this._raw.delete(0);
296
+
297
+ return first;
298
+ }
299
+
300
+ splice(
301
+ start: number,
302
+ deleteCount: number,
303
+ ...items: (Item extends CoValueSchema
304
+ ? Schema.Schema.To<Item> | undefined
305
+ : Schema.Schema.To<Item>)[]
306
+ ): (Item extends CoValueSchema
307
+ ? Schema.Schema.To<Item> | undefined
308
+ : Schema.Schema.To<Item>)[] {
309
+ const deleted = this.slice(start, start + deleteCount);
310
+
311
+ for (
312
+ let idxToDelete = start + deleteCount;
313
+ idxToDelete > start;
314
+ idxToDelete--
315
+ ) {
316
+ this._raw.delete(idxToDelete);
317
+ }
318
+
319
+ let rawItems;
320
+ if (propertyIsCoValueSchema(itemSchema)) {
321
+ rawItems = items.map((item) => item.id);
322
+ } else {
323
+ rawItems = items.map((item) => encodeItem(item));
324
+ }
325
+
326
+ let appendAfter = start;
327
+ for (const item of rawItems) {
328
+ this._raw.append(item, appendAfter);
329
+ appendAfter++;
330
+ }
331
+
332
+ return deleted;
333
+ }
334
+
335
+ static load = SharedCoValueConstructor.load;
336
+ static loadEf = SharedCoValueConstructor.loadEf;
337
+ static subscribe = SharedCoValueConstructor.subscribe;
338
+ static subscribeEf = SharedCoValueConstructor.subscribeEf;
339
+
340
+ toJSON() {
341
+ return this.map((item) =>
342
+ typeof item === "object" &&
343
+ "toJSON" in item &&
344
+ typeof item.toJSON === "function"
345
+ ? item.toJSON()
346
+ : item
347
+ );
348
+ }
349
+
350
+ [inspect]() {
351
+ return this.toJSON();
352
+ }
353
+
354
+ static as<SubClass>() {
355
+ return CoListOfItem as unknown as CoListSchema<SubClass, Item>;
356
+ }
357
+
358
+ subscribe(listener: (update: this) => void): () => void {
359
+ return SharedCoValueConstructor.prototype.subscribe.call(
360
+ this,
361
+ listener as unknown as (
362
+ update: SharedCoValueConstructor
363
+ ) => void
364
+ );
365
+ }
366
+
367
+ subscribeEf() {
368
+ return SharedCoValueConstructor.prototype.subscribeEf.call(
369
+ this
370
+ ) as unknown as Stream.Stream<this, UnavailableError, never>;
371
+ }
372
+ }
373
+
374
+ return CoListOfItem as CoListSchema<CoListOfItem, Item> & {
375
+ as<SubClass>(): CoListSchema<SubClass, Item>;
376
+ };
377
+ }
@@ -0,0 +1 @@
1
+ export { CoListBase } from "./coList.js";
@@ -0,0 +1,110 @@
1
+ import { CoValue, CoValueSchema } from "../../coValueInterfaces.js";
2
+ import { CojsonInternalTypes, JsonValue, RawCoMap } from "cojson";
3
+ import { ValueRef } from "../../refs.js";
4
+ import {
5
+ PropertySignatureWithOutput,
6
+ SchemaWithInputAndOutput,
7
+ SchemaWithOutput,
8
+ } from "../../schemaHelpers.js";
9
+ import { Schema } from "@effect/schema";
10
+ import { Simplify } from "effect/Types";
11
+ import { AnyAccount } from "../account/account.js";
12
+
13
+ export type IndexSignature = {
14
+ key: SchemaWithInputAndOutput<string, string>;
15
+ value: CoMapFieldValue;
16
+ };
17
+
18
+ export type NoIndexSignature = {
19
+ key: never;
20
+ value: never;
21
+ };
22
+
23
+ /**
24
+ * @category Schemas & CoValues - CoMap
25
+ */
26
+ export interface CoMapBase<
27
+ Fields extends CoMapFields,
28
+ IdxSig extends IndexSignature = never,
29
+ > extends CoValue<"CoMap", RawCoMap> {
30
+ /** @category Referenced CoValues */
31
+ readonly _refs: {
32
+ [Key in keyof Fields as NonNullable<
33
+ Schema.Schema.To<Fields[Key]>
34
+ > extends CoValue
35
+ ? Key
36
+ : never]: ValueRef<NonNullable<Schema.Schema.To<Fields[Key]>>>;
37
+ } & {
38
+ [Key in Schema.Schema.To<IdxSig["key"]>]: NonNullable<
39
+ Schema.Schema.To<IdxSig["value"]>
40
+ > extends CoValue
41
+ ? ValueRef<NonNullable<Schema.Schema.To<IdxSig["value"]>>>
42
+ : never;
43
+ };
44
+
45
+ readonly _edits: {
46
+ [Key in keyof Fields]: {
47
+ value?: Schema.Schema.To<Fields[Key]>;
48
+ ref?: NonNullable<Schema.Schema.To<Fields[Key]>> extends CoValue
49
+ ? ValueRef<Schema.Schema.To<Fields[Key]>>
50
+ : never;
51
+ by?: AnyAccount;
52
+ madeAt: Date;
53
+ tx: CojsonInternalTypes.TransactionID;
54
+ };
55
+ } & {
56
+ [Key in Schema.Schema.To<IdxSig["key"]>]: {
57
+ value?: Schema.Schema.To<IdxSig["value"]>;
58
+ ref?: Schema.Schema.To<IdxSig["value"]> extends CoValueSchema<
59
+ infer Self,
60
+ infer Value
61
+ >
62
+ ? ValueRef<Self & Value>
63
+ : never;
64
+ by?: AnyAccount;
65
+ madeAt: Date;
66
+ tx: CojsonInternalTypes.TransactionID;
67
+ };
68
+ };
69
+ }
70
+
71
+ /**
72
+ * @category Schemas & CoValues - CoMap
73
+ */
74
+ export type CoMap<
75
+ Fields extends CoMapFields,
76
+ IdxSig extends IndexSignature | NoIndexSignature = NoIndexSignature,
77
+ > = {
78
+ /** @category Specified fields */
79
+ [Key in keyof Fields]: Schema.Schema.To<Fields[Key]>;
80
+ } & {
81
+ [Key in Schema.Schema.To<IdxSig["key"]>]: Schema.Schema.To<IdxSig["value"]>;
82
+ } & CoMapBase<Fields, IdxSig>;
83
+
84
+ /** @category Schemas & CoValues - CoMap */
85
+ export interface CoMapSchema<
86
+ Self,
87
+ Fields extends CoMapFields,
88
+ IdxSig extends IndexSignature | NoIndexSignature,
89
+ > extends CoValueSchema<
90
+ Self,
91
+ CoMap<Fields, IdxSig>,
92
+ "CoMap",
93
+ Simplify<CoMapInit<Fields, IdxSig>>
94
+ > {}
95
+
96
+ export type CoMapFieldValue =
97
+ | SchemaWithOutput<CoValue | undefined>
98
+ | SchemaWithOutput<JsonValue>
99
+ | PropertySignatureWithOutput<CoValue | JsonValue | undefined>;
100
+
101
+ export type CoMapFields = {
102
+ [key: string]: CoMapFieldValue;
103
+ };
104
+
105
+ export type CoMapInit<
106
+ Fields extends CoMapFields,
107
+ IdxSig extends IndexSignature = never,
108
+ > = Schema.ToStruct<Fields> & {
109
+ [Key in Schema.Schema.To<IdxSig["key"]>]: Schema.Schema.To<IdxSig["value"]>;
110
+ };