Skip to content
English

引用快照、解析器登记和取消 ​

策略的具体实现如下。

ts
function snapshotArtifactReference(reference: ArtifactReference): ArtifactReference {
  if (!reference || typeof reference !== 'object')
    throw new TypeError('Invalid artifact reference');
  const { resolverId, artifactId, revision } = reference;
  if (
    typeof resolverId !== 'string' ||
    !resolverId.trim() ||
    typeof artifactId !== 'string' ||
    !artifactId.trim() ||
    (revision !== undefined && (typeof revision !== 'string' || !revision.trim()))
  )
    throw new TypeError('Invalid artifact reference');
  return Object.freeze({ resolverId, artifactId, ...(revision === undefined ? {} : { revision }) });
}

export function defineArtifactCatalog<Value, App>(
  definitions: readonly ArtifactResolver<Value, App>[],
) {
  const compiled = definitions.map((definition) => {
    if (!definition || typeof definition !== 'object')
      throw new TypeError('Use an artifact resolver id and OperationContext');
    const { id, resolve } = definition;
    if (typeof id !== 'string' || !id.trim() || typeof resolve !== 'function')
      throw new TypeError('Invalid artifact resolver');
    return Object.freeze({ id, resolve: resolve.bind(definition) });
  });
  const catalog = readonlyCatalog(
    compiled,
    (id) => new TypeError(`Unregistered artifact resolver: ${id}`),
  );
  /**
   * Resolve one reference through its registered resolver.
   *
   * @param reference - Resolver id, artifact id and optional revision; snapshotted and frozen
   *   before the call so a handler cannot observe later mutation.
   * @param context - Operation context supplying the abort signal.
   * @returns The resolver's value.
   * @throws TypeError For a malformed reference or context, or an unknown resolver id.
   */
  async function resolve(
    reference: ArtifactReference,
    context: OperationContext<App>,
  ): Promise<Value> {
    if (!context?.signal) throw new TypeError('Artifact resolution requires OperationContext');
    context.signal.throwIfAborted();
    const snapshot = snapshotArtifactReference(reference);
    context.signal.throwIfAborted();
    const result = await awaitWithSignal(
      catalog.require(snapshot.resolverId).resolve(snapshot, context),
      context.signal,
    );
    context.signal.throwIfAborted();
    return result;
  }
  return Object.freeze({ ...catalog, resolve });
}

接口参考、使用示例与开发指南。