{
  "version": 3,
  "sources": ["../../../src/Type.ts"],
  "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Schema from 'effect/Schema';\nimport type * as Types from 'effect/Types';\n\nimport { raise } from '@dxos/debug';\nimport { type EncodedReference } from '@dxos/echo-protocol';\nimport { assertArgument, invariant } from '@dxos/invariant';\nimport { DXN, EID, type EntityId, type URI } from '@dxos/keys';\n\nimport type * as Database from './Database';\nimport type * as EntityModule from './Entity';\nimport * as internal from './internal';\nimport * as typeInternal from './internal/Type';\nimport type * as RelationModule from './Relation';\n\n//\n// Internal types (not exported)\n//\n\n/**\n * Structural base shared by the three sibling type-entity interfaces\n * ({@link Obj}, {@link Relation}, {@link Type}). NOT exported — callers\n * should constrain on {@link AnyEntity} when they want \"any of the three\"\n * and on the specific kind interface otherwise.\n */\ninterface BaseTypeEntity<A> {\n  /**\n   * Entity-kind brand of the type-entity value itself — always `EntityKind.Type`.\n   * The kind of instance the type *describes* lives on `[SchemaKindId]`\n   * (Object / Relation / Type). Lets `Obj.isObject` / `Relation.isRelation`\n   * reject type entities by a single `[KindId]` check.\n   */\n  readonly [internal.KindId]: internal.EntityKind.Type;\n\n  /**\n   * Object id. Like all ECHO entities, type entities always carry an id —\n   * stamped at construction for in-memory (static) declarations and assigned by\n   * the database once persisted. The id does NOT determine the entity's URI:\n   * static types resolve to their typename DXN, persisted types to `echo:/<id>`\n   * (see `getTypeURIFromSpecifier`).\n   */\n  readonly id: EntityId;\n\n  readonly name?: string;\n  // NOTE: `typename` / `version` are intentionally NOT fields on any type-entity\n  // interface. Both static and persisted entities carry them in `EntityMeta`\n  // (`key` / `version`); read them via `Type.getTypename(self)` /\n  // `Type.getVersion(self)` — never as a direct property.\n  readonly jsonSchema: internal.JsonSchemaType;\n  readonly [InstancePhantomId]?: A;\n}\n\n//\n// Obj — `Type.Type` value for an ECHO object schema.\n//\n\n/**\n * TypeScript type for an ECHO object type — a `Type.Type<A>` entity.\n *\n * `T` is the instance type produced by `Obj.make(Foo, props)`. `Fields` is\n * retained as a structural hint (the runtime value still carries `.fields`),\n * but consumers should derive instance/encoded types via `Type.InstanceType`.\n *\n * **Not a `Schema.Schema`.** `Foo.ast` / `Schema.Schema.Type<typeof Foo>` /\n * `Schema.extend(Foo)` no longer typecheck — extract the Effect Schema via\n * `Type.getSchema(Foo)` first, or derive instance types via\n * `Type.InstanceType<typeof Foo>`.\n *\n * @example\n * ```ts\n * const Person = Schema.Struct({\n *   name: Schema.String,\n * }).pipe(Type.makeObject(DXN.make('com.example.type.person', '0.1.0')));\n *\n * type Person = Type.InstanceType<typeof Person>;\n * ```\n */\nexport interface Obj<T, Fields extends Schema.Struct.Fields = Schema.Struct.Fields> extends BaseTypeEntity<\n  T & EntityModule.OfKind<typeof EntityModule.Kind.Object>\n> {\n  /** Schema-kind brand (object). */\n  readonly [internal.SchemaKindId]: internal.EntityKind.Object;\n\n  /** Source Effect Schema — used internally by `Type.getSchema(self)`. */\n  readonly [internal.StaticTypeSchemaSlot]: Schema.Schema.AnyNoContext;\n\n  /**\n   * The fields defined in the original struct schema.\n   * Allows accessing field definitions for introspection.\n   */\n  readonly fields: Fields;\n}\n\n/**\n * Type that represents any ECHO object type — a `Type.Type` entity branded\n * with the object entity kind, i.e. what `Type.makeObject(dxn)` produces.\n */\nexport type AnyObj = Obj<unknown>;\n\n/**\n * Factory function to create an ECHO object type.\n *\n * Returns a `Type.Type` entity — a live, in-memory `TypeSchema` instance,\n * NOT a `Schema.Schema`. Use `Type.InstanceType<typeof Foo>` for the instance\n * type and `Type.getSchema(Foo)` to obtain the underlying Effect Schema.\n *\n * The entity's id defaults to `EntityId.deterministic(typename, version)` so\n * constructing a type never reaches `crypto.getRandomValues()` — required for\n * Cloudflare workerd, which forbids RNG calls in global (module-evaluation)\n * scope. Pass `{ id }` to override (e.g. with `EntityId.random()` from a\n * request handler).\n *\n * @example\n * ```ts\n * const Person = Schema.Struct({\n *   name: Schema.String,\n * }).pipe(Type.makeObject(DXN.make('com.example.type.person', '0.1.0')));\n * ```\n */\nexport const makeObject: {\n  (\n    dxn: DXN.DXN,\n    options?: { id?: EntityId },\n  ): <Self extends Schema.Schema.Any>(self: Self) => Obj<Schema.Schema.Type<Self>>;\n} = internal.EchoObjectSchema as any;\n\n//\n// Type — the ECHO entity that holds a schema and metadata.\n// Persisted via `db.addType()`; subscribed to via `Filter.type(Type.Type)`.\n//\n\n/**\n * ECHO meta-schema entity — stores `{ name?, typename, version, jsonSchema }`.\n * Type-kind sibling of `Type.makeObject(...)` / `Type.makeRelation(...)` outputs.\n * Stored types live under this entity; filter via `Filter.type(Type.Type)`.\n */\nexport const Type: Type<typeInternal.TypeSchema> = typeInternal.TypeSchema as any;\n\n/**\n * Default version stamped on draft (unnamed) types created via\n * {@link makeObjectFromJsonSchema} / {@link makeRelationFromJsonSchema} when\n * the caller does not supply one. Pure dynamic drafts surface as `'0.0.0'`\n * until they are persisted, at which point automerge-heads suffix the version.\n */\nconst DRAFT_VERSION = '0.0.0';\n\n/**\n * Common props shared by the type-kind factories. Typename and version are\n * optional — drafts omit typename and default version to {@link DRAFT_VERSION}.\n */\ntype MakeTypeProps = {\n  jsonSchema: internal.JsonSchemaType;\n  typename?: string;\n  version?: string;\n  name?: string;\n  id?: EntityId;\n};\n\n/**\n * Construct a new object-kind type entity from raw metadata — for cases where\n * an Effect Schema isn't available (e.g. JSON-Schema arriving over the network\n * or from a UI editor). Parallel to {@link makeObject} but takes pre-built\n * `jsonSchema` instead of piping through an Effect schema.\n *\n * The returned entity is in-memory; persist it with `db.addType(entity)`.\n */\nexport const makeObjectFromJsonSchema = (props: MakeTypeProps): Type<typeInternal.TypeSchema> => {\n  const { typename, version, ...data } = props;\n  // `typename` / `version` are routed through `EntityMeta` (`key` / `version`)\n  // — the canonical registry-provenance pair — not data fields. Drafts default\n  // to `'0.0.0'`; the version is omitted from meta entirely when the caller\n  // doesn't supply one so the proxy projection can apply its own default.\n  return internal.makeObject(\n    internal.getStaticTypeSchema(typeInternal.TypeSchema) as any,\n    data as any,\n    {\n      keys: [],\n      key: typename,\n      version: version ?? DRAFT_VERSION,\n    },\n    typeInternal.TypeSchema,\n  ) as unknown as Type<typeInternal.TypeSchema>;\n};\n\n/**\n * Construct a new relation-kind type entity from raw metadata. Parallel to\n * {@link makeRelation} but takes pre-built `jsonSchema` instead of piping\n * through an Effect schema. `source` / `target` accept either a static\n * `Type.Obj` entity or the well-known `Obj.Unknown` schema.\n *\n * The returned entity is in-memory; persist it with `db.addType(entity)`.\n */\nexport const makeRelationFromJsonSchema = (\n  props: MakeTypeProps & {\n    source: AnyObj | internal.UnknownTypeSchema<any, typeof EntityModule.Kind.Object>;\n    target: AnyObj | internal.UnknownTypeSchema<any, typeof EntityModule.Kind.Object>;\n  },\n): Type<typeInternal.TypeSchema> => {\n  const { source, target, jsonSchema, typename, version, ...rest } = props;\n  // Embed source/target DXNs + relation entity-kind into the jsonSchema so the\n  // entity round-trips correctly through `toEffectSchema` / queries / refs.\n  const sourceURI = internal.getTypeURIFromSpecifier(source);\n  const targetURI = internal.getTypeURIFromSpecifier(target);\n  const enrichedJsonSchema: internal.JsonSchemaType = {\n    ...jsonSchema,\n    entityKind: internal.EntityKind.Relation,\n    relationSource: { $ref: sourceURI },\n    relationTarget: { $ref: targetURI },\n  };\n  // `typename` / `version` route through `EntityMeta` (see\n  // {@link makeObjectFromJsonSchema}); drafts default version to `'0.0.0'`.\n  return internal.makeObject(\n    internal.getStaticTypeSchema(typeInternal.TypeSchema) as any,\n    { ...rest, jsonSchema: enrichedJsonSchema } as any,\n    {\n      keys: [],\n      key: typename,\n      version: version ?? DRAFT_VERSION,\n    },\n    typeInternal.TypeSchema,\n  ) as unknown as Type<typeInternal.TypeSchema>;\n};\n\n/**\n * TypeScript type for an ECHO relation type — a `Type.Type<A>` entity.\n *\n * `T` is the instance-property type produced by `Relation.make(...)` (excluding\n * source/target endpoints). `Source` and `Target` are the endpoint types.\n *\n * **Not a `Schema.Schema`.** See {@link Obj}'s note.\n */\nexport interface Relation<\n  T,\n  Source,\n  Target,\n  Fields extends Schema.Struct.Fields = Schema.Struct.Fields,\n> extends BaseTypeEntity<\n  RelationModule.Endpoints<Source, Target> & T & EntityModule.OfKind<typeof EntityModule.Kind.Relation>\n> {\n  /** Schema-kind brand (relation). */\n  readonly [internal.SchemaKindId]: internal.EntityKind.Relation;\n\n  /** Source Effect Schema — used internally by `Type.getSchema(self)`. */\n  readonly [internal.StaticTypeSchemaSlot]: Schema.Schema.AnyNoContext;\n\n  /**\n   * The fields defined in the original struct schema.\n   * Allows accessing field definitions for introspection.\n   */\n  readonly fields: Fields;\n}\n\n/**\n * Type that represents any ECHO relation type — a `Type.Type` entity branded\n * with the relation entity kind, i.e. what `Type.makeRelation(...)` produces.\n */\nexport type AnyRelation = Relation<unknown, unknown, unknown>;\n\n/**\n * Factory function to create an ECHO relation schema.\n * Adds relation metadata annotations to an Effect schema.\n *\n * @example\n * ```ts\n * const WorksFor = Schema.Struct({\n *   role: Schema.String,\n * }).pipe(Type.makeRelation({\n *   dxn: DXN.make('com.example.type.worksFor', '0.1.0'),\n *   source: Person,\n *   target: Company,\n * }));\n * ```\n */\nexport const makeRelation: {\n  <SourceInstance, TargetInstance>(opts: {\n    dxn: DXN.DXN;\n    source: Obj<SourceInstance, any> | internal.UnknownTypeSchema<SourceInstance, typeof EntityModule.Kind.Object>;\n    target: Obj<TargetInstance, any> | internal.UnknownTypeSchema<TargetInstance, typeof EntityModule.Kind.Object>;\n    /**\n     * Override the entity id. Defaults to `EntityId.deterministic(typename, version)`;\n     * see `Type.makeObject` for the workerd motivation.\n     */\n    id?: EntityId;\n  }): <Self extends Schema.Schema.Any>(\n    self: Self,\n  ) => Relation<\n    Schema.Schema.Type<Self>,\n    SourceInstance & EntityModule.OfKind<typeof EntityModule.Kind.Object>,\n    TargetInstance & EntityModule.OfKind<typeof EntityModule.Kind.Object>\n  >;\n} = internal.EchoRelationSchema as any;\n\n/**\n * Type that represents any ECHO type-kind entity — a `Type.Type` meta-schema\n * value (static `Type.Type` or a persisted draft from `db.addType(...)`).\n * Mirrors {@link AnyObj} / {@link AnyRelation} for the third sibling kind.\n */\nexport type AnyType = Type<unknown>;\n\n/**\n * Any ECHO type-entity — one of the three sibling kinds: object-kind, relation-kind,\n * or type-kind (the meta-schema). APIs that want \"any ECHO type\" use this union;\n * the underlying Effect Schema is retrieved via `Type.getSchema`.\n */\nexport type AnyEntity = AnyObj | AnyRelation | AnyType;\n\n/**\n * Type guard: narrows a `Type.AnyEntity` to an object-kind entity. Checks\n * ENTITIES, not instances — use `Obj.isObject` for instances. Raw\n * `Schema.Schema` values (including the branded `Obj.Unknown` companion)\n * are intentionally not accepted; inspect their `TypeAnnotation` directly.\n */\nexport const isObject = (entity: AnyEntity): entity is AnyObj => {\n  return internal.getSchemaKind(entity) === internal.EntityKind.Object;\n};\n\n/**\n * Type guard: narrows a `Type.AnyEntity` to a relation-kind entity. Checks\n * ENTITIES, not instances — use `Relation.isRelation` for instances.\n */\nexport const isRelation = (entity: AnyEntity): entity is AnyRelation => {\n  return internal.getSchemaKind(entity) === internal.EntityKind.Relation;\n};\n\n/**\n * Type guard: narrows a `Type.AnyEntity` to the type-kind meta-schema\n * (e.g. `Type.Type`). Mirrors {@link isObject} / {@link isRelation}.\n */\nexport const isTypeKind = (entity: AnyEntity): entity is Type => {\n  return internal.getSchemaKind(entity) === internal.EntityKind.Type;\n};\n\n/**\n * Narrow a `Type.AnyEntity` (e.g. one returned from `schemaRegistry.query(...)`)\n * to `AnyObj`, throwing if it describes a relation or the type-kind\n * meta-schema. Use at call sites that need to pass the value to `Obj.make`,\n * `Filter.type`, or other object-only APIs.\n */\nexport const assertObject = (entity: AnyEntity): AnyObj => {\n  assertArgument(isObject(entity), 'entity', 'Expected an object-kind Type entity.');\n  return entity;\n};\n\n/** Narrow a `Type.AnyEntity` to `AnyRelation`, throwing otherwise. */\nexport const expectRelation = (entity: AnyEntity): AnyRelation => {\n  assertArgument(isRelation(entity), 'entity', 'Expected a relation-kind Type entity.');\n  return entity;\n};\n\n/** Narrow a `Type.AnyEntity` to the `Type.Type` meta-schema, throwing otherwise. */\nexport const expectTypeKind = (entity: AnyEntity): Type => {\n  assertArgument(isTypeKind(entity), 'entity', 'Expected a type-kind Type entity.');\n  return entity;\n};\n\n/**\n * Type that represents any Ref schema (with unknown target type).\n * This is a schema type, not an instance type.\n */\nexport type AnyRef = Schema.Schema<internal.Ref<any>, EncodedReference>;\n\n//\n// Schema utility functions\n//\n\n/**\n * Returns the URI identifying a type entity. Always defined.\n *\n * - Static `Type.Obj` / `Type.Relation` → typename DXN (e.g. `dxn:com.example.type.person:0.1.0`).\n * - Persisted `Type.Type` instance (has `id`) → local `EID` (`echo:/<objectId>`).\n * - In-memory `Type.Type` draft (has `id`, no typename) → local `EID`.\n *\n * Only accepts `Type.AnyEntity` entities. Raw `Schema.Schema` values and the\n * branded `Obj.Unknown` / `Relation.Unknown` schemas are intentionally not\n * supported — use `internal.getSchemaURI` or the schema's typename annotation\n * directly when working at the schema level.\n */\nexport const getURI = (input: AnyEntity): URI.URI => {\n  // For Type entities, route through `getTypeURIFromSpecifier` (id → EID,\n  // typename/version → DXN). For Obj/Relation entities, unwrap to the source\n  // Effect Schema first and read its annotations.\n  if (isType(input)) {\n    return internal.getTypeURIFromSpecifier(input);\n  }\n  return internal.getSchemaURI(getSchema(input)) ?? raise(new TypeError('Type entity has no URI'));\n};\n\n/**\n * @returns The typename. Example: `com.example.type.person`.\n *\n * Persisted `Type.Type` entities carry typename in `EntityMeta.key` (the\n * canonical registry-provenance field); unnamed drafts fall back to the\n * entity's object id so the helper always returns a string. Any `dxn:` or\n * `echo:/` prefix is stripped — typename is a bare identifier, not a URI.\n */\n// TODO(wittjosiah): For in-database types this should return the object id once the registry\n//   has more robust options for shadowing types (so callers can disambiguate db-stored copies).\nexport const getTypename = (input: AnyEntity): string => {\n  // Both in-memory and in-database entities carry typename in `EntityMeta.key`\n  // — the canonical registry-provenance field. In-memory entities attach meta\n  // eagerly (see `makeEchoTypeSchema`), so a single meta-backed read covers\n  // both forms.\n  const meta = internal.getMetaChecked(input);\n  let typename: string | undefined = meta.key as string | undefined;\n  // `meta.key` is a denormalized copy of the typename. The authoritative source\n  // for a type entity is its `jsonSchema.typename` (`getSchema` rebuilds the\n  // Effect Schema from `jsonSchema`). A type loaded from a snapshot can arrive\n  // with `meta.key` absent (the meta round-trip dropped the denormalized copy)\n  // while `jsonSchema.typename` is always present — consult it before the\n  // last-resort id fallback so callers never receive a bare object id where a\n  // typename is expected (e.g. `Filter.typename`, which rejects non-typenames).\n  if (typename == null) {\n    typename = input.jsonSchema?.typename;\n  }\n  // Unnamed drafts (no meta.key, no jsonSchema typename) fall back to the id.\n  typename ??= input.id as string;\n  // Typename is a bare identifier — strip URI prefixes if a caller seeded\n  // meta.key with one accidentally (or if a static entity carries a DXN-\n  // style typename).\n  typename = stripTypenamePrefix(typename);\n  invariant(typeof typename === 'string' && typename.length > 0, 'Invalid typename');\n  return typename;\n};\n\n/**\n * Gets the version.\n * @example 0.1.0\n * @example 0.1.0-<heads> (in-database, versioned by automerge heads)\n *\n * The registry-provenance semver lives in `EntityMeta.version`; unversioned\n * drafts default to {@link DRAFT_VERSION} (`'0.0.0'`). In-database entities are\n * additionally versioned by their automerge heads, which are exposed as the\n * semver pre-release tag (`<semver>-<heads>`). In-memory declarations have no\n * heads and surface the bare semver. Read the registry semver alone via\n * `Type.getMeta(input).version`.\n */\nexport const getVersion = (input: AnyEntity): string => {\n  const meta = internal.getMetaChecked(input);\n  // As with `getTypename`: `meta.version` is a denormalized copy; the\n  // authoritative semver lives in `jsonSchema.version`. Prefer meta, fall back\n  // to jsonSchema (always present on persisted types, survives serialization),\n  // then to `DRAFT_VERSION` for unversioned drafts.\n  const semver = (meta.version as string | undefined) ?? input.jsonSchema?.version ?? DRAFT_VERSION;\n  invariant(typeof semver === 'string' && semver.match(/^\\d+\\.\\d+\\.\\d+$/), 'Invalid version');\n  // In-database entities are versioned by their automerge heads; expose them as\n  // the semver pre-release tag. In-memory drafts carry no heads → bare semver.\n  const heads = internal.version(input).automergeHeads;\n  if (heads != null && heads.length > 0) {\n    return `${semver}-${[...heads].sort().join('.')}`;\n  }\n  return semver;\n};\n\n/**\n * Strip URI prefixes (`dxn:`, `echo:/`, `echo://`) from a typename string.\n * Typename is a bare identifier — callers reading from meta or from a\n * caller-supplied seed value shouldn't propagate URI prefixes downstream.\n */\nconst stripTypenamePrefix = (value: string): string => {\n  if (value.startsWith('dxn:')) {\n    return value.slice('dxn:'.length);\n  }\n  if (value.startsWith('echo://')) {\n    return value.slice('echo://'.length);\n  }\n  if (value.startsWith('echo:/')) {\n    return value.slice('echo:/'.length);\n  }\n  return value;\n};\n\n/**\n * Type predicate: true iff the value is any type-kind ECHO entity — a static\n * `Type.Obj` / `Type.Relation` produced by `Type.makeObject` / `Type.makeRelation`, a\n * static meta `Type.Type`, or a persisted `Type.Type` returned by the database.\n *\n * All three branches stamp `[KindId] = Type`, so this is a single brand check.\n * Use {@link isObject} / {@link isRelation} / {@link isTypeKind}\n * when you need to discriminate further; use {@link getDatabase} when you mean\n * \"is this a db-attached type\" (vs. an in-memory declaration).\n */\nexport const isType = (value: unknown): value is AnyEntity =>\n  internal.getEntityKindBrand(value) === internal.EntityKind.Type;\n\n/**\n * Get the database the type entity belongs to, or `undefined` if it is an\n * in-memory declaration (`Type.makeObject` / `Type.makeRelation` result) not\n * yet attached to a database. Mirrors `Obj.getDatabase` / `Relation.getDatabase`.\n *\n * Database attachment is the canonical discriminator between in-memory and\n * in-database type entities — both are live reactive `TypeSchema` instances and\n * are otherwise indistinguishable.\n */\nexport const getDatabase = (input: AnyEntity): Database.Database | undefined => internal.getDatabase(input);\n\n/**\n * Mutable meta type returned by `Type.getMeta` inside a `Type.update` callback.\n * Mirrors `Obj.Meta` / `Relation.Meta` — `Type.Type` is an Entity like its\n * siblings, so its meta is the same `EntityMeta` record:\n * `{ keys, tags?, key?, version? }`.\n *\n * `key` / `version` here are the canonical registry-provenance pair\n * (typename + semver) on persisted Type.Type entities; they are absent on\n * unnamed drafts. Use {@link getTypename} / {@link getVersion} when you want\n * a non-`undefined` value with id / {@link DRAFT_VERSION} fallbacks.\n */\nexport type Meta = internal.Meta;\n\n/**\n * Deeply read-only version of {@link Meta}.\n * Prevents mutation at all nesting levels (e.g., `meta.keys.push()` is a TS error).\n */\nexport type ReadonlyMeta = internal.ReadonlyMeta;\n\n/**\n * Returns the entity's `EntityMeta`. Same semantics as `Obj.getMeta` /\n * `Relation.getMeta` — `Type.Type` is an Entity and carries the canonical\n * `EntityMeta` directly. Returns mutable meta when passed a mutable type\n * (inside a `Type.update` callback), read-only meta otherwise.\n *\n * For persisted Type entities, `meta.key` holds the typename and\n * `meta.version` holds the semver. Use {@link getTypename} / {@link getVersion}\n * if you want the helpers' id / {@link DRAFT_VERSION} fallbacks for drafts.\n *\n * Both persisted and in-memory type entities (`Type.makeObject` /\n * `Type.makeRelation` results) carry their `EntityMeta` via `[MetaId]`, so the\n * lookup is uniform.\n */\nexport function getMeta(entity: internal.Mutable<AnyEntity>): Meta;\nexport function getMeta(entity: Mutable): Meta;\nexport function getMeta(entity: AnyEntity): ReadonlyMeta;\nexport function getMeta(entity: AnyEntity | internal.Mutable<AnyEntity> | Mutable): ReadonlyMeta | Meta {\n  // The `Mutable` overload accepts the narrowed view passed to `Type.update`\n  // callbacks; at runtime that draft IS the underlying persisted Type entity,\n  // so the same `MetaId` lookup works.\n  assertArgument(isType(entity), 'entity', 'Expected a Type entity.');\n  // Both persisted and in-memory type entities carry runtime `EntityMeta` via\n  // `[MetaId]`, so the lookup is uniform.\n  return internal.getMetaChecked(entity);\n}\n\n/**\n * Get the display label of a type entity.\n * Reads the field(s) nominated by the type's {@link LabelAnnotation} (e.g. `name` on persisted schemas).\n * Returns `undefined` if no label field is populated.\n */\nexport const getLabel = (entity: AnyEntity, options?: internal.GetLabelOptions): string | undefined =>\n  internal.getLabel(entity, options);\n\n/**\n * String key used to phantom-carry the instance type produced by a `Type.Type`.\n * Used by `Type.InstanceType<typeof Foo>` to recover the schema instance type\n * since `Type.makeObject(dxn)` does not return a `Schema.Schema`.\n *\n * Re-exported from the internal types layer so both `Type.ts` and internal\n * helpers (`makeObject`, `createObject`) reference the same phantom key.\n */\nexport const InstancePhantomId = internal.InstancePhantomId;\nexport type InstancePhantomId = internal.InstancePhantomId;\n\n/**\n * Sibling of {@link Obj} / {@link Relation} for the third ECHO entity kind:\n * **type-kind** entities (meta-schemas). The singleton {@link Type} const is\n * the canonical example — it describes stored type definitions themselves.\n *\n * Not a `Schema.Schema`. Use `Type.getSchema(value)` to obtain the underlying\n * Effect Schema and `Type.update(value, draft => ...)` to mutate.\n *\n * `A` is the instance-type phantom — what `Obj.make(value, ...)` would produce.\n * Merged with the `Type` const value via TypeScript declaration merging.\n */\nexport interface Type<A = unknown> extends BaseTypeEntity<A & EntityModule.OfKind<typeof EntityModule.Kind.Type>> {\n  /** Schema-kind brand (type — the meta-schema kind). */\n  readonly [internal.SchemaKindId]: internal.EntityKind.Type;\n\n  /** Source Effect Schema — used internally by `Type.getSchema(self)`. */\n  readonly [internal.StaticTypeSchemaSlot]: Schema.Schema.AnyNoContext;\n}\n\n/**\n * Instance type produced by a Type entity.\n *\n * Accepts ONLY {@link AnyEntity} inputs — `Type.Obj`, `Type.Relation`, or\n * `Type.Type`. Raw Effect `Schema.Schema` values are rejected: for those, use\n * `Schema.Schema.Type<typeof Foo>` directly. This separation keeps the type\n * system honest about which values represent ECHO entities versus plain\n * Effect schemas.\n *\n * Dispatches on the entity kind:\n *  - `Relation<Props, S, T>` → `Endpoints<S,T> & Props & OfKind<Relation>`\n *  - `Obj<A>`                → `A & OfKind<Object>`\n *  - `Type<A>`               → `A & OfKind<Type>`\n */\nexport type InstanceType<T extends AnyEntity> =\n  T extends Relation<infer Props, infer Source, infer Target, any>\n    ? RelationModule.Endpoints<Source, Target> & Props & EntityModule.OfKind<typeof EntityModule.Kind.Relation>\n    : T extends Obj<infer A, any>\n      ? A & EntityModule.OfKind<typeof EntityModule.Kind.Object>\n      : T extends Type<infer A>\n        ? A & EntityModule.OfKind<typeof EntityModule.Kind.Type>\n        : never;\n\n/**\n * Returns the Effect Schema for a type entity.\n *\n * - For static `Type.Obj` / `Type.Relation` entities the source Effect Schema is\n *   read from a hidden slot — these overloads preserve the instance type.\n * - For `Type.Type` entities (the meta-schema kind) the schema is rebuilt from\n *   `type.jsonSchema`; the instance type isn't statically knowable so the wide\n *   `AnyEntity` overload widens to `Schema.Schema.AnyNoContext`.\n *\n * Always call this when you need to interact with the Effect Schema API\n * (e.g. before passing to Effect.Schema functions). For ECHO-side APIs\n * (`Obj.make`, `Filter.type`, `Ref`) pass the type entity directly.\n *\n * Only accepts `Type.AnyEntity` — raw `Schema.Schema` values can be used\n * directly without unwrapping.\n */\nexport function getSchema<T extends AnyObj>(type: T): Schema.Schema<InstanceType<T>>;\nexport function getSchema<T extends AnyRelation>(type: T): Schema.Schema<InstanceType<T>>;\nexport function getSchema(type: AnyEntity): Schema.Schema.AnyNoContext;\nexport function getSchema(type: AnyEntity): Schema.Schema.AnyNoContext {\n  // Static `Type.Type` entities carry the source Effect Schema on a hidden\n  // slot so we can return it without round-tripping through JsonSchema.\n  const staticSchema = internal.getStaticTypeSchema(type);\n  if (staticSchema != null) {\n    return staticSchema;\n  }\n  assertArgument(isType(type), 'type', 'Expected a Type entity.');\n  // Persisted `Type.Type` entity — build the Effect Schema from its stored\n  // jsonSchema and re-attach the TypeIdentifierAnnotation so the rebuilt\n  // schema's URI (via getSchemaURI) matches the entity's local EID.\n  const rebuilt = internal.toEffectSchema(type.jsonSchema);\n  if (typeof type.id === 'string') {\n    return rebuilt.annotations({\n      [internal.TypeIdentifierAnnotationId]: EID.make({ entityId: type.id }),\n    });\n  }\n  return rebuilt;\n}\n\n/**\n * Mutable view of a `Type.Type` — the shape passed to the `Type.update` callback.\n * Outside `Type.update`, `Type.Type` fields are read-only (both at the type level\n * and at runtime — direct assignment throws). Use this to constrain mutation to\n * the change context, analogous to `Obj.update(obj, (draft) => ...)`.\n *\n * NOTE: `typename` and `version` are intentionally absent — they live in\n * `EntityMeta` (`key` / `version` — the canonical registry-provenance pair).\n * Read them via {@link getTypename} / {@link getVersion} / {@link getMeta};\n * `typename` is treated as immutable on persisted entities.\n *\n * Unlike `Obj.update` — whose mutable view is inferred as `Mutable<A>` over the\n * whole instance type because every data field is editable — a `Type.Type`\n * exposes only `name` and `jsonSchema` for mutation. The rest of its shape\n * (`id`, the `[KindId]` / `[SchemaKindId]` brands, and `typename` / `version`\n * in meta) is immutable, so this view is declared explicitly rather than\n * derived from `InstanceType<Type.Type>`.\n */\nexport interface Mutable {\n  name?: string;\n  // Deep-mutable within the change context — `Type.update`'s purpose is to allow\n  // mutation, so the draft exposes `jsonSchema` as writable (the readonly\n  // `JsonSchemaType` would force callers to cast).\n  jsonSchema: Types.DeepMutable<internal.JsonSchemaType>;\n}\n\n/**\n * Perform mutations on a `Type.Type` within a change context.\n *\n * The callback receives a {@link Mutable} view of the type — direct mutation of\n * a `Type.Type` outside `Type.update` throws at runtime, mirroring `Obj.update`.\n * Delegates to the same automerge-transaction primitive `Obj.update(obj, cb)` uses.\n */\nexport const update = (type: AnyEntity, callback: (mutable: Mutable) => void): void => {\n  // `Type.Type` is an ECHO object; the change machinery is the same as `Obj.update`.\n  internal.change(type, callback as internal.ChangeCallback<AnyEntity>);\n};\n\n//\n// Field-level helpers for mutating persisted types.\n// These are thin wrappers over `Type.update` plus the JsonSchema manipulation\n// utilities. Callers pass a persisted `Type.Type` (e.g. one returned by\n// `db.addType(schemaEntity)`) and the helper drives the change context.\n//\n\n/**\n * Add fields to a persisted type's schema.\n * @throws if the type is not persisted.\n */\nexport const addFields = (type: AnyEntity, fields: Schema.Struct.Fields): void => {\n  const extended = typeInternal.addFieldsToSchema(getSchema(type), fields);\n  update(type, (draft) => {\n    draft.jsonSchema = internal.toJsonSchema(extended);\n  });\n};\n\n/**\n * Replace existing fields on a persisted type's schema.\n * @throws if the type is not persisted.\n */\nexport const updateFields = (type: AnyEntity, fields: Schema.Struct.Fields): void => {\n  const updated = typeInternal.updateFieldsInSchema(getSchema(type), fields);\n  update(type, (draft) => {\n    draft.jsonSchema = internal.toJsonSchema(updated);\n  });\n};\n\n/**\n * Rename a field on a persisted type's schema.\n * @throws if the type is not persisted.\n */\nexport const updateFieldPropertyName = (\n  type: Type,\n  { before, after }: { before: PropertyKey; after: PropertyKey },\n): void => {\n  const renamed = typeInternal.updateFieldNameInSchema(getSchema(type), { before, after });\n  update(type, (draft) => {\n    draft.jsonSchema = internal.toJsonSchema(renamed);\n  });\n};\n\n/**\n * Remove fields from a persisted type's schema.\n * @throws if the type is not persisted.\n */\nexport const removeFields = (type: AnyEntity, fieldNames: string[]): void => {\n  const removed = typeInternal.removeFieldsFromSchema(getSchema(type), fieldNames);\n  update(type, (draft) => {\n    draft.jsonSchema = internal.toJsonSchema(removed);\n  });\n};\n"],
  "mappings": "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",
  "names": ["InstancePhantomId", "getDatabase", "getLabel", "makeObject", "raise", "assertArgument", "invariant", "EID", "makeObject", "version", "typename", "typeInternal", "enrichedJsonSchema", "entityKind", "EntityKind", "relationSource", "sourceURI", "relationTarget", "keys", "entity", "getSchemaURI", "input", "heads", "join", "semver", "value", "startsWith", "getDatabase", "InstancePhantomId", "staticSchema", "assertArgument", "annotations", "internal", "TypeIdentifierAnnotationId", "entityId", "change", "callback", "type", "draft", "extended", "updated", "before", "after", "update", "removed"]
}
