jazz-tools 0.7.3 → 0.7.8
Sign up to get free protection for your applications and to get access to all the features.
- package/.turbo/turbo-build.log +2 -17
- package/.turbo/turbo-test.log +32 -32
- package/CHANGELOG.md +12 -0
- package/dist/coValues/account.js +11 -1
- package/dist/coValues/account.js.map +1 -1
- package/dist/coValues/coList.js +168 -34
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.js +149 -48
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coStream.js +15 -28
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/coValues/group.js +1 -1
- package/dist/coValues/group.js.map +1 -1
- package/dist/coValues/interfaces.js.map +1 -1
- package/dist/implementation/symbols.js +0 -1
- package/dist/implementation/symbols.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/tests/coMap.test.js +11 -0
- package/dist/tests/coMap.test.js.map +1 -1
- package/package.json +1 -1
- package/src/coValues/account.ts +24 -1
- package/src/coValues/coList.ts +180 -48
- package/src/coValues/coMap.ts +152 -63
- package/src/coValues/coStream.ts +16 -34
- package/src/coValues/group.ts +1 -1
- package/src/coValues/interfaces.ts +1 -0
- package/src/implementation/symbols.ts +0 -3
- package/src/index.ts +1 -1
- package/src/tests/coMap.test.ts +16 -0
package/src/coValues/coMap.ts
CHANGED
@@ -24,7 +24,6 @@ import {
|
|
24
24
|
makeRefs,
|
25
25
|
subscriptionsScopes,
|
26
26
|
ItemsSym,
|
27
|
-
InitValues,
|
28
27
|
isRefEncoded,
|
29
28
|
loadCoValue,
|
30
29
|
loadCoValueEf,
|
@@ -42,17 +41,14 @@ type CoMapEdit<V> = {
|
|
42
41
|
madeAt: Date;
|
43
42
|
};
|
44
43
|
|
45
|
-
type InitValuesFor<C extends CoMap> = {
|
46
|
-
init: Simplify<CoMapInit<C>>;
|
47
|
-
owner: Account | Group;
|
48
|
-
};
|
49
|
-
|
50
44
|
/**
|
51
45
|
* CoMaps are collaborative versions of plain objects, mapping string-like keys to values.
|
52
46
|
*
|
53
47
|
* @categoryDescription Declaration
|
54
48
|
* Declare your own CoMap schemas by subclassing `CoMap` and assigning field schemas with `co`.
|
55
49
|
*
|
50
|
+
* Optional `co.ref(...)` fields must be marked with `{ optional: true }`.
|
51
|
+
*
|
56
52
|
* ```ts
|
57
53
|
* import { co, CoMap } from "jazz-tools";
|
58
54
|
*
|
@@ -60,6 +56,7 @@ type InitValuesFor<C extends CoMap> = {
|
|
60
56
|
* name = co.string;
|
61
57
|
* age = co.number;
|
62
58
|
* pet = co.ref(Animal);
|
59
|
+
* car = co.ref(Car, { optional: true });
|
63
60
|
* }
|
64
61
|
* ```
|
65
62
|
*
|
@@ -103,17 +100,19 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
103
100
|
/**
|
104
101
|
* If property `prop` is a `co.ref(...)`, you can use `coMaps._refs.prop` to access
|
105
102
|
* the `Ref` instead of the potentially loaded/null value.
|
103
|
+
*
|
106
104
|
* This allows you to always get the ID or load the value manually.
|
107
105
|
*
|
108
106
|
* @example
|
109
107
|
* ```ts
|
110
108
|
* person._refs.pet.id; // => ID<Animal>
|
111
109
|
* person._refs.pet.value;
|
112
|
-
* // => Animal |
|
110
|
+
* // => Animal | null
|
113
111
|
* const pet = await person._refs.pet.load();
|
114
112
|
* ```
|
115
113
|
*
|
116
|
-
* @category Content
|
114
|
+
* @category Content
|
115
|
+
**/
|
117
116
|
get _refs(): {
|
118
117
|
[Key in CoKeys<this>]: IfCo<this[Key], RefIfCoValue<this[Key]>>;
|
119
118
|
} {
|
@@ -196,44 +195,66 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
196
195
|
return Account.fromNode(this._raw.core.node);
|
197
196
|
}
|
198
197
|
|
199
|
-
/** @internal */
|
200
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
201
|
-
[InitValues]?: any;
|
202
|
-
|
203
198
|
/** @internal */
|
204
199
|
constructor(
|
205
200
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
206
|
-
options: { fromRaw: RawCoMap } |
|
201
|
+
options: { fromRaw: RawCoMap } | undefined
|
207
202
|
) {
|
208
203
|
super();
|
209
204
|
|
210
|
-
if (
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
});
|
223
|
-
} else {
|
224
|
-
throw new Error("Invalid CoMap constructor arguments");
|
205
|
+
if (options) {
|
206
|
+
if ("fromRaw" in options) {
|
207
|
+
Object.defineProperties(this, {
|
208
|
+
id: {
|
209
|
+
value: options.fromRaw.id as unknown as ID<this>,
|
210
|
+
enumerable: false,
|
211
|
+
},
|
212
|
+
_raw: { value: options.fromRaw, enumerable: false },
|
213
|
+
});
|
214
|
+
} else {
|
215
|
+
throw new Error("Invalid CoMap constructor arguments");
|
216
|
+
}
|
225
217
|
}
|
226
218
|
|
227
219
|
return new Proxy(this, CoMapProxyHandler as ProxyHandler<this>);
|
228
220
|
}
|
229
221
|
|
230
|
-
/**
|
222
|
+
/**
|
223
|
+
* Create a new CoMap with the given initial values and owner.
|
224
|
+
*
|
225
|
+
* The owner (a Group or Account) determines access rights to the CoMap.
|
226
|
+
*
|
227
|
+
* The CoMap will immediately be persisted and synced to connected peers.
|
228
|
+
*
|
229
|
+
* @example
|
230
|
+
* ```ts
|
231
|
+
* const person = Person.create({
|
232
|
+
* name: "Alice",
|
233
|
+
* age: 42,
|
234
|
+
* pet: cat,
|
235
|
+
* }, { owner: friendGroup });
|
236
|
+
* ```
|
237
|
+
*
|
238
|
+
* @category Creation
|
239
|
+
**/
|
231
240
|
static create<M extends CoMap>(
|
232
241
|
this: CoValueClass<M>,
|
233
242
|
init: Simplify<CoMapInit<M>>,
|
234
243
|
options: { owner: Account | Group },
|
235
244
|
) {
|
236
|
-
|
245
|
+
const instance = new this();
|
246
|
+
const raw = instance.rawFromInit(
|
247
|
+
init,
|
248
|
+
options.owner,
|
249
|
+
);
|
250
|
+
Object.defineProperties(instance, {
|
251
|
+
id: {
|
252
|
+
value: raw.id,
|
253
|
+
enumerable: false,
|
254
|
+
},
|
255
|
+
_raw: { value: raw, enumerable: false },
|
256
|
+
});
|
257
|
+
return instance;
|
237
258
|
}
|
238
259
|
|
239
260
|
toJSON() {
|
@@ -284,6 +305,10 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
284
305
|
key as keyof typeof this._schema
|
285
306
|
] || this._schema[ItemsSym]) as Schema;
|
286
307
|
|
308
|
+
if (!descriptor) {
|
309
|
+
continue;
|
310
|
+
}
|
311
|
+
|
287
312
|
if (descriptor === "json") {
|
288
313
|
rawInit[key] = initValue as JsonValue;
|
289
314
|
} else if (isRefEncoded(descriptor)) {
|
@@ -301,7 +326,24 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
301
326
|
return rawOwner.createMap(rawInit);
|
302
327
|
}
|
303
328
|
|
304
|
-
/**
|
329
|
+
/**
|
330
|
+
* Declare a Record-like CoMap schema, by extending `CoMap.Record(...)` and passing the value schema using `co`. Keys are always `string`.
|
331
|
+
*
|
332
|
+
* @example
|
333
|
+
* ```ts
|
334
|
+
* import { co, CoMap } from "jazz-tools";
|
335
|
+
*
|
336
|
+
* class ColorToFruitMap extends CoMap.Record(
|
337
|
+
* co.ref(Fruit)
|
338
|
+
* ) {}
|
339
|
+
*
|
340
|
+
* // assume we have map: ColorToFruitMap
|
341
|
+
* // and strawberry: Fruit
|
342
|
+
* map["red"] = strawberry;
|
343
|
+
* ```
|
344
|
+
*
|
345
|
+
* @category Declaration
|
346
|
+
*/
|
305
347
|
static Record<Value>(value: IfCo<Value, Value>) {
|
306
348
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
307
349
|
class RecordLikeCoMap extends CoMap {
|
@@ -313,7 +355,27 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
313
355
|
return RecordLikeCoMap;
|
314
356
|
}
|
315
357
|
|
316
|
-
/**
|
358
|
+
/**
|
359
|
+
* Load a `CoMap` with a given ID, as a given account.
|
360
|
+
*
|
361
|
+
* `depth` specifies which (if any) fields that reference other CoValues to load as well before resolving.
|
362
|
+
* The `DeeplyLoaded` return type guarantees that corresponding referenced CoValues are loaded to the specified depth.
|
363
|
+
*
|
364
|
+
* You can pass `[]` or `{}` for shallowly loading only this CoMap, or `{ fieldA: depthA, fieldB: depthB }` for recursively loading referenced CoValues.
|
365
|
+
*
|
366
|
+
* Check out the `load` methods on `CoMap`/`CoList`/`CoStream`/`Group`/`Account` to see which depth structures are valid to nest.
|
367
|
+
*
|
368
|
+
* @example
|
369
|
+
* ```ts
|
370
|
+
* const person = await Person.load(
|
371
|
+
* "co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
|
372
|
+
* me,
|
373
|
+
* { pet: {} }
|
374
|
+
* );
|
375
|
+
* ```
|
376
|
+
*
|
377
|
+
* @category Subscription & Loading
|
378
|
+
*/
|
317
379
|
static load<M extends CoMap, Depth>(
|
318
380
|
this: CoValueClass<M>,
|
319
381
|
id: ID<M>,
|
@@ -323,7 +385,13 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
323
385
|
return loadCoValue(this, id, as, depth);
|
324
386
|
}
|
325
387
|
|
326
|
-
/**
|
388
|
+
/**
|
389
|
+
* Effectful version of `CoMap.load()`.
|
390
|
+
*
|
391
|
+
* Needs to be run inside an `AccountCtx` context.
|
392
|
+
*
|
393
|
+
* @category Subscription & Loading
|
394
|
+
*/
|
327
395
|
static loadEf<M extends CoMap, Depth>(
|
328
396
|
this: CoValueClass<M>,
|
329
397
|
id: ID<M>,
|
@@ -332,7 +400,34 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
332
400
|
return loadCoValueEf<M, Depth>(this, id, depth);
|
333
401
|
}
|
334
402
|
|
335
|
-
/**
|
403
|
+
/**
|
404
|
+
* Load and subscribe to a `CoMap` with a given ID, as a given account.
|
405
|
+
*
|
406
|
+
* Automatically also subscribes to updates to all referenced/nested CoValues as soon as they are accessed in the listener.
|
407
|
+
*
|
408
|
+
* `depth` specifies which (if any) fields that reference other CoValues to load as well before calling `listener` for the first time.
|
409
|
+
* The `DeeplyLoaded` return type guarantees that corresponding referenced CoValues are loaded to the specified depth.
|
410
|
+
*
|
411
|
+
* You can pass `[]` or `{}` for shallowly loading only this CoMap, or `{ fieldA: depthA, fieldB: depthB }` for recursively loading referenced CoValues.
|
412
|
+
*
|
413
|
+
* Check out the `load` methods on `CoMap`/`CoList`/`CoStream`/`Group`/`Account` to see which depth structures are valid to nest.
|
414
|
+
*
|
415
|
+
* Returns an unsubscribe function that you should call when you no longer need updates.
|
416
|
+
*
|
417
|
+
* Also see the `useCoState` hook to reactively subscribe to a CoValue in a React component.
|
418
|
+
*
|
419
|
+
* @example
|
420
|
+
* ```ts
|
421
|
+
* const unsub = Person.subscribe(
|
422
|
+
* "co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
|
423
|
+
* me,
|
424
|
+
* { pet: {} },
|
425
|
+
* (person) => console.log(person)
|
426
|
+
* );
|
427
|
+
* ```
|
428
|
+
*
|
429
|
+
* @category Subscription & Loading
|
430
|
+
*/
|
336
431
|
static subscribe<M extends CoMap, Depth>(
|
337
432
|
this: CoValueClass<M>,
|
338
433
|
id: ID<M>,
|
@@ -343,7 +438,13 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
343
438
|
return subscribeToCoValue<M, Depth>(this, id, as, depth, listener);
|
344
439
|
}
|
345
440
|
|
346
|
-
/**
|
441
|
+
/**
|
442
|
+
* Effectful version of `CoMap.subscribe()` that returns a stream of updates.
|
443
|
+
*
|
444
|
+
* Needs to be run inside an `AccountCtx` context.
|
445
|
+
*
|
446
|
+
* @category Subscription & Loading
|
447
|
+
*/
|
347
448
|
static subscribeEf<M extends CoMap, Depth>(
|
348
449
|
this: CoValueClass<M>,
|
349
450
|
id: ID<M>,
|
@@ -352,7 +453,13 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
352
453
|
return subscribeToCoValueEf<M, Depth>(this, id, depth);
|
353
454
|
}
|
354
455
|
|
355
|
-
/**
|
456
|
+
/**
|
457
|
+
* Given an already loaded `CoMap`, ensure that the specified fields are loaded to the specified depth.
|
458
|
+
*
|
459
|
+
* Works like `CoMap.load()`, but you don't need to pass the ID or the account to load as again.
|
460
|
+
*
|
461
|
+
* @category Subscription & Loading
|
462
|
+
*/
|
356
463
|
ensureLoaded<M extends CoMap, Depth>(
|
357
464
|
this: M,
|
358
465
|
depth: Depth & DepthsIn<M>,
|
@@ -360,7 +467,15 @@ export class CoMap extends CoValueBase implements CoValue {
|
|
360
467
|
return ensureCoValueLoaded(this, depth);
|
361
468
|
}
|
362
469
|
|
363
|
-
/**
|
470
|
+
/**
|
471
|
+
* Given an already loaded `CoMap`, subscribe to updates to the `CoMap` and ensure that the specified fields are loaded to the specified depth.
|
472
|
+
*
|
473
|
+
* Works like `CoMap.subscribe()`, but you don't need to pass the ID or the account to load as again.
|
474
|
+
*
|
475
|
+
* Returns an unsubscribe function that you should call when you no longer need updates.
|
476
|
+
*
|
477
|
+
* @category Subscription & Loading
|
478
|
+
**/
|
364
479
|
subscribe<M extends CoMap, Depth>(
|
365
480
|
this: M,
|
366
481
|
depth: Depth & DepthsIn<M>,
|
@@ -381,30 +496,6 @@ export type CoMapInit<Map extends object> = {
|
|
381
496
|
: IfCo<Map[Key], Key>]: Map[Key];
|
382
497
|
} & { [Key in CoKeys<Map> as IfCo<Map[Key], Key>]?: Map[Key] };
|
383
498
|
|
384
|
-
function tryInit(map: CoMap) {
|
385
|
-
if (
|
386
|
-
map[InitValues] &&
|
387
|
-
(map._schema[ItemsSym] ||
|
388
|
-
Object.keys(map[InitValues].init).every(
|
389
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
390
|
-
(key) => (map._schema as any)[key],
|
391
|
-
))
|
392
|
-
) {
|
393
|
-
const raw = map.rawFromInit(
|
394
|
-
map[InitValues].init,
|
395
|
-
map[InitValues].owner,
|
396
|
-
);
|
397
|
-
Object.defineProperties(map, {
|
398
|
-
id: {
|
399
|
-
value: raw.id,
|
400
|
-
enumerable: false,
|
401
|
-
},
|
402
|
-
_raw: { value: raw, enumerable: false },
|
403
|
-
});
|
404
|
-
delete map[InitValues];
|
405
|
-
}
|
406
|
-
}
|
407
|
-
|
408
499
|
// TODO: cache handlers per descriptor for performance?
|
409
500
|
const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
410
501
|
get(target, key, receiver) {
|
@@ -447,7 +538,6 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
447
538
|
(target.constructor as typeof CoMap)._schema ||= {};
|
448
539
|
(target.constructor as typeof CoMap)._schema[key] =
|
449
540
|
value[SchemaInit];
|
450
|
-
tryInit(target);
|
451
541
|
return true;
|
452
542
|
}
|
453
543
|
|
@@ -478,7 +568,6 @@ const CoMapProxyHandler: ProxyHandler<CoMap> = {
|
|
478
568
|
(target.constructor as typeof CoMap)._schema ||= {};
|
479
569
|
(target.constructor as typeof CoMap)._schema[key as string] =
|
480
570
|
attributes.value[SchemaInit];
|
481
|
-
tryInit(target);
|
482
571
|
return true;
|
483
572
|
} else {
|
484
573
|
return Reflect.defineProperty(target, key, attributes);
|
package/src/coValues/coStream.ts
CHANGED
@@ -30,7 +30,6 @@ import {
|
|
30
30
|
Ref,
|
31
31
|
inspect,
|
32
32
|
co,
|
33
|
-
InitValues,
|
34
33
|
SchemaInit,
|
35
34
|
isRefEncoded,
|
36
35
|
loadCoValue,
|
@@ -93,9 +92,6 @@ export class CoStream<Item = any> extends CoValueBase implements CoValue {
|
|
93
92
|
return this.perSession[this._loadedAs.sessionID!];
|
94
93
|
}
|
95
94
|
|
96
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
97
|
-
[InitValues]?: any;
|
98
|
-
|
99
95
|
constructor(
|
100
96
|
options:
|
101
97
|
| { init: Item[]; owner: Account | Group }
|
@@ -103,7 +99,7 @@ export class CoStream<Item = any> extends CoValueBase implements CoValue {
|
|
103
99
|
) {
|
104
100
|
super();
|
105
101
|
|
106
|
-
if ("fromRaw" in options) {
|
102
|
+
if (options && "fromRaw" in options) {
|
107
103
|
Object.defineProperties(this, {
|
108
104
|
id: {
|
109
105
|
value: options.fromRaw.id,
|
@@ -111,11 +107,6 @@ export class CoStream<Item = any> extends CoValueBase implements CoValue {
|
|
111
107
|
},
|
112
108
|
_raw: { value: options.fromRaw, enumerable: false },
|
113
109
|
});
|
114
|
-
} else {
|
115
|
-
this[InitValues] = {
|
116
|
-
init: options.init,
|
117
|
-
owner: options.owner,
|
118
|
-
};
|
119
110
|
}
|
120
111
|
|
121
112
|
return new Proxy(this, CoStreamProxyHandler as ProxyHandler<this>);
|
@@ -126,7 +117,21 @@ export class CoStream<Item = any> extends CoValueBase implements CoValue {
|
|
126
117
|
init: S extends CoStream<infer Item> ? UnCo<Item>[] : never,
|
127
118
|
options: { owner: Account | Group },
|
128
119
|
) {
|
129
|
-
|
120
|
+
const instance = new this({ init, owner: options.owner });
|
121
|
+
const raw = options.owner._raw.createStream();
|
122
|
+
|
123
|
+
Object.defineProperties(instance, {
|
124
|
+
id: {
|
125
|
+
value: raw.id,
|
126
|
+
enumerable: false,
|
127
|
+
},
|
128
|
+
_raw: { value: raw, enumerable: false },
|
129
|
+
});
|
130
|
+
|
131
|
+
if (init) {
|
132
|
+
instance.push(...init);
|
133
|
+
}
|
134
|
+
return instance;
|
130
135
|
}
|
131
136
|
|
132
137
|
push(...items: Item[]) {
|
@@ -317,27 +322,6 @@ function entryFromRawEntry<Item>(
|
|
317
322
|
};
|
318
323
|
}
|
319
324
|
|
320
|
-
function init(stream: CoStream) {
|
321
|
-
const init = stream[InitValues];
|
322
|
-
if (!init) return;
|
323
|
-
|
324
|
-
const raw = init.owner._raw.createStream();
|
325
|
-
|
326
|
-
Object.defineProperties(stream, {
|
327
|
-
id: {
|
328
|
-
value: raw.id,
|
329
|
-
enumerable: false,
|
330
|
-
},
|
331
|
-
_raw: { value: raw, enumerable: false },
|
332
|
-
});
|
333
|
-
|
334
|
-
if (init.init) {
|
335
|
-
stream.push(...init.init);
|
336
|
-
}
|
337
|
-
|
338
|
-
delete stream[InitValues];
|
339
|
-
}
|
340
|
-
|
341
325
|
export const CoStreamProxyHandler: ProxyHandler<CoStream> = {
|
342
326
|
get(target, key, receiver) {
|
343
327
|
if (typeof key === "string" && key.startsWith("co_")) {
|
@@ -391,7 +375,6 @@ export const CoStreamProxyHandler: ProxyHandler<CoStream> = {
|
|
391
375
|
(target.constructor as typeof CoStream)._schema ||= {};
|
392
376
|
(target.constructor as typeof CoStream)._schema[ItemsSym] =
|
393
377
|
value[SchemaInit];
|
394
|
-
init(target);
|
395
378
|
return true;
|
396
379
|
} else {
|
397
380
|
return Reflect.set(target, key, value, receiver);
|
@@ -407,7 +390,6 @@ export const CoStreamProxyHandler: ProxyHandler<CoStream> = {
|
|
407
390
|
(target.constructor as typeof CoStream)._schema ||= {};
|
408
391
|
(target.constructor as typeof CoStream)._schema[ItemsSym] =
|
409
392
|
descriptor.value[SchemaInit];
|
410
|
-
init(target);
|
411
393
|
return true;
|
412
394
|
} else {
|
413
395
|
return Reflect.defineProperty(target, key, descriptor);
|
package/src/coValues/group.ts
CHANGED
@@ -114,7 +114,7 @@ export class Group extends CoValueBase implements CoValue {
|
|
114
114
|
const initOwner = options.owner;
|
115
115
|
if (!initOwner) throw new Error("No owner provided");
|
116
116
|
if (
|
117
|
-
initOwner
|
117
|
+
initOwner._type === "Account" &&
|
118
118
|
isControlledAccount(initOwner)
|
119
119
|
) {
|
120
120
|
const rawOwner = initOwner._raw;
|
@@ -1,9 +1,6 @@
|
|
1
1
|
export const SchemaInit = Symbol.for("SchemaInit");
|
2
2
|
export type SchemaInit = typeof SchemaInit;
|
3
3
|
|
4
|
-
export const InitValues = Symbol.for("InitValues");
|
5
|
-
export type InitValues = typeof InitValues;
|
6
|
-
|
7
4
|
export const ItemsSym = Symbol.for("items");
|
8
5
|
export type ItemsSym = typeof ItemsSym;
|
9
6
|
|
package/src/index.ts
CHANGED
@@ -17,7 +17,7 @@ export type { ID, CoValue } from "./internal.js";
|
|
17
17
|
|
18
18
|
export { Encoders, co } from "./internal.js";
|
19
19
|
|
20
|
-
export { CoMap } from "./internal.js";
|
20
|
+
export { CoMap, type CoMapInit } from "./internal.js";
|
21
21
|
export { CoList } from "./internal.js";
|
22
22
|
export { CoStream, BinaryCoStream } from "./internal.js";
|
23
23
|
export { Group, Profile } from "./internal.js";
|
package/src/tests/coMap.test.ts
CHANGED
@@ -52,6 +52,22 @@ describe("Simple CoMap operations", async () => {
|
|
52
52
|
expect(Object.keys(map)).toEqual(["color", "_height", "birthday"]);
|
53
53
|
});
|
54
54
|
|
55
|
+
test("Construction with too many things provided", () => {
|
56
|
+
const mapWithExtra = TestMap.create(
|
57
|
+
{
|
58
|
+
color: "red",
|
59
|
+
_height: 10,
|
60
|
+
birthday: birthday,
|
61
|
+
name: "Hermes",
|
62
|
+
extra: "extra",
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
64
|
+
} as any,
|
65
|
+
{ owner: me },
|
66
|
+
);
|
67
|
+
|
68
|
+
expect(mapWithExtra.color).toEqual("red");
|
69
|
+
})
|
70
|
+
|
55
71
|
describe("Mutation", () => {
|
56
72
|
test("assignment & deletion", () => {
|
57
73
|
map.color = "blue";
|