{
  "version": 3,
  "sources": ["../../../src/Registry.ts"],
  "sourcesContent": ["// Copyright 2026 DXOS.org\n\n// @import-as-namespace\n\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\n\nimport { type ReadOnlyEvent } from '@dxos/async';\n\nimport type * as Database from './Database';\nimport * as Entity from './Entity';\nimport type * as Filter from './Filter';\nimport type * as Query from './Query';\n\n/**\n * Identifier denoting an ECHO Registry.\n */\nexport const TypeId = Symbol.for('@dxos/echo/Registry');\nexport type TypeId = typeof TypeId;\n\n/**\n * Composable, in-memory registry of keyed ECHO entities.\n *\n * Entities are stored by id and queried via the standard ECHO Query API.\n * A registry may delegate to an optional upstream registry: results from the local\n * registry take precedence and upstream results fill in anything not found locally.\n *\n * Intended use cases include caches of schemas, operations, blueprints, routines, plugins,\n * etc., sourced from 3rd-party plugins, local code, or local space objects.\n *\n * Types (schema-definition entities produced by `Type.makeObject` / `Type.makeRelation`) are\n * stored the same way as any other entity — via `add()`. Use `list().filter(Type.isType)` to\n * retrieve them.\n *\n * Scope: a Registry is independent of any ECHO space or Hypergraph — it is a process-local,\n * in-memory cache. Wire one per space (e.g. as a Layer scoped to the space's Effect runtime)\n * or share a single instance across spaces depending on the use case.\n *\n * The concrete implementation (and the `makeRegistry` / `registryLayer` factories) lives in\n * `@dxos/echo-client`; this module declares only the interface so that the `@dxos/echo` API surface\n * stays free of query-matching dependencies.\n */\nexport interface Registry {\n  readonly [TypeId]: TypeId;\n\n  /**\n   * Stable per-instance identifier. Used to key process-local resources (e.g. memoized\n   * reactive atoms) to a specific registry instance, analogous to {@link Database.spaceId}.\n   */\n  readonly id: string;\n\n  /**\n   * Fires whenever local registry contents change (add, remove, or clear).\n   */\n  readonly changed: ReadOnlyEvent<void>;\n\n  /**\n   * All locally-stored entities.\n   * Does not include upstream entities — use {@link list} for that.\n   */\n  readonly local: readonly Entity.Unknown[];\n\n  /**\n   * Add or replace one or more entities in the local registry.\n   * Existing entries with the same id are replaced.\n   * Also indexes type entities by DXN for fast lookup.\n   */\n  add(entities: readonly Entity.Unknown[]): void;\n\n  /**\n   * Remove an entity by id from the local registry.\n   * @returns true if an entity was removed, false if it was not found.\n   */\n  remove(id: string): boolean;\n\n  /**\n   * Remove all locally-stored entities.\n   * Does not affect the upstream registry.\n   */\n  clear(): void;\n\n  /**\n   * Get an entity by id.\n   * Searches the local registry first, then falls back to the upstream registry.\n   */\n  get(id: string): Entity.Unknown | undefined;\n\n  /**\n   * Get an entity by one of its addressing URIs — a type entity by its typename DXN (or, when\n   * persisted, its identifier EID), a keyed entity by its `dxn:<key>[:<version>]`. Accepts legacy\n   * DXN forms (normalized internally). Searches the local registry first, then falls back to the\n   * upstream registry. Narrow the result with `Type.isType` when a type entity is required.\n   */\n  getByURI(uri: string): Entity.Unknown | undefined;\n\n  /**\n   * List all entities.\n   * Local entities take precedence over upstream entities with the same id.\n   */\n  list(): Entity.Unknown[];\n\n  /**\n   * Run an ECHO query against the registry's entities (implements {@link Database.Queryable}).\n   *\n   * Matching happens in-memory over {@link list}. Scope (`from`) clauses are unwrapped and\n   * ignored — a direct registry query always targets the registry's own entities. The primary\n   * way to query registry contents is still through the database (`db.query(...).from(Scope.registry())`),\n   * which fans the database and registry together; this method is for querying a registry directly.\n   *\n   * Only locally-evaluable AST nodes are supported: `select`, `filter`, `limit`, `from`, `options`,\n   * and boolean combinators. Server-side concerns (order, traversal, text/timestamp filters) throw.\n   */\n  query: Database.QueryFn;\n}\n\n/**\n * Type guard for {@link Registry}.\n */\nexport const isRegistry = (obj: unknown): obj is Registry =>\n  obj != null && typeof obj === 'object' && TypeId in obj && (obj as { [TypeId]?: unknown })[TypeId] === TypeId;\n\n/**\n * Options for the registry factory (`makeRegistry` in `@dxos/echo-client`).\n */\nexport type Options = {\n  /**\n   * Optional upstream registry. Queries fall back to upstream when an entity\n   * is not present in the local registry.\n   */\n  upstream?: Registry;\n\n  /**\n   * Initial set of entities to seed the local registry with.\n   */\n  initial?: readonly Entity.Unknown[];\n};\n\n/**\n * Effect Context tag for {@link Registry}.\n * Use this to inject a registry into Effect-based code.\n */\nexport class Service extends Context.Tag('@dxos/echo/Registry/Service')<Service, Registry>() {}\n\n/**\n * Executes a query against the registry and returns the results.\n * Analogous to {@link Database.query} `.run` for the in-process registry.\n */\nexport const runQuery: {\n  <Q extends Query.Any>(query: Q): Effect.Effect<Query.Type<Q>[], never, Service>;\n  <F extends Filter.Any>(filter: F): Effect.Effect<Filter.Type<F>[], never, Service>;\n} = (queryOrFilter: Query.Any | Filter.Any) =>\n  Effect.gen(function* () {\n    const registry = yield* Service;\n    return (yield* Effect.promise(() => registry.query(queryOrFilter as any).run())) as any;\n  });\n"],
  "mappings": ";;;;;AAAA;;;;;;;AAIA,YAAYA,aAAa;AACzB,YAAYC,YAAY;AAYjB,IAAMC,SAASC,uBAAOC,IAAI,qBAAA;AAqG1B,IAAMC,aAAa,CAACC,QACzBA,OAAO,QAAQ,OAAOA,QAAQ,YAAYJ,UAAUI,OAAQA,IAA+BJ,MAAAA,MAAYA;AAsBlG,IAAMK,UAAN,cAA8BC,YAAI,6BAAA,EAAA,EAAA;AAAqD;AAMvF,IAAMC,WAGT,CAACC,kBACIC,WAAI,aAAA;AACT,QAAMC,WAAW,OAAOL;AACxB,SAAQ,OAAcM,eAAQ,MAAMD,SAASE,MAAMJ,aAAAA,EAAsBK,IAAG,CAAA;AAC9E,CAAA;",
  "names": ["Context", "Effect", "TypeId", "Symbol", "for", "isRegistry", "obj", "Service", "Tag", "runQuery", "queryOrFilter", "gen", "registry", "promise", "query", "run"]
}
