jazz-tools 0.7.3 → 0.7.8
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/.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";
         |