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

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