jazz-tools 0.7.0-alpha.0 → 0.7.0-alpha.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. package/.eslintrc.cjs +8 -1
  2. package/.turbo/turbo-build.log +79 -9
  3. package/CHANGELOG.md +76 -0
  4. package/dist/coValues/account.js +171 -0
  5. package/dist/coValues/account.js.map +1 -0
  6. package/dist/coValues/coList.js +246 -0
  7. package/dist/coValues/coList.js.map +1 -0
  8. package/dist/coValues/coMap.js +235 -0
  9. package/dist/coValues/coMap.js.map +1 -0
  10. package/dist/coValues/coStream.js +263 -0
  11. package/dist/coValues/coStream.js.map +1 -0
  12. package/dist/coValues/extensions/imageDef.js +14 -11
  13. package/dist/coValues/extensions/imageDef.js.map +1 -1
  14. package/dist/coValues/group.js +71 -0
  15. package/dist/coValues/group.js.map +1 -0
  16. package/dist/coValues/interfaces.js +61 -0
  17. package/dist/coValues/interfaces.js.map +1 -0
  18. package/dist/implementation/errors.js.map +1 -0
  19. package/dist/implementation/inspect.js +2 -0
  20. package/dist/implementation/inspect.js.map +1 -0
  21. package/dist/{refs.js → implementation/refs.js} +16 -15
  22. package/dist/implementation/refs.js.map +1 -0
  23. package/dist/implementation/schema.js +41 -0
  24. package/dist/implementation/schema.js.map +1 -0
  25. package/dist/{subscriptionScope.js → implementation/subscriptionScope.js} +1 -1
  26. package/dist/implementation/subscriptionScope.js.map +1 -0
  27. package/dist/index.js +10 -29
  28. package/dist/index.js.map +1 -1
  29. package/dist/internal.js +13 -0
  30. package/dist/internal.js.map +1 -0
  31. package/dist/tests/coList.test.js +22 -22
  32. package/dist/tests/coList.test.js.map +1 -1
  33. package/dist/tests/coMap.test.js +140 -46
  34. package/dist/tests/coMap.test.js.map +1 -1
  35. package/dist/tests/coStream.test.js +55 -49
  36. package/dist/tests/coStream.test.js.map +1 -1
  37. package/package.json +11 -4
  38. package/src/coValues/account.ts +327 -0
  39. package/src/coValues/coList.ts +391 -0
  40. package/src/coValues/coMap.ts +413 -0
  41. package/src/coValues/coStream.ts +404 -0
  42. package/src/coValues/extensions/imageDef.ts +20 -16
  43. package/src/coValues/group.ts +139 -0
  44. package/src/coValues/interfaces.ts +218 -0
  45. package/src/implementation/inspect.ts +2 -0
  46. package/src/{refs.ts → implementation/refs.ts} +53 -39
  47. package/src/implementation/schema.ts +124 -0
  48. package/src/{subscriptionScope.ts → implementation/subscriptionScope.ts} +11 -13
  49. package/src/index.ts +14 -57
  50. package/src/internal.ts +15 -0
  51. package/src/tests/coList.test.ts +23 -25
  52. package/src/tests/coMap.test.ts +140 -53
  53. package/src/tests/coStream.test.ts +76 -68
  54. package/dist/coValueInterfaces.js +0 -8
  55. package/dist/coValueInterfaces.js.map +0 -1
  56. package/dist/coValues/account/account.js +0 -11
  57. package/dist/coValues/account/account.js.map +0 -1
  58. package/dist/coValues/account/accountOf.js +0 -150
  59. package/dist/coValues/account/accountOf.js.map +0 -1
  60. package/dist/coValues/account/migration.js +0 -4
  61. package/dist/coValues/account/migration.js.map +0 -1
  62. package/dist/coValues/coList/coList.js +0 -2
  63. package/dist/coValues/coList/coList.js.map +0 -1
  64. package/dist/coValues/coList/coListOf.js +0 -235
  65. package/dist/coValues/coList/coListOf.js.map +0 -1
  66. package/dist/coValues/coList/internalDocs.js +0 -2
  67. package/dist/coValues/coList/internalDocs.js.map +0 -1
  68. package/dist/coValues/coMap/coMap.js +0 -2
  69. package/dist/coValues/coMap/coMap.js.map +0 -1
  70. package/dist/coValues/coMap/coMapOf.js +0 -262
  71. package/dist/coValues/coMap/coMapOf.js.map +0 -1
  72. package/dist/coValues/coMap/internalDocs.js +0 -2
  73. package/dist/coValues/coMap/internalDocs.js.map +0 -1
  74. package/dist/coValues/coStream/coStream.js +0 -2
  75. package/dist/coValues/coStream/coStream.js.map +0 -1
  76. package/dist/coValues/coStream/coStreamOf.js +0 -244
  77. package/dist/coValues/coStream/coStreamOf.js.map +0 -1
  78. package/dist/coValues/construction.js +0 -34
  79. package/dist/coValues/construction.js.map +0 -1
  80. package/dist/coValues/group/group.js +0 -2
  81. package/dist/coValues/group/group.js.map +0 -1
  82. package/dist/coValues/group/groupOf.js +0 -109
  83. package/dist/coValues/group/groupOf.js.map +0 -1
  84. package/dist/coValues/resolution.js +0 -66
  85. package/dist/coValues/resolution.js.map +0 -1
  86. package/dist/errors.js.map +0 -1
  87. package/dist/refs.js.map +0 -1
  88. package/dist/schemaHelpers.js +0 -14
  89. package/dist/schemaHelpers.js.map +0 -1
  90. package/dist/subscriptionScope.js.map +0 -1
  91. package/dist/tests/types.test.js +0 -33
  92. package/dist/tests/types.test.js.map +0 -1
  93. package/src/coValueInterfaces.ts +0 -105
  94. package/src/coValues/account/account.ts +0 -106
  95. package/src/coValues/account/accountOf.ts +0 -284
  96. package/src/coValues/account/migration.ts +0 -12
  97. package/src/coValues/coList/coList.ts +0 -57
  98. package/src/coValues/coList/coListOf.ts +0 -377
  99. package/src/coValues/coList/internalDocs.ts +0 -1
  100. package/src/coValues/coMap/coMap.ts +0 -110
  101. package/src/coValues/coMap/coMapOf.ts +0 -451
  102. package/src/coValues/coMap/internalDocs.ts +0 -1
  103. package/src/coValues/coStream/coStream.ts +0 -63
  104. package/src/coValues/coStream/coStreamOf.ts +0 -404
  105. package/src/coValues/construction.ts +0 -110
  106. package/src/coValues/group/group.ts +0 -27
  107. package/src/coValues/group/groupOf.ts +0 -183
  108. package/src/coValues/resolution.ts +0 -111
  109. package/src/schemaHelpers.ts +0 -72
  110. package/src/tests/types.test.ts +0 -37
  111. /package/dist/{errors.js → implementation/errors.js} +0 -0
  112. /package/src/{errors.ts → implementation/errors.ts} +0 -0
@@ -0,0 +1,413 @@
1
+ import type { JsonValue, RawCoMap } from "cojson";
2
+ import type { Simplify } from "effect/Types";
3
+ import { Schema as EffectSchema } from "@effect/schema";
4
+ import type {
5
+ CoValue,
6
+ Schema,
7
+ SchemaFor,
8
+ Group,
9
+ ID,
10
+ RefEncoded,
11
+ EnsureCoValueNullable,
12
+ IfCo,
13
+ } from "../internal.js";
14
+ import {
15
+ Account,
16
+ CoValueBase,
17
+ Ref,
18
+ SchemaInit,
19
+ inspect,
20
+ makeRefs,
21
+ subscriptionsScopes,
22
+ ItemsSym,
23
+ InitValues,
24
+ isRefEncoded,
25
+ } from "../internal.js";
26
+
27
+ type ValidFields<Fields extends { [key: string]: any; [ItemsSym]?: any }> = {
28
+ [Key in keyof Fields & string as IfCo<
29
+ Fields[Key],
30
+ IfOptionalKey<Key, Fields>
31
+ >]?: EnsureCoValueNullable<Fields[Key], Key>;
32
+ } & {
33
+ [Key in keyof Fields & string as IfCo<
34
+ Fields[Key],
35
+ IfRequiredKey<Key, Fields>
36
+ >]: EnsureCoValueNullable<Fields[Key], Key>;
37
+ } & {
38
+ [Key in ItemsSym]?: EnsureCoValueNullable<Fields[ItemsSym], Key>;
39
+ };
40
+
41
+ type IfOptionalKey<Key extends keyof Obj, Obj> = Pick<
42
+ Partial<Obj>,
43
+ Key
44
+ > extends Pick<Obj, Key>
45
+ ? Key
46
+ : never;
47
+ type IfRequiredKey<Key extends keyof Obj, Obj> = Pick<
48
+ Partial<Obj>,
49
+ Key
50
+ > extends Pick<Obj, Key>
51
+ ? never
52
+ : Key;
53
+
54
+ type DefaultFields = {
55
+ [key: string]: any;
56
+ [ItemsSym]?: any;
57
+ };
58
+
59
+ type CoMapSchema<Fields extends object> = {
60
+ [Key in OwnKeys<Fields> as IfCo<Fields[Key], Key>]: SchemaFor<
61
+ Fields[Key]
62
+ >;
63
+ } & {
64
+ [ItemsSym]: ItemsSym extends keyof Fields
65
+ ? SchemaFor<Fields[ItemsSym]>
66
+ : never;
67
+ };
68
+
69
+ type CoMapEdit<V> = {
70
+ value?: V;
71
+ ref?: V extends CoValue ? Ref<V> : never;
72
+ by?: Account;
73
+ madeAt: Date;
74
+ };
75
+
76
+ type InitValuesFor<C extends CoMap> = {
77
+ init: Simplify<CoMapInit<C>>;
78
+ owner: Account | Group;
79
+ };
80
+
81
+ export class CoMap<Fields extends ValidFields<Fields> = DefaultFields>
82
+ extends CoValueBase
83
+ implements CoValue<"CoMap", RawCoMap>
84
+ {
85
+ declare id: ID<this>;
86
+ declare _type: "CoMap";
87
+ static {
88
+ this.prototype._type = "CoMap";
89
+ }
90
+ declare _raw: RawCoMap;
91
+
92
+ static _schema: any;
93
+ get _schema() {
94
+ return (this.constructor as typeof CoMap)
95
+ ._schema as CoMapSchema<this>;
96
+ }
97
+
98
+ get _refs(): {
99
+ [Key in OwnKeys<this> as NonNullable<this[Key]> extends CoValue
100
+ ? Key
101
+ : never]: NonNullable<this[Key]> extends CoValue
102
+ ? Ref<NonNullable<this[Key]>>
103
+ : never;
104
+ } {
105
+ return makeRefs<OwnKeys<Fields>>(
106
+ (key) => this._raw.get(key as string) as unknown as ID<CoValue>,
107
+ () =>
108
+ Object.keys(this._schema).filter((key) => {
109
+ const schema = this._schema[
110
+ key as keyof typeof this._schema
111
+ ] as Schema;
112
+ schema !== "json" && isRefEncoded(schema);
113
+ }) as OwnKeys<Fields>[],
114
+ this._loadedAs,
115
+ (key) => this._schema[key] as RefEncoded<CoValue>
116
+ ) as any;
117
+ }
118
+
119
+ get _edits() {
120
+ return new Proxy(this, {
121
+ get(target, key) {
122
+ const rawEdit = target._raw.lastEditAt(key as string);
123
+ if (!rawEdit) return undefined;
124
+
125
+ const descriptor = target._schema[
126
+ key as keyof typeof target._schema
127
+ ] as Schema;
128
+
129
+ return {
130
+ value:
131
+ descriptor === "json"
132
+ ? rawEdit.value
133
+ : "encoded" in descriptor
134
+ ? EffectSchema.decodeSync(descriptor.encoded)(
135
+ rawEdit.value
136
+ )
137
+ : new Ref(
138
+ rawEdit.value as ID<CoValue>,
139
+ target._loadedAs,
140
+ descriptor
141
+ ).accessFrom(target),
142
+ ref:
143
+ descriptor !== "json" && isRefEncoded(descriptor)
144
+ ? new Ref(
145
+ rawEdit.value as ID<CoValue>,
146
+ target._loadedAs,
147
+ descriptor
148
+ )
149
+ : undefined,
150
+ by:
151
+ rawEdit.by &&
152
+ new Ref(
153
+ rawEdit.by as ID<Account>,
154
+ target._loadedAs,
155
+ Account
156
+ ).accessFrom(target),
157
+ madeAt: rawEdit.at,
158
+ };
159
+ },
160
+ }) as {
161
+ [Key in OwnKeys<this> as IfCo<this[Key], Key>]: CoMapEdit<
162
+ this[Key]
163
+ >;
164
+ };
165
+ }
166
+
167
+ get _loadedAs() {
168
+ return Account.fromNode(this._raw.core.node);
169
+ }
170
+
171
+ [InitValues]?: InitValuesFor<this>;
172
+
173
+ constructor(_init: undefined, options: { fromRaw: RawCoMap });
174
+ constructor(
175
+ init: Simplify<CoMapInit<Fields>>,
176
+ options: { owner: Account | Group }
177
+ );
178
+ constructor(
179
+ init: Simplify<CoMapInit<Fields>> | undefined,
180
+ options: { owner: Account | Group } | { fromRaw: RawCoMap }
181
+ ) {
182
+ super();
183
+
184
+ if (init && "owner" in options) {
185
+ this[InitValues] = {
186
+ init,
187
+ owner: options.owner,
188
+ } as InitValuesFor<this>;
189
+ } else if ("fromRaw" in options) {
190
+ Object.defineProperties(this, {
191
+ id: {
192
+ value: options.fromRaw.id as unknown as ID<this>,
193
+ enumerable: false,
194
+ },
195
+ _raw: { value: options.fromRaw, enumerable: false },
196
+ });
197
+ } else {
198
+ throw new Error("Invalid CoMap constructor arguments");
199
+ }
200
+
201
+ return new Proxy(this, CoMapProxyHandler as ProxyHandler<this>);
202
+ }
203
+
204
+ toJSON() {
205
+ const jsonedFields = this._raw.keys().map((key) => {
206
+ const tKey = key as OwnKeys<Fields>;
207
+ const descriptor = this._schema[tKey] as Schema;
208
+
209
+ if (descriptor == "json" || "encode" in descriptor) {
210
+ return [key, this._raw.get(key)];
211
+ } else if (isRefEncoded(descriptor)) {
212
+ const jsonedRef = (this as any)[tKey]?.toJSON();
213
+ return [key, jsonedRef];
214
+ } else {
215
+ return [key, undefined];
216
+ }
217
+ });
218
+
219
+ return {
220
+ id: this.id,
221
+ _type: this._type,
222
+ ...Object.fromEntries(jsonedFields),
223
+ };
224
+ }
225
+
226
+ [inspect]() {
227
+ return this.toJSON();
228
+ }
229
+
230
+ rawFromInit<Fields extends object = Record<string, any>>(
231
+ init: Simplify<CoMapInit<Fields>> | undefined,
232
+ owner: Account | Group
233
+ ) {
234
+ const rawOwner = owner._raw;
235
+
236
+ const rawInit = {} as {
237
+ [key in keyof Fields]: JsonValue | undefined;
238
+ };
239
+
240
+ if (init)
241
+ for (const key of Object.keys(init) as (keyof Fields)[]) {
242
+ const initValue = init[key as keyof typeof init];
243
+
244
+ const descriptor = (this._schema[
245
+ key as keyof typeof this._schema
246
+ ] || this._schema[ItemsSym]) as Schema;
247
+
248
+ if (descriptor === "json") {
249
+ rawInit[key] = initValue as JsonValue;
250
+ } else if (isRefEncoded(descriptor)) {
251
+ if (initValue) {
252
+ rawInit[key] = (initValue as unknown as CoValue).id;
253
+ }
254
+ } else if ("encoded" in descriptor) {
255
+ rawInit[key] = EffectSchema.encodeSync(descriptor.encoded)(
256
+ initValue as any
257
+ );
258
+ }
259
+ }
260
+
261
+ return rawOwner.createMap(rawInit);
262
+ }
263
+ }
264
+
265
+ export type OwnKeys<Fields extends object> = Exclude<
266
+ keyof Fields & string,
267
+ keyof CoMap<Record<string, never>>
268
+ >;
269
+
270
+ export type CoMapInit<Fields extends object> = {
271
+ [Key in OwnKeys<Fields> as undefined extends Fields[Key]
272
+ ? never
273
+ : null extends Fields[Key]
274
+ ? never
275
+ : IfCo<Fields[Key], Key>]: Fields[Key];
276
+ } & { [Key in OwnKeys<Fields> as IfCo<Fields[Key], Key>]?: Fields[Key] };
277
+
278
+ function tryInit(map: CoMap) {
279
+ if (
280
+ map[InitValues] &&
281
+ (map._schema[ItemsSym] ||
282
+ Object.keys(map[InitValues].init).every(
283
+ (key) => (map._schema as any)[key]
284
+ ))
285
+ ) {
286
+ const raw = map.rawFromInit(
287
+ map[InitValues].init,
288
+ map[InitValues].owner
289
+ );
290
+ Object.defineProperties(map, {
291
+ id: {
292
+ value: raw.id,
293
+ enumerable: false,
294
+ },
295
+ _raw: { value: raw, enumerable: false },
296
+ });
297
+ delete map[InitValues];
298
+ }
299
+ }
300
+
301
+ // TODO: cache handlers per descriptor for performance?
302
+ const CoMapProxyHandler: ProxyHandler<CoMap> = {
303
+ get(target, key, receiver) {
304
+ if (key === "_schema") {
305
+ return Reflect.get(target, key);
306
+ } else if (key in target) {
307
+ return Reflect.get(target, key, receiver);
308
+ } else {
309
+ const descriptor = (target._schema[
310
+ key as keyof CoMap["_schema"]
311
+ ] || target._schema[ItemsSym]) as Schema;
312
+ if (descriptor && typeof key === "string") {
313
+ const raw = target._raw.get(key);
314
+
315
+ if (descriptor === "json") {
316
+ return raw;
317
+ } else if ("encoded" in descriptor) {
318
+ return raw === undefined
319
+ ? undefined
320
+ : EffectSchema.decodeSync(descriptor.encoded)(raw);
321
+ } else if (isRefEncoded(descriptor)) {
322
+ return raw === undefined
323
+ ? undefined
324
+ : new Ref(
325
+ raw as unknown as ID<CoValue>,
326
+ target._loadedAs,
327
+ descriptor
328
+ ).accessFrom(receiver);
329
+ }
330
+ } else {
331
+ return undefined;
332
+ }
333
+ }
334
+ },
335
+ set(target, key, value, receiver) {
336
+ if (
337
+ (typeof key === "string" || ItemsSym) &&
338
+ typeof value === "object" &&
339
+ SchemaInit in value
340
+ ) {
341
+ (target.constructor as typeof CoMap)._schema ||= {};
342
+ (target.constructor as typeof CoMap)._schema[key] =
343
+ value[SchemaInit];
344
+ tryInit(target);
345
+ return true;
346
+ }
347
+
348
+ const descriptor = (target._schema[key as keyof CoMap["_schema"]] ||
349
+ target._schema[ItemsSym]) as Schema;
350
+ if (descriptor && typeof key === "string") {
351
+ if (descriptor === "json") {
352
+ target._raw.set(key, value);
353
+ } else if ("encoded" in descriptor) {
354
+ target._raw.set(
355
+ key,
356
+ EffectSchema.encodeSync(descriptor.encoded)(value)
357
+ );
358
+ } else if (isRefEncoded(descriptor)) {
359
+ target._raw.set(key, value.id);
360
+ subscriptionsScopes.get(target)?.onRefAccessedOrSet(value.id);
361
+ }
362
+ return true;
363
+ } else {
364
+ return Reflect.set(target, key, value, receiver);
365
+ }
366
+ },
367
+ defineProperty(target, key, attributes) {
368
+ if (
369
+ "value" in attributes &&
370
+ typeof attributes.value === "object" &&
371
+ SchemaInit in attributes.value
372
+ ) {
373
+ (target.constructor as typeof CoMap)._schema ||= {};
374
+ (target.constructor as typeof CoMap)._schema[key as string] =
375
+ attributes.value[SchemaInit];
376
+ tryInit(target);
377
+ return true;
378
+ } else {
379
+ return Reflect.defineProperty(target, key, attributes);
380
+ }
381
+ },
382
+ ownKeys(target) {
383
+ const keys = Reflect.ownKeys(target).filter((k) => k !== ItemsSym);
384
+ for (const key of Reflect.ownKeys(target._schema)) {
385
+ if (key !== ItemsSym && !keys.includes(key)) {
386
+ keys.push(key);
387
+ }
388
+ }
389
+ for (const key of target._raw.keys()) {
390
+ if (!keys.includes(key)) {
391
+ keys.push(key);
392
+ }
393
+ }
394
+
395
+ return keys;
396
+ },
397
+ getOwnPropertyDescriptor(target, key) {
398
+ if (key in target) {
399
+ return Reflect.getOwnPropertyDescriptor(target, key);
400
+ } else {
401
+ const descriptor = (target._schema[
402
+ key as keyof CoMap["_schema"]
403
+ ] || target._schema[ItemsSym]) as Schema;
404
+ if (descriptor || key in target._raw.ops) {
405
+ return {
406
+ enumerable: true,
407
+ configurable: true,
408
+ writable: true,
409
+ };
410
+ }
411
+ }
412
+ },
413
+ };