jazz-tools 0.7.0-alpha.8 → 0.7.1

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 (72) hide show
  1. package/.eslintrc.cjs +3 -10
  2. package/.prettierrc.js +9 -0
  3. package/.turbo/turbo-build.log +3 -19
  4. package/.turbo/turbo-lint.log +4 -0
  5. package/.turbo/turbo-test.log +140 -0
  6. package/CHANGELOG.md +304 -0
  7. package/README.md +10 -2
  8. package/dist/coValues/account.js +59 -41
  9. package/dist/coValues/account.js.map +1 -1
  10. package/dist/coValues/coList.js +49 -46
  11. package/dist/coValues/coList.js.map +1 -1
  12. package/dist/coValues/coMap.js +143 -44
  13. package/dist/coValues/coMap.js.map +1 -1
  14. package/dist/coValues/coStream.js +144 -35
  15. package/dist/coValues/coStream.js.map +1 -1
  16. package/dist/coValues/deepLoading.js +60 -0
  17. package/dist/coValues/deepLoading.js.map +1 -0
  18. package/dist/coValues/extensions/imageDef.js +10 -7
  19. package/dist/coValues/extensions/imageDef.js.map +1 -1
  20. package/dist/coValues/group.js +49 -13
  21. package/dist/coValues/group.js.map +1 -1
  22. package/dist/coValues/interfaces.js +70 -31
  23. package/dist/coValues/interfaces.js.map +1 -1
  24. package/dist/implementation/devtoolsFormatters.js +114 -0
  25. package/dist/implementation/devtoolsFormatters.js.map +1 -0
  26. package/dist/implementation/refs.js +58 -18
  27. package/dist/implementation/refs.js.map +1 -1
  28. package/dist/implementation/schema.js +58 -0
  29. package/dist/implementation/schema.js.map +1 -0
  30. package/dist/implementation/subscriptionScope.js +19 -1
  31. package/dist/implementation/subscriptionScope.js.map +1 -1
  32. package/dist/implementation/symbols.js +5 -0
  33. package/dist/implementation/symbols.js.map +1 -0
  34. package/dist/index.js +3 -5
  35. package/dist/index.js.map +1 -1
  36. package/dist/internal.js +5 -2
  37. package/dist/internal.js.map +1 -1
  38. package/dist/tests/coList.test.js +51 -48
  39. package/dist/tests/coList.test.js.map +1 -1
  40. package/dist/tests/coMap.test.js +131 -73
  41. package/dist/tests/coMap.test.js.map +1 -1
  42. package/dist/tests/coStream.test.js +56 -41
  43. package/dist/tests/coStream.test.js.map +1 -1
  44. package/dist/tests/deepLoading.test.js +188 -0
  45. package/dist/tests/deepLoading.test.js.map +1 -0
  46. package/dist/tests/groupsAndAccounts.test.js +83 -0
  47. package/dist/tests/groupsAndAccounts.test.js.map +1 -0
  48. package/package.json +17 -9
  49. package/src/coValues/account.ts +113 -125
  50. package/src/coValues/coList.ts +87 -103
  51. package/src/coValues/coMap.ts +200 -147
  52. package/src/coValues/coStream.ts +264 -80
  53. package/src/coValues/deepLoading.ts +229 -0
  54. package/src/coValues/extensions/imageDef.ts +17 -13
  55. package/src/coValues/group.ts +92 -58
  56. package/src/coValues/interfaces.ts +215 -115
  57. package/src/implementation/devtoolsFormatters.ts +110 -0
  58. package/src/implementation/inspect.ts +1 -1
  59. package/src/implementation/refs.ts +80 -28
  60. package/src/implementation/schema.ts +138 -0
  61. package/src/implementation/subscriptionScope.ts +48 -12
  62. package/src/implementation/symbols.ts +11 -0
  63. package/src/index.ts +12 -8
  64. package/src/internal.ts +7 -3
  65. package/src/tests/coList.test.ts +77 -62
  66. package/src/tests/coMap.test.ts +201 -113
  67. package/src/tests/coStream.test.ts +113 -84
  68. package/src/tests/deepLoading.test.ts +301 -0
  69. package/src/tests/groupsAndAccounts.test.ts +91 -0
  70. package/dist/implementation/encoding.js +0 -26
  71. package/dist/implementation/encoding.js.map +0 -1
  72. package/src/implementation/encoding.ts +0 -105
@@ -1,15 +1,15 @@
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
- Encoding,
7
- EncodingFor,
6
+ Schema,
8
7
  Group,
9
8
  ID,
10
9
  RefEncoded,
11
- EnsureCoValueNullable,
12
- IsVal,
10
+ IfCo,
11
+ RefIfCoValue,
12
+ ClassOf,
13
13
  } from "../internal.js";
14
14
  import {
15
15
  Account,
@@ -21,161 +21,182 @@ import {
21
21
  subscriptionsScopes,
22
22
  ItemsSym,
23
23
  InitValues,
24
+ isRefEncoded,
24
25
  } from "../internal.js";
25
26
 
26
- type ValidFields<Fields extends { [key: string]: any; [ItemsSym]?: any }> = {
27
- [Key in keyof Fields & string as IsVal<
28
- Fields[Key],
29
- IfOptionalKey<Key, Fields>
30
- >]?: EnsureCoValueNullable<Fields[Key], Key>;
31
- } & {
32
- [Key in keyof Fields & string as IsVal<
33
- Fields[Key],
34
- IfRequiredKey<Key, Fields>
35
- >]: EnsureCoValueNullable<Fields[Key], Key>;
36
- } & {
37
- [Key in ItemsSym]?: EnsureCoValueNullable<Fields[ItemsSym], Key>;
38
- };
39
-
40
- type IfOptionalKey<Key extends keyof Obj, Obj> = Pick<
41
- Partial<Obj>,
42
- Key
43
- > extends Pick<Obj, Key>
44
- ? Key
45
- : never;
46
- type IfRequiredKey<Key extends keyof Obj, Obj> = Pick<
47
- Partial<Obj>,
48
- Key
49
- > extends Pick<Obj, Key>
50
- ? never
51
- : Key;
52
-
53
- type DefaultFields = {
54
- [key: string]: any;
55
- [ItemsSym]?: any;
56
- };
57
-
58
- type CoMapEncoding<Fields extends object> = {
59
- [Key in OwnKeys<Fields> as IsVal<Fields[Key], Key>]: EncodingFor<
60
- Fields[Key]
61
- >;
62
- } &
63
- {
64
- [ItemsSym]: ItemsSym extends keyof Fields ? EncodingFor<Fields[ItemsSym]> : never;
65
- }
66
-
67
27
  type CoMapEdit<V> = {
68
28
  value?: V;
69
- ref?: V extends CoValue ? Ref<V> : never;
29
+ ref?: RefIfCoValue<V>;
70
30
  by?: Account;
71
31
  madeAt: Date;
72
- }
32
+ };
73
33
 
74
34
  type InitValuesFor<C extends CoMap> = {
75
35
  init: Simplify<CoMapInit<C>>;
76
36
  owner: Account | Group;
77
- }
37
+ };
78
38
 
79
- export class CoMap<Fields extends ValidFields<Fields> = DefaultFields>
80
- extends CoValueBase
81
- implements CoValue<"CoMap", RawCoMap>
82
- {
83
- id!: ID<this>;
84
- _type!: "CoMap";
39
+ /**
40
+ * CoMaps are collaborative versions of plain objects, mapping string-like keys to values.
41
+ *
42
+ * @categoryDescription Declaration
43
+ * Declare your own CoMap schemas by subclassing `CoMap` and assigning field schemas with `co`.
44
+ *
45
+ * ```ts
46
+ * import { co, CoMap } from "jazz-tools";
47
+ *
48
+ * class Person extends CoMap {
49
+ * name = co.string;
50
+ * age = co.number;
51
+ * pet = co.ref(Animal);
52
+ * }
53
+ * ```
54
+ *
55
+ * @categoryDescription Content
56
+ * You can access properties you declare on a `CoMap` (using `co`) as if they were normal properties on a plain object, using dot notation, `Object.keys()`, etc.
57
+ *
58
+ * ```ts
59
+ * person.name;
60
+ * person["age"];
61
+ * person.age = 42;
62
+ * person.pet?.name;
63
+ * Object.keys(person);
64
+ * // => ["name", "age", "pet"]
65
+ * ```
66
+ *
67
+ * @category CoValues
68
+ * */
69
+ export class CoMap extends CoValueBase implements CoValue<"CoMap", RawCoMap> {
70
+ /**
71
+ * The ID of this `CoMap`
72
+ * @category Content */
73
+ declare id: ID<this>;
74
+ /** @category Type Helpers */
75
+ declare _type: "CoMap";
85
76
  static {
86
77
  this.prototype._type = "CoMap";
87
78
  }
88
- _raw!: RawCoMap;
89
-
90
- static _encoding: any;
91
- get _encoding() {
92
- return (this.constructor as typeof CoMap)._encoding as CoMapEncoding<this>
79
+ /** @category Internals */
80
+ declare _raw: RawCoMap;
81
+
82
+ /** @internal */
83
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
+ static _schema: any;
85
+ /** @internal */
86
+ get _schema() {
87
+ return (this.constructor as typeof CoMap)._schema as {
88
+ [key: string]: Schema;
89
+ } & { [ItemsSym]?: Schema };
93
90
  }
94
91
 
92
+ /**
93
+ * If property `prop` is a `co.ref(...)`, you can use `coMaps._refs.prop` to access
94
+ * the `Ref` instead of the potentially loaded/null value.
95
+ * This allows you to always get the ID or load the value manually.
96
+ *
97
+ * @example
98
+ * ```ts
99
+ * person._refs.pet.id; // => ID<Animal>
100
+ * person._refs.pet.value;
101
+ * // => Animal | undefined
102
+ * const pet = await person._refs.pet.load();
103
+ * ```
104
+ *
105
+ * @category Content */
95
106
  get _refs(): {
96
- [Key in OwnKeys<Fields> as NonNullable<Fields[Key]> extends CoValue
97
- ? Key
98
- : never]: NonNullable<Fields[Key]> extends CoValue
99
- ? Ref<NonNullable<Fields[Key]>>
100
- : never;
107
+ [Key in CoKeys<this>]: IfCo<this[Key], RefIfCoValue<this[Key]>>;
101
108
  } {
102
- return makeRefs<OwnKeys<Fields>>(
109
+ return makeRefs<CoKeys<this>>(
103
110
  (key) => this._raw.get(key as string) as unknown as ID<CoValue>,
104
- () =>
105
- Object.keys(this._encoding).filter((key) => {
106
- const schema = this._encoding[
107
- key as keyof typeof this._encoding
108
- ] as Encoding;
109
- schema !== "json" && "ref" in schema;
110
- }) as OwnKeys<Fields>[],
111
+ () => {
112
+ const keys = this._raw.keys().filter((key) => {
113
+ const schema =
114
+ this._schema[key as keyof typeof this._schema] ||
115
+ (this._schema[ItemsSym] as Schema | undefined);
116
+ return schema && schema !== "json" && isRefEncoded(schema);
117
+ }) as CoKeys<this>[];
118
+
119
+ return keys;
120
+ },
111
121
  this._loadedAs,
112
- (key) => this._encoding[key] as RefEncoded<CoValue>
122
+ (key) =>
123
+ (this._schema[key] ||
124
+ this._schema[ItemsSym]) as RefEncoded<CoValue>,
125
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
126
  ) as any;
114
127
  }
115
128
 
129
+ /** @category Collaboration */
116
130
  get _edits() {
117
131
  return new Proxy(this, {
118
132
  get(target, key) {
119
133
  const rawEdit = target._raw.lastEditAt(key as string);
120
134
  if (!rawEdit) return undefined;
121
135
 
122
- const descriptor = target._encoding[
123
- key as keyof typeof target._encoding
124
- ] as Encoding;
136
+ const descriptor = target._schema[
137
+ key as keyof typeof target._schema
138
+ ] as Schema;
125
139
 
126
140
  return {
127
141
  value:
128
142
  descriptor === "json"
129
143
  ? rawEdit.value
130
144
  : "encoded" in descriptor
131
- ? Schema.decodeSync(descriptor.encoded)(
132
- rawEdit.value
133
- )
145
+ ? decodeSync(descriptor.encoded)(rawEdit.value)
134
146
  : new Ref(
135
147
  rawEdit.value as ID<CoValue>,
136
148
  target._loadedAs,
137
- descriptor
138
- ).accessFrom(target),
149
+ descriptor,
150
+ ).accessFrom(
151
+ target,
152
+ "_edits." + key.toString() + ".value",
153
+ ),
139
154
  ref:
140
- descriptor !== "json" && "ref" in descriptor
155
+ descriptor !== "json" && isRefEncoded(descriptor)
141
156
  ? new Ref(
142
157
  rawEdit.value as ID<CoValue>,
143
158
  target._loadedAs,
144
- descriptor
159
+ descriptor,
145
160
  )
146
161
  : undefined,
147
162
  by:
148
163
  rawEdit.by &&
149
164
  new Ref(rawEdit.by as ID<Account>, target._loadedAs, {
150
- ref: () => Account,
151
- }).accessFrom(target),
165
+ ref: Account,
166
+ optional: false,
167
+ }).accessFrom(
168
+ target,
169
+ "_edits." + key.toString() + ".by",
170
+ ),
152
171
  madeAt: rawEdit.at,
153
172
  };
154
173
  },
155
174
  }) as {
156
- [Key in OwnKeys<this> as IsVal<this[Key], Key>]: CoMapEdit<this[Key]>
175
+ [Key in CoKeys<this>]: IfCo<this[Key], CoMapEdit<this[Key]>>;
157
176
  };
158
177
  }
159
178
 
179
+ /** @internal */
160
180
  get _loadedAs() {
161
181
  return Account.fromNode(this._raw.core.node);
162
182
  }
163
183
 
164
- [InitValues]?: InitValuesFor<this>;
184
+ /** @internal */
185
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
186
+ [InitValues]?: any;
165
187
 
166
- constructor(_init: undefined, options: { fromRaw: RawCoMap });
188
+ /** @internal */
167
189
  constructor(
168
- init: Simplify<CoMapInit<Fields>>,
169
- options: { owner: Account | Group }
170
- );
171
- constructor(
172
- init: Simplify<CoMapInit<Fields>> | undefined,
173
- options: { owner: Account | Group } | { fromRaw: RawCoMap }
190
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
191
+ options: { fromRaw: RawCoMap } | { init: any; owner: Account | Group },
174
192
  ) {
175
193
  super();
176
194
 
177
- if (init && "owner" in options) {
178
- this[InitValues] = { init, owner: options.owner } as InitValuesFor<this>;
195
+ if ("owner" in options) {
196
+ this[InitValues] = {
197
+ init: options.init,
198
+ owner: options.owner,
199
+ } as InitValuesFor<this>;
179
200
  } else if ("fromRaw" in options) {
180
201
  Object.defineProperties(this, {
181
202
  id: {
@@ -191,14 +212,25 @@ export class CoMap<Fields extends ValidFields<Fields> = DefaultFields>
191
212
  return new Proxy(this, CoMapProxyHandler as ProxyHandler<this>);
192
213
  }
193
214
 
215
+ /** @category Creation */
216
+ static create<M extends CoMap>(
217
+ this: ClassOf<M>,
218
+ init: Simplify<CoMapInit<M>>,
219
+ options: { owner: Account | Group },
220
+ ) {
221
+ return new this({ init, owner: options.owner });
222
+ }
223
+
194
224
  toJSON() {
195
225
  const jsonedFields = this._raw.keys().map((key) => {
196
- const tKey = key as OwnKeys<Fields>;
197
- const descriptor = this._encoding[tKey] as Encoding;
226
+ const tKey = key as CoKeys<this>;
227
+ const descriptor = (this._schema[tKey] ||
228
+ this._schema[ItemsSym]) as Schema;
198
229
 
199
230
  if (descriptor == "json" || "encode" in descriptor) {
200
231
  return [key, this._raw.get(key)];
201
- } else if ("ref" in descriptor) {
232
+ } else if (isRefEncoded(descriptor)) {
233
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
202
234
  const jsonedRef = (this as any)[tKey]?.toJSON();
203
235
  return [key, jsonedRef];
204
236
  } else {
@@ -217,9 +249,11 @@ export class CoMap<Fields extends ValidFields<Fields> = DefaultFields>
217
249
  return this.toJSON();
218
250
  }
219
251
 
252
+ /** @internal */
253
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
220
254
  rawFromInit<Fields extends object = Record<string, any>>(
221
255
  init: Simplify<CoMapInit<Fields>> | undefined,
222
- owner: Account | Group
256
+ owner: Account | Group,
223
257
  ) {
224
258
  const rawOwner = owner._raw;
225
259
 
@@ -231,51 +265,63 @@ export class CoMap<Fields extends ValidFields<Fields> = DefaultFields>
231
265
  for (const key of Object.keys(init) as (keyof Fields)[]) {
232
266
  const initValue = init[key as keyof typeof init];
233
267
 
234
- const descriptor = (this._encoding[
235
- key as keyof typeof this._encoding
236
- ] || this._encoding[ItemsSym]) as Encoding;
268
+ const descriptor = (this._schema[
269
+ key as keyof typeof this._schema
270
+ ] || this._schema[ItemsSym]) as Schema;
237
271
 
238
272
  if (descriptor === "json") {
239
273
  rawInit[key] = initValue as JsonValue;
240
- } else if ("ref" in descriptor) {
274
+ } else if (isRefEncoded(descriptor)) {
241
275
  if (initValue) {
242
276
  rawInit[key] = (initValue as unknown as CoValue).id;
243
277
  }
244
278
  } else if ("encoded" in descriptor) {
245
- rawInit[key] = Schema.encodeSync(descriptor.encoded)(
246
- initValue as any
279
+ rawInit[key] = encodeSync(descriptor.encoded)(
280
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
281
+ initValue as any,
247
282
  );
248
283
  }
249
284
  }
250
285
 
251
286
  return rawOwner.createMap(rawInit);
252
287
  }
288
+
289
+ /** @category Declaration */
290
+ static Record<Value>(value: IfCo<Value, Value>) {
291
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
292
+ class RecordLikeCoMap extends CoMap {
293
+ [ItemsSym] = value;
294
+ }
295
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
296
+ interface RecordLikeCoMap extends Record<string, Value> {}
297
+
298
+ return RecordLikeCoMap;
299
+ }
253
300
  }
254
301
 
255
- export type OwnKeys<Fields extends object> = Exclude<
256
- keyof Fields & string,
257
- keyof CoMap<Record<string, never>>
302
+ export type CoKeys<Map extends object> = Exclude<
303
+ keyof Map & string,
304
+ keyof CoMap
258
305
  >;
259
306
 
260
- export type CoMapInit<Fields extends object> = {
261
- [Key in OwnKeys<Fields> as undefined extends Fields[Key]
307
+ export type CoMapInit<Map extends object> = {
308
+ [Key in CoKeys<Map> as undefined extends Map[Key]
262
309
  ? never
263
- : null extends Fields[Key]
264
- ? never
265
- : IsVal<Fields[Key], Key>]: Fields[Key];
266
- } & { [Key in OwnKeys<Fields> as IsVal<Fields[Key], Key>]?: Fields[Key] };
310
+ : IfCo<Map[Key], Key>]: Map[Key];
311
+ } & { [Key in CoKeys<Map> as IfCo<Map[Key], Key>]?: Map[Key] };
267
312
 
268
313
  function tryInit(map: CoMap) {
269
314
  if (
270
315
  map[InitValues] &&
271
- (map._encoding[ItemsSym] ||
316
+ (map._schema[ItemsSym] ||
272
317
  Object.keys(map[InitValues].init).every(
273
- (key) => (map._encoding as any)[key]
318
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
319
+ (key) => (map._schema as any)[key],
274
320
  ))
275
321
  ) {
276
322
  const raw = map.rawFromInit(
277
323
  map[InitValues].init,
278
- map[InitValues].owner
324
+ map[InitValues].owner,
279
325
  );
280
326
  Object.defineProperties(map, {
281
327
  id: {
@@ -291,14 +337,13 @@ function tryInit(map: CoMap) {
291
337
  // TODO: cache handlers per descriptor for performance?
292
338
  const CoMapProxyHandler: ProxyHandler<CoMap> = {
293
339
  get(target, key, receiver) {
294
- if (key === "_encoding") {
340
+ if (key === "_schema") {
295
341
  return Reflect.get(target, key);
296
342
  } else if (key in target) {
297
343
  return Reflect.get(target, key, receiver);
298
344
  } else {
299
- const descriptor = (target._encoding[
300
- key as keyof CoMap["_encoding"]
301
- ] || target._encoding[ItemsSym]) as Encoding;
345
+ const descriptor = (target._schema[key as keyof CoMap["_schema"]] ||
346
+ target._schema[ItemsSym]) as Schema;
302
347
  if (descriptor && typeof key === "string") {
303
348
  const raw = target._raw.get(key);
304
349
 
@@ -307,15 +352,15 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
307
352
  } else if ("encoded" in descriptor) {
308
353
  return raw === undefined
309
354
  ? undefined
310
- : Schema.decodeSync(descriptor.encoded)(raw);
311
- } else if ("ref" in descriptor) {
355
+ : decodeSync(descriptor.encoded)(raw);
356
+ } else if (isRefEncoded(descriptor)) {
312
357
  return raw === undefined
313
358
  ? undefined
314
359
  : new Ref(
315
360
  raw as unknown as ID<CoValue>,
316
361
  target._loadedAs,
317
- descriptor
318
- ).accessFrom(receiver);
362
+ descriptor,
363
+ ).accessFrom(receiver, key);
319
364
  }
320
365
  } else {
321
366
  return undefined;
@@ -328,26 +373,25 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
328
373
  typeof value === "object" &&
329
374
  SchemaInit in value
330
375
  ) {
331
- (target.constructor as typeof CoMap)._encoding ||= {};
332
- (target.constructor as typeof CoMap)._encoding[key] =
376
+ (target.constructor as typeof CoMap)._schema ||= {};
377
+ (target.constructor as typeof CoMap)._schema[key] =
333
378
  value[SchemaInit];
334
379
  tryInit(target);
335
380
  return true;
336
381
  }
337
382
 
338
- const descriptor = (target._encoding[key as keyof CoMap["_encoding"]] ||
339
- target._encoding[ItemsSym]) as Encoding;
383
+ const descriptor = (target._schema[key as keyof CoMap["_schema"]] ||
384
+ target._schema[ItemsSym]) as Schema;
340
385
  if (descriptor && typeof key === "string") {
341
386
  if (descriptor === "json") {
342
387
  target._raw.set(key, value);
343
388
  } else if ("encoded" in descriptor) {
344
- target._raw.set(
345
- key,
346
- Schema.encodeSync(descriptor.encoded)(value)
347
- );
348
- } else if ("ref" in descriptor) {
389
+ target._raw.set(key, encodeSync(descriptor.encoded)(value));
390
+ } else if (isRefEncoded(descriptor)) {
349
391
  target._raw.set(key, value.id);
350
- subscriptionsScopes.get(target)?.onRefAccessedOrSet(value.id);
392
+ subscriptionsScopes
393
+ .get(target)
394
+ ?.onRefAccessedOrSet(target.id, value.id);
351
395
  }
352
396
  return true;
353
397
  } else {
@@ -360,8 +404,8 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
360
404
  typeof attributes.value === "object" &&
361
405
  SchemaInit in attributes.value
362
406
  ) {
363
- (target.constructor as typeof CoMap)._encoding ||= {};
364
- (target.constructor as typeof CoMap)._encoding[key as string] =
407
+ (target.constructor as typeof CoMap)._schema ||= {};
408
+ (target.constructor as typeof CoMap)._schema[key as string] =
365
409
  attributes.value[SchemaInit];
366
410
  tryInit(target);
367
411
  return true;
@@ -371,11 +415,11 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
371
415
  },
372
416
  ownKeys(target) {
373
417
  const keys = Reflect.ownKeys(target).filter((k) => k !== ItemsSym);
374
- for (const key of Reflect.ownKeys(target._encoding)) {
375
- if (key !== ItemsSym && !keys.includes(key)) {
376
- keys.push(key);
377
- }
378
- }
418
+ // for (const key of Reflect.ownKeys(target._schema)) {
419
+ // if (key !== ItemsSym && !keys.includes(key)) {
420
+ // keys.push(key);
421
+ // }
422
+ // }
379
423
  for (const key of target._raw.keys()) {
380
424
  if (!keys.includes(key)) {
381
425
  keys.push(key);
@@ -388,9 +432,8 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
388
432
  if (key in target) {
389
433
  return Reflect.getOwnPropertyDescriptor(target, key);
390
434
  } else {
391
- const descriptor = (target._encoding[
392
- key as keyof CoMap["_encoding"]
393
- ] || target._encoding[ItemsSym]) as Encoding;
435
+ const descriptor = (target._schema[key as keyof CoMap["_schema"]] ||
436
+ target._schema[ItemsSym]) as Schema;
394
437
  if (descriptor || key in target._raw.ops) {
395
438
  return {
396
439
  enumerable: true,
@@ -400,4 +443,14 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
400
443
  }
401
444
  }
402
445
  },
446
+ deleteProperty(target, key) {
447
+ const descriptor = (target._schema[key as keyof CoMap["_schema"]] ||
448
+ target._schema[ItemsSym]) as Schema;
449
+ if (typeof key === "string" && descriptor) {
450
+ target._raw.delete(key);
451
+ return true;
452
+ } else {
453
+ return Reflect.deleteProperty(target, key);
454
+ }
455
+ },
403
456
  };