Skip to content
English

全命中与首个 handled ​

策略的具体实现如下。

ts
export function definePolicySet<Input, Kind extends string>(
  definitions: readonly PolicyDefinition<Input, Kind>[],
) {
  const catalog = registerPolicies(definitions, 'when');
  return Object.freeze({
    ...readonlyCatalog(catalog, (id) => new TypeError(`Unknown policy: ${id}`)),
    assess(input: Input) {
      const matched = catalog.filter((policy) => booleanMatch(policy.when(input)));
      return {
        required: matched.length > 0,
        reasons: matched.map((policy) => policy.id),
        kinds: [...new Set(matched.map((policy) => policy.kind))],
      };
    },
  });
}

export function defineRecoveryChain<Input, Result>(
  definitions: readonly RecoveryDefinition<Input, Result>[],
) {
  const catalog = registerPolicies(definitions, 'tryRecover').map((definition) => {
    return Object.freeze({
      id: definition.id,
      description: definition.description,
      tryRecover(input: Input): RecoveryResult<Result> {
        const value = synchronous(
          definition.tryRecover(input),
          'Recovery handlers must be synchronous',
        );
        const result = value as RecoveryResult<Result>;
        if (
          !result ||
          typeof result !== 'object' ||
          typeof result.handled !== 'boolean' ||
          (result.handled && !('value' in result))
        )
          throw new TypeError('Invalid recovery outcome');
        return result;
      },
    });
  });
  const tryRecover = (
    input: Input,
    execution: Partial<import('../structs/common.js').ExecutionContext> = {},
  ): RecoveryResult<Result> => {
    for (const policy of catalog) {
      const result = nativeSubFlowSync(execution, 'recovery', policy.id, () =>
        policy.tryRecover(input),
      );
      if (result.handled) return result;
    }
    return { handled: false };
  };
  return Object.freeze({
    ...readonlyCatalog(catalog, (id) => new TypeError(`Unknown recovery policy: ${id}`)),
    tryRecover,
  });
}

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