import * as Schema from 'effect/Schema';
import { EntityNotFoundError } from './entity.js';
/**
 * Update an existing entity model of given type in the repo.
 */
export const update = (handle, type) => {
  const validate = Schema.validateSync(Schema.partial(type.update));
  const encode = Schema.encodeSync(type.update);
  const decode = Schema.decodeUnknownSync(type.update);
  // TODO: what's the right way to get the name of the type?
  // @ts-expect-error name is defined
  const typeName = type.name;
  return (id, data) => {
    validate(data);
    // apply changes to the repo -> updates the existing entity to the repo entities document
    let updated;
    handle.change(doc => {
      if (doc.entities === undefined) {
        return;
      }
      // TODO: Fetch the pre-decoded value from the local cache.
      const entity = doc.entities[id] ?? undefined;
      if (entity === undefined || typeof entity !== 'object') {
        return;
      }
      // TODO: Try to get a diff of the entity properties and only override the changed ones.
      updated = {
        ...decode(entity),
        ...data
      };
      const encoded = {
        ...encode(updated),
        '@@types@@': [typeName],
        __deleted: entity.__deleted ?? false,
        __version: entity.__version ?? ''
      };
      // filter out undefined values otherwise Automerge will throw an error
      for (const key in updated) {
        if (updated[key] === undefined) {
          delete encoded[key];
        }
      }
      doc.entities[id] = encoded;
    });
    if (updated === undefined) {
      throw new EntityNotFoundError({
        id,
        type
      });
    }
    return {
      id,
      type: typeName,
      ...updated,
      // injecting the schema to the entity to be able to access it in the preparePublish function
      __schema: type
    };
  };
};
//# sourceMappingURL=update.js.map