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.
- package/.eslintrc.cjs +3 -10
- package/.prettierrc.js +9 -0
- package/.turbo/turbo-build.log +3 -19
- package/.turbo/turbo-lint.log +4 -0
- package/.turbo/turbo-test.log +140 -0
- package/CHANGELOG.md +304 -0
- package/README.md +10 -2
- package/dist/coValues/account.js +59 -41
- package/dist/coValues/account.js.map +1 -1
- package/dist/coValues/coList.js +49 -46
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.js +143 -44
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coStream.js +144 -35
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/coValues/deepLoading.js +60 -0
- package/dist/coValues/deepLoading.js.map +1 -0
- package/dist/coValues/extensions/imageDef.js +10 -7
- package/dist/coValues/extensions/imageDef.js.map +1 -1
- package/dist/coValues/group.js +49 -13
- package/dist/coValues/group.js.map +1 -1
- package/dist/coValues/interfaces.js +70 -31
- package/dist/coValues/interfaces.js.map +1 -1
- package/dist/implementation/devtoolsFormatters.js +114 -0
- package/dist/implementation/devtoolsFormatters.js.map +1 -0
- package/dist/implementation/refs.js +58 -18
- package/dist/implementation/refs.js.map +1 -1
- package/dist/implementation/schema.js +58 -0
- package/dist/implementation/schema.js.map +1 -0
- package/dist/implementation/subscriptionScope.js +19 -1
- package/dist/implementation/subscriptionScope.js.map +1 -1
- package/dist/implementation/symbols.js +5 -0
- package/dist/implementation/symbols.js.map +1 -0
- package/dist/index.js +3 -5
- package/dist/index.js.map +1 -1
- package/dist/internal.js +5 -2
- package/dist/internal.js.map +1 -1
- package/dist/tests/coList.test.js +51 -48
- package/dist/tests/coList.test.js.map +1 -1
- package/dist/tests/coMap.test.js +131 -73
- package/dist/tests/coMap.test.js.map +1 -1
- package/dist/tests/coStream.test.js +56 -41
- package/dist/tests/coStream.test.js.map +1 -1
- package/dist/tests/deepLoading.test.js +188 -0
- package/dist/tests/deepLoading.test.js.map +1 -0
- package/dist/tests/groupsAndAccounts.test.js +83 -0
- package/dist/tests/groupsAndAccounts.test.js.map +1 -0
- package/package.json +17 -9
- package/src/coValues/account.ts +113 -125
- package/src/coValues/coList.ts +87 -103
- package/src/coValues/coMap.ts +200 -147
- package/src/coValues/coStream.ts +264 -80
- package/src/coValues/deepLoading.ts +229 -0
- package/src/coValues/extensions/imageDef.ts +17 -13
- package/src/coValues/group.ts +92 -58
- package/src/coValues/interfaces.ts +215 -115
- package/src/implementation/devtoolsFormatters.ts +110 -0
- package/src/implementation/inspect.ts +1 -1
- package/src/implementation/refs.ts +80 -28
- package/src/implementation/schema.ts +138 -0
- package/src/implementation/subscriptionScope.ts +48 -12
- package/src/implementation/symbols.ts +11 -0
- package/src/index.ts +12 -8
- package/src/internal.ts +7 -3
- package/src/tests/coList.test.ts +77 -62
- package/src/tests/coMap.test.ts +201 -113
- package/src/tests/coStream.test.ts +113 -84
- package/src/tests/deepLoading.test.ts +301 -0
- package/src/tests/groupsAndAccounts.test.ts +91 -0
- package/dist/implementation/encoding.js +0 -26
- package/dist/implementation/encoding.js.map +0 -1
- package/src/implementation/encoding.ts +0 -105
package/src/coValues/coMap.ts
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
import type { JsonValue, RawCoMap } from "cojson";
|
2
2
|
import type { Simplify } from "effect/Types";
|
3
|
-
import {
|
3
|
+
import { encodeSync, decodeSync } from "@effect/schema/Schema";
|
4
4
|
import type {
|
5
5
|
CoValue,
|
6
|
-
|
7
|
-
EncodingFor,
|
6
|
+
Schema,
|
8
7
|
Group,
|
9
8
|
ID,
|
10
9
|
RefEncoded,
|
11
|
-
|
12
|
-
|
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?:
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
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
|
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<
|
109
|
+
return makeRefs<CoKeys<this>>(
|
103
110
|
(key) => this._raw.get(key as string) as unknown as ID<CoValue>,
|
104
|
-
() =>
|
105
|
-
|
106
|
-
const schema =
|
107
|
-
key as keyof typeof this.
|
108
|
-
|
109
|
-
schema !== "json" &&
|
110
|
-
}) as
|
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) =>
|
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.
|
123
|
-
key as keyof typeof target.
|
124
|
-
] as
|
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
|
-
?
|
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(
|
149
|
+
descriptor,
|
150
|
+
).accessFrom(
|
151
|
+
target,
|
152
|
+
"_edits." + key.toString() + ".value",
|
153
|
+
),
|
139
154
|
ref:
|
140
|
-
descriptor !== "json" &&
|
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:
|
151
|
-
|
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
|
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
|
-
|
184
|
+
/** @internal */
|
185
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
186
|
+
[InitValues]?: any;
|
165
187
|
|
166
|
-
|
188
|
+
/** @internal */
|
167
189
|
constructor(
|
168
|
-
|
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 (
|
178
|
-
this[InitValues] = {
|
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
|
197
|
-
const descriptor = this.
|
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 (
|
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.
|
235
|
-
key as keyof typeof this.
|
236
|
-
] || this.
|
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 (
|
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] =
|
246
|
-
|
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
|
256
|
-
keyof
|
257
|
-
keyof CoMap
|
302
|
+
export type CoKeys<Map extends object> = Exclude<
|
303
|
+
keyof Map & string,
|
304
|
+
keyof CoMap
|
258
305
|
>;
|
259
306
|
|
260
|
-
export type CoMapInit<
|
261
|
-
[Key in
|
307
|
+
export type CoMapInit<Map extends object> = {
|
308
|
+
[Key in CoKeys<Map> as undefined extends Map[Key]
|
262
309
|
? never
|
263
|
-
:
|
264
|
-
|
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.
|
316
|
+
(map._schema[ItemsSym] ||
|
272
317
|
Object.keys(map[InitValues].init).every(
|
273
|
-
|
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 === "
|
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.
|
300
|
-
|
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
|
-
:
|
311
|
-
} else if (
|
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).
|
332
|
-
(target.constructor as typeof CoMap).
|
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.
|
339
|
-
target.
|
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
|
-
|
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
|
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).
|
364
|
-
(target.constructor as typeof CoMap).
|
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.
|
375
|
-
|
376
|
-
|
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.
|
392
|
-
|
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
|
};
|