jazz-tools 0.7.0-alpha.2 → 0.7.0-alpha.20

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