{
  "version": 3,
  "sources": ["../../../src/internal/common/types/well-known-types.ts", "../../../src/internal/common/types/meta.ts", "../../../src/internal/common/api/meta.ts", "../../../src/internal/Entity/guard.ts", "../../../src/internal/Annotation/entity-dictionary.ts"],
  "sourcesContent": ["//\n// Copyright 2026 DXOS.org\n//\n\nimport { DXN } from '@dxos/keys';\n\n/**\n * DXN identity of the system {@link Tag} type.\n *\n * Defined in this low-level leaf so it can be shared by the public `Tag` type (which brands the\n * schema with this DXN) and by `EntityMetaSchema.tags` (which builds a `Ref<Tag>` schema from it)\n * without either importing the other — `Tag` is top-level and `meta` is deep-internal, so a direct\n * dependency between them would form an eval-order cycle.\n */\nexport const TagTypeDXN = DXN.make('org.dxos.type.tag', '0.1.0');\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { type EncodedReference, ForeignKey } from '@dxos/echo-protocol';\nimport { invariant } from '@dxos/invariant';\nimport { DXN } from '@dxos/keys';\nimport { type Comparator, intersection } from '@dxos/util';\n\nimport type * as Tag from '../../../Tag';\nimport { Dictionary } from '../../Annotation/dictionary';\n// `meta` is no longer re-exported from the `common/types` barrel (see ./index.ts), so importing the\n// Ref schema builder here no longer forms an eval-order cycle with `Annotation`/`Database`.\nimport { type Ref, createEchoReferenceSchema } from '../../Ref/ref';\nimport { type AnyProperties } from './base';\nimport { MetaId } from './model-symbols';\nimport { TagTypeDXN } from './well-known-types';\n\n/**\n * Property name for meta when object is serialized to JSON.\n */\nexport const ATTR_META = '@meta';\n\n//\n// EntityMeta\n//\n\n/**\n * Schema for references to {@link Tag} objects stored in {@link EntityMetaSchema.tags}.\n *\n * Built from the shared {@link createEchoReferenceSchema} (the same builder `Ref.Ref` uses) via\n * `Schema.suspend`, so it reuses the canonical ref codec rather than duplicating it. The Tag type\n * identity comes from the shared {@link TagTypeDXN} constant; `suspend` defers construction until\n * first use, and `Tag` is referenced type-only, so no `Tag` value import is needed.\n */\nconst TagRefSchema = Schema.suspend(\n  (): Schema.Schema<Ref<Tag.Tag>, EncodedReference> =>\n    // The factory yields a loosely-typed `Ref<any>` schema; narrow it to the Tag-typed ref.\n    createEchoReferenceSchema(undefined, DXN.getName(TagTypeDXN), DXN.getVersion(TagTypeDXN)) as Schema.Schema<\n      Ref<Tag.Tag>,\n      EncodedReference\n    >,\n);\n\nexport const EntityMetaSchema = Schema.Struct({\n  keys: Schema.Array(ForeignKey),\n\n  /**\n   * Tags applied to this entity, as references to {@link Tag} objects.\n   */\n  tags: Schema.Array(TagRefSchema),\n\n  /**\n   * Fully-qualified registry key for the object (FQN format, e.g. `org.example.type.foo`).\n   * Identifies the canonical registry entry the object instance was created from.\n   */\n  key: Schema.optional(Schema.String),\n\n  /**\n   * Semantic version of the registry entry the object was created from.\n   * Must be a valid semver string (e.g. `1.2.3`).\n   */\n  version: Schema.optional(Schema.String),\n\n  /**\n   * Dictionary of annotations to this entity.\n   */\n  annotations: Dictionary,\n\n  /**\n   * Unix ms timestamp when this entity was created.\n   * Read-only; sourced from the system section of the automerge document — not stored in meta.\n   */\n  createdAt: Schema.optional(Schema.Number),\n\n  /**\n   * Unix ms timestamp of the last automerge change on this entity's document.\n   * Read-only; derived from the automerge change graph — not stored in meta.\n   */\n  updatedAt: Schema.optional(Schema.Number),\n});\n\nexport type EntityMeta = Schema.Schema.Type<typeof EntityMetaSchema>;\n\n/*\n * Get metadata from object.\n * Only callable on the object root.\n *\n * @internal (use Obj.getMeta or Relation.getMeta)\n */\n// TODO(burdon): Refine type to BaseObj.\nexport const getMeta = (obj: AnyProperties): EntityMeta => {\n  const metadata = (obj as any)[MetaId];\n  invariant(metadata, 'EntityMeta not found.');\n  return metadata;\n};\n\n//\n// Foreign keys\n//\n\nexport const foreignKey = (source: string, id: string): ForeignKey => ({ source, id });\nexport const foreignKeyEquals = (a: ForeignKey, b: ForeignKey) => a.source === b.source && a.id === b.id;\n\n// TODO(dmaretskyi): Move to echo-schema.\nexport const compareForeignKeys: Comparator<AnyProperties> = (a: AnyProperties, b: AnyProperties) =>\n  intersection(getMeta(a).keys, getMeta(b).keys, foreignKeyEquals).length > 0;\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport type { ForeignKey } from '@dxos/echo-protocol';\nimport { assertArgument, invariant } from '@dxos/invariant';\nimport type { DeepReadonly } from '@dxos/util';\n\nimport type * as Tag from '../../../Tag';\nimport type { Ref } from '../../Ref/ref';\nimport { type Mutable } from '../proxy';\nimport { type AnyProperties } from '../types';\nimport { type EntityMeta, getMeta as getMeta$ } from '../types/meta';\n\n/**\n * Deeply read-only version of EntityMeta.\n */\nexport type ReadonlyMeta = DeepReadonly<EntityMeta>;\n\n/**\n * Mutable meta type received in meta mutation callbacks.\n */\nexport type Meta = Mutable<EntityMeta>;\n\n/**\n * Get the metadata for an entity with validation.\n * Returns mutable meta when passed a mutable entity (inside change callback).\n * Returns read-only meta when passed a regular entity or snapshot.\n *\n * TODO(burdon): When passed a Snapshot, should return a snapshot of meta, not the live meta proxy.\n */\nexport function getMetaChecked(entity: Mutable<AnyProperties>): Meta;\nexport function getMetaChecked(entity: AnyProperties): ReadonlyMeta;\nexport function getMetaChecked(entity: AnyProperties): Meta | ReadonlyMeta {\n  assertArgument(entity, 'entity', 'Should be an entity.');\n  const meta = getMeta$(entity);\n  invariant(meta != null, 'Invalid entity.');\n  return meta;\n}\n\n/**\n * @returns Foreign keys for the entity from the specified source.\n * Accepts both reactive entities and snapshots.\n */\nexport const getKeys = (entity: AnyProperties, source: string): ForeignKey[] => {\n  assertArgument(entity, 'entity', 'Should be an entity.');\n  const meta = getMetaChecked(entity);\n  invariant(meta != null, 'Invalid entity.');\n  return meta.keys.filter((key) => key.source === source);\n};\n\n/**\n * Delete all keys from the entity for the specified source.\n * Must be called within an Obj.update or Relation.update callback.\n */\nexport const deleteKeys = (entity: Mutable<AnyProperties>, source: string) => {\n  const meta = getMetaChecked(entity);\n  for (let i = 0; i < meta.keys.length; i++) {\n    if (meta.keys[i].source === source) {\n      meta.keys.splice(i, 1);\n      i--;\n    }\n  }\n};\n\n/**\n * Add a tag (a reference to a {@link Tag} object) to the entity. Idempotent.\n * Must be called within an Obj.update or Relation.update callback.\n */\nexport const addTag = (entity: Mutable<AnyProperties>, tag: Ref<Tag.Tag>) => {\n  const meta = getMetaChecked(entity);\n  // Two refs to the same target are not `===`; dedupe by URI.\n  if (!meta.tags.some((existing) => existing.uri === tag.uri)) {\n    meta.tags.push(tag);\n  }\n};\n\n/**\n * Remove a tag (a reference to a {@link Tag} object) from the entity. No-op when not present.\n * Must be called within an Obj.update or Relation.update callback.\n */\nexport const removeTag = (entity: Mutable<AnyProperties>, tag: Ref<Tag.Tag>) => {\n  const meta = getMetaChecked(entity);\n  for (let i = 0; i < meta.tags.length; i++) {\n    if (meta.tags[i].uri === tag.uri) {\n      meta.tags.splice(i, 1);\n      i--;\n    }\n  }\n};\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport type * as Entity from '../../Entity';\nimport { KindId, SnapshotKindId } from '../common/types';\n\n/**\n * Returns true if the value is an ECHO entity instance (object or relation).\n */\nexport const isEntity = (value: unknown): value is Entity.Unknown => {\n  if (typeof value !== 'object' || value === null) {\n    return false;\n  }\n  return (value as any)[KindId] !== undefined;\n};\n\n/**\n * Returns true if the value is an ECHO entity snapshot.\n */\nexport const isSnapshot = (value: unknown): value is Entity.Snapshot => {\n  if (typeof value !== 'object' || value === null) {\n    return false;\n  }\n  return (value as any)[SnapshotKindId] !== undefined;\n};\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Option from 'effect/Option';\n\nimport { deepMapValues } from '@dxos/util';\n\nimport type * as Annotation from '../../Annotation';\nimport type * as Entity from '../../Entity';\nimport { getMetaChecked } from '../common/api/meta';\nimport { type Mutable } from '../common/proxy/reactive';\nimport { getDatabase } from '../Entity/api';\nimport { isEntity, isSnapshot } from '../Entity/guard';\nimport { Ref, getRefSavedTarget } from '../Ref';\nimport { getDictionary, setDictionary } from './dictionary';\n\n/**\n * Get the value of an annotation from an entity instance or snapshot.\n */\nexport const get = <T>(\n  target: Entity.Unknown | Entity.Snapshot,\n  annotation: Annotation.Annotation<T>,\n): Option.Option<T> => {\n  if (isEntity(target) || isSnapshot(target)) {\n    const meta = getMetaChecked(target);\n    return getDictionary(meta.annotations, annotation);\n  } else {\n    throw new TypeError('Target is not an annotation target.');\n  }\n};\n\n/**\n * Set the value of an annotation on an entity instance.\n * Must be called with a mutable entity — i.e. inside an `Obj.update` callback.\n */\nexport const set = <T>(target: Mutable<Entity.Unknown>, annotation: Annotation.Annotation<T>, value: T): void => {\n  if (isEntity(target)) {\n    const meta = getMetaChecked(target);\n    // Persist any unsaved Ref targets in the value into the entity's database so\n    // the encoded DXN resolves on read. This mirrors normal property assignment,\n    // where the reactive proxy links unsaved ref targets via `createRef` →\n    // `database.add`. `setDictionary` pre-encodes the value (`Schema.encodeSync`),\n    // so the live Ref never reaches the proxy's link handling and would otherwise\n    // be stored as a dangling reference.\n    persistRefTargets(target, value);\n    setDictionary(meta.annotations, annotation, value);\n  } else {\n    throw new TypeError('Target is not an annotation target.');\n  }\n};\n\n/**\n * Add any unsaved Ref targets found in `value` to the host entity's database, matching the\n * auto-persistence applied to refs assigned to ordinary entity properties. Refs whose target\n * already lives in a database (the host's or a foreign one) are left untouched.\n */\nconst persistRefTargets = (host: Entity.Unknown, value: unknown): void => {\n  const database = getDatabase(host);\n  if (database == null) {\n    return;\n  }\n\n  deepMapValues(value, (current, recurse) => {\n    if (Ref.isRef(current)) {\n      const refTarget = getRefSavedTarget(current);\n      if (refTarget != null && isEntity(refTarget) && getDatabase(refTarget) == null) {\n        database.add(refTarget);\n      }\n      return current;\n    }\n    return recurse(current);\n  });\n};\n"],
  "mappings": "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",
  "names": ["DXN", "TagTypeDXN", "make", "Schema", "ForeignKey", "invariant", "DXN", "intersection", "Schema", "Struct", "keys", "ForeignKey", "invariant", "metadata", "id", "compareForeignKeys", "a", "b", "intersection", "getMeta", "assertArgument", "invariant", "__dxlog_file", "getMetaChecked", "meta", "entity", "invariant", "keys", "key", "source", "splice", "i", "tags", "existing", "length", "uri", "isEntity", "value", "KindId", "undefined", "isSnapshot", "SnapshotKindId", "deepMapValues", "get", "target", "annotation", "isEntity", "isSnapshot", "meta", "getMetaChecked", "getDictionary", "annotations", "TypeError", "set", "value", "persistRefTargets", "setDictionary", "host", "database", "getDatabase", "deepMapValues", "current", "recurse", "Ref", "isRef", "refTarget", "getRefSavedTarget", "add"]
}
