jazz-tools 0.7.0-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ };