@sayoriqwq/effect-harness 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HARNESS.md +34 -0
- package/README.md +113 -0
- package/dist/bin/effect-harness.d.ts +2 -0
- package/dist/bin/effect-harness.js +39 -0
- package/dist/bin/effect-harness.js.map +1 -0
- package/dist/src/cli/Main.d.ts +6 -0
- package/dist/src/cli/Main.js +141 -0
- package/dist/src/cli/Main.js.map +1 -0
- package/dist/src/harness/CraftSkills.d.ts +14 -0
- package/dist/src/harness/CraftSkills.js +164 -0
- package/dist/src/harness/CraftSkills.js.map +1 -0
- package/dist/src/harness/Errors.d.ts +24 -0
- package/dist/src/harness/Errors.js +26 -0
- package/dist/src/harness/Errors.js.map +1 -0
- package/dist/src/harness/GuardrailRules.d.ts +6 -0
- package/dist/src/harness/GuardrailRules.js +303 -0
- package/dist/src/harness/GuardrailRules.js.map +1 -0
- package/dist/src/harness/Guardrails.d.ts +10 -0
- package/dist/src/harness/Guardrails.js +69 -0
- package/dist/src/harness/Guardrails.js.map +1 -0
- package/dist/src/harness/Init.d.ts +9 -0
- package/dist/src/harness/Init.js +234 -0
- package/dist/src/harness/Init.js.map +1 -0
- package/dist/src/harness/Model.d.ts +44 -0
- package/dist/src/harness/Model.js +169 -0
- package/dist/src/harness/Model.js.map +1 -0
- package/dist/src/harness/ModuleSources.d.ts +5 -0
- package/dist/src/harness/ModuleSources.js +47 -0
- package/dist/src/harness/ModuleSources.js.map +1 -0
- package/dist/src/harness/PnpmWorkspace.d.ts +2 -0
- package/dist/src/harness/PnpmWorkspace.js +23 -0
- package/dist/src/harness/PnpmWorkspace.js.map +1 -0
- package/dist/src/harness/Publish.d.ts +53 -0
- package/dist/src/harness/Publish.js +282 -0
- package/dist/src/harness/Publish.js.map +1 -0
- package/dist/src/harness/SelfVerify.d.ts +4 -0
- package/dist/src/harness/SelfVerify.js +56 -0
- package/dist/src/harness/SelfVerify.js.map +1 -0
- package/dist/src/harness/SourcePin.d.ts +12 -0
- package/dist/src/harness/SourcePin.js +320 -0
- package/dist/src/harness/SourcePin.js.map +1 -0
- package/dist/src/harness/Status.d.ts +12 -0
- package/dist/src/harness/Status.js +88 -0
- package/dist/src/harness/Status.js.map +1 -0
- package/dist/src/harness/TargetVerify.d.ts +8 -0
- package/dist/src/harness/TargetVerify.js +432 -0
- package/dist/src/harness/TargetVerify.js.map +1 -0
- package/dist/src/harness/TestContract.d.ts +6 -0
- package/dist/src/harness/TestContract.js +45 -0
- package/dist/src/harness/TestContract.js.map +1 -0
- package/dist/src/platform/Json.d.ts +8 -0
- package/dist/src/platform/Json.js +35 -0
- package/dist/src/platform/Json.js.map +1 -0
- package/dist/src/platform/ManagedFiles.d.ts +8 -0
- package/dist/src/platform/ManagedFiles.js +59 -0
- package/dist/src/platform/ManagedFiles.js.map +1 -0
- package/dist/src/platform/Process.d.ts +8 -0
- package/dist/src/platform/Process.js +80 -0
- package/dist/src/platform/Process.js.map +1 -0
- package/guide/default-capabilities.md +38 -0
- package/guide/index.md +49 -0
- package/guide/setup.md +64 -0
- package/harness/default-capabilities.md +32 -0
- package/harness/exposure.md +46 -0
- package/harness/feedback/index.md +60 -0
- package/harness/index.md +22 -0
- package/harness/official-inventory.md +85 -0
- package/harness/runtime/codex/AGENTS.fragment.md +28 -0
- package/harness/runtime/codex/agents/effect-worker.md +26 -0
- package/harness/runtime/codex/skills/effect-code/SKILL.md +72 -0
- package/harness/runtime/codex/skills/effect-code/agents/openai.yaml +4 -0
- package/harness/runtime/codex/skills/effect-feedback/SKILL.md +66 -0
- package/harness/runtime/codex/skills/effect-feedback/agents/openai.yaml +4 -0
- package/harness/source.md +52 -0
- package/harness/target-agent-contract.md +205 -0
- package/package.json +68 -0
- package/repos/craft-skills.manifest.json +34 -0
- package/repos/effect/.agents/skills/grill-me/SKILL.md +43 -0
- package/repos/effect/.agents/skills/jsdocs/SKILL.md +203 -0
- package/repos/effect/.agents/skills/scratchpad/SKILL.md +44 -0
- package/repos/effect/.agents/skills/scratchpad/agents/openai.yaml +7 -0
- package/repos/effect/.agents/skills/scratchpad/scripts/extract-example.mjs +260 -0
- package/repos/effect/.changeset/add-bigdecimal-sumall-multiplyall.md +5 -0
- package/repos/effect/.changeset/add-chunk-schema.md +5 -0
- package/repos/effect/.changeset/add-command-hidden.md +19 -0
- package/repos/effect/.changeset/add-config-nested.md +5 -0
- package/repos/effect/.changeset/add-flag-hidden.md +15 -0
- package/repos/effect/.changeset/add-from-string-schemas.md +5 -0
- package/repos/effect/.changeset/add-headers-remove-many.md +5 -0
- package/repos/effect/.changeset/add-indexeddb-kvs-layer.md +5 -0
- package/repos/effect/.changeset/add-make-msgpack.md +5 -0
- package/repos/effect/.changeset/add-make-option.md +5 -0
- package/repos/effect/.changeset/add-missing-tx-modules.md +11 -0
- package/repos/effect/.changeset/add-newtype-module.md +5 -0
- package/repos/effect/.changeset/add-scalar-show-operation-id.md +5 -0
- package/repos/effect/.changeset/add-schedule-tap.md +5 -0
- package/repos/effect/.changeset/add-schema-annotate-encoded.md +5 -0
- package/repos/effect/.changeset/add-schema-array-ensure.md +5 -0
- package/repos/effect/.changeset/add-schema-bigdecimal.md +5 -0
- package/repos/effect/.changeset/add-schema-datetime.md +5 -0
- package/repos/effect/.changeset/add-schema-option-from-optional-nullor.md +5 -0
- package/repos/effect/.changeset/add-schema-option-from-undefined-nullish.md +5 -0
- package/repos/effect/.changeset/add-schema-string-encoding.md +5 -0
- package/repos/effect/.changeset/add-sql-pglite.md +5 -0
- package/repos/effect/.changeset/add-standard-jsdoc-rule.md +5 -0
- package/repos/effect/.changeset/add-stream-broadcastn.md +5 -0
- package/repos/effect/.changeset/add-unstable-encoding-export.md +5 -0
- package/repos/effect/.changeset/afraid-cobras-like.md +5 -0
- package/repos/effect/.changeset/ai-openai-config-field-leak.md +6 -0
- package/repos/effect/.changeset/ai-openai-file-nullable-fields.md +5 -0
- package/repos/effect/.changeset/anthropic-4-6-structured-output.md +5 -0
- package/repos/effect/.changeset/asyncresult-exhaustive.md +5 -0
- package/repos/effect/.changeset/atom-stream-error-type.md +5 -0
- package/repos/effect/.changeset/beige-paths-sort.md +5 -0
- package/repos/effect/.changeset/better-apples-nail.md +5 -0
- package/repos/effect/.changeset/better-rocks-arrive.md +5 -0
- package/repos/effect/.changeset/big-pans-look.md +5 -0
- package/repos/effect/.changeset/blue-dingos-greet.md +5 -0
- package/repos/effect/.changeset/blue-ligers-cheat.md +5 -0
- package/repos/effect/.changeset/blue-onions-smile.md +5 -0
- package/repos/effect/.changeset/blue-ravens-type.md +5 -0
- package/repos/effect/.changeset/blue-trams-kiss.md +7 -0
- package/repos/effect/.changeset/bold-chairs-yawn.md +5 -0
- package/repos/effect/.changeset/bold-planets-shout.md +30 -0
- package/repos/effect/.changeset/breezy-meals-see.md +5 -0
- package/repos/effect/.changeset/bright-bugs-bow.md +5 -0
- package/repos/effect/.changeset/bright-canyons-clean.md +5 -0
- package/repos/effect/.changeset/bright-dogs-fail.md +5 -0
- package/repos/effect/.changeset/bright-flags-stand.md +5 -0
- package/repos/effect/.changeset/bright-laws-teach.md +5 -0
- package/repos/effect/.changeset/bright-lemons-dance.md +5 -0
- package/repos/effect/.changeset/bright-planes-smash.md +5 -0
- package/repos/effect/.changeset/bright-rats-attend.md +5 -0
- package/repos/effect/.changeset/bright-toes-rush.md +5 -0
- package/repos/effect/.changeset/bumpy-boxes-teach.md +5 -0
- package/repos/effect/.changeset/busy-lions-sneeze.md +5 -0
- package/repos/effect/.changeset/busy-maps-attend.md +7 -0
- package/repos/effect/.changeset/calm-buckets-own.md +5 -0
- package/repos/effect/.changeset/calm-carrots-march.md +7 -0
- package/repos/effect/.changeset/calm-cars-rest.md +5 -0
- package/repos/effect/.changeset/calm-panthers-nail.md +5 -0
- package/repos/effect/.changeset/calm-seas-smile.md +5 -0
- package/repos/effect/.changeset/calm-squids-hug.md +5 -0
- package/repos/effect/.changeset/chatty-poets-type.md +5 -0
- package/repos/effect/.changeset/chilled-mice-wash.md +5 -0
- package/repos/effect/.changeset/chilly-pumas-rule.md +5 -0
- package/repos/effect/.changeset/chubby-buckets-feel.md +5 -0
- package/repos/effect/.changeset/chubby-parents-flow.md +5 -0
- package/repos/effect/.changeset/chubby-planets-fall.md +5 -0
- package/repos/effect/.changeset/clean-balloons-tan.md +5 -0
- package/repos/effect/.changeset/clean-bulldogs-care.md +5 -0
- package/repos/effect/.changeset/clean-dryers-sneeze.md +5 -0
- package/repos/effect/.changeset/clean-geese-work.md +5 -0
- package/repos/effect/.changeset/clean-goats-wave.md +5 -0
- package/repos/effect/.changeset/clean-needles-shake.md +23 -0
- package/repos/effect/.changeset/clean-tires-guess.md +5 -0
- package/repos/effect/.changeset/clear-spies-boil.md +5 -0
- package/repos/effect/.changeset/cli-help-choices.md +5 -0
- package/repos/effect/.changeset/cold-knives-lie.md +35 -0
- package/repos/effect/.changeset/cold-rooms-show.md +5 -0
- package/repos/effect/.changeset/cold-sloths-wave.md +5 -0
- package/repos/effect/.changeset/compact-json-schema-enum.md +25 -0
- package/repos/effect/.changeset/config-withdefault-eager.md +7 -0
- package/repos/effect/.changeset/config.json +24 -0
- package/repos/effect/.changeset/consolidate-encoding.md +5 -0
- package/repos/effect/.changeset/consolidate-sql-error.md +16 -0
- package/repos/effect/.changeset/crisp-seas-warn.md +5 -0
- package/repos/effect/.changeset/cuddly-rooms-bet.md +5 -0
- package/repos/effect/.changeset/curly-poems-talk.md +5 -0
- package/repos/effect/.changeset/curly-spies-relax.md +5 -0
- package/repos/effect/.changeset/curvy-apples-float.md +5 -0
- package/repos/effect/.changeset/custom-http-security-openapi-generator.md +5 -0
- package/repos/effect/.changeset/cute-heads-thank.md +5 -0
- package/repos/effect/.changeset/cyan-loops-grow.md +5 -0
- package/repos/effect/.changeset/cyan-radios-switch.md +5 -0
- package/repos/effect/.changeset/deep-rivers-spend.md +5 -0
- package/repos/effect/.changeset/dirty-lamps-trade.md +5 -0
- package/repos/effect/.changeset/dirty-laws-wear.md +5 -0
- package/repos/effect/.changeset/duration-temporal-object-input.md +7 -0
- package/repos/effect/.changeset/eager-coats-cheat.md +5 -0
- package/repos/effect/.changeset/early-birds-dream.md +5 -0
- package/repos/effect/.changeset/early-donuts-argue.md +5 -0
- package/repos/effect/.changeset/early-peaches-check.md +6 -0
- package/repos/effect/.changeset/eff-691-default-logger-ordering.md +5 -0
- package/repos/effect/.changeset/eff-693-rpcgroup-handler-deps.md +5 -0
- package/repos/effect/.changeset/eff-694-cli-completions-module.md +5 -0
- package/repos/effect/.changeset/eff-695-layer-mock-dual-api.md +5 -0
- package/repos/effect/.changeset/eff-697-rpcserialization-json-array-decode.md +5 -0
- package/repos/effect/.changeset/eff-698-rpcserialization-unreachable-branch.md +5 -0
- package/repos/effect/.changeset/eff-700-httpapi-middleware-errors.md +12 -0
- package/repos/effect/.changeset/eff-701-httpapierror-respondable.md +5 -0
- package/repos/effect/.changeset/eff-704-stream-merge-predicate.md +5 -0
- package/repos/effect/.changeset/eff-705-layer-tap-apis.md +5 -0
- package/repos/effect/.changeset/eff-706-servicemap-mutate.md +6 -0
- package/repos/effect/.changeset/eff-716-response-id-tracker-map.md +5 -0
- package/repos/effect/.changeset/eff-717-openai-socket-cancel.md +5 -0
- package/repos/effect/.changeset/eff-718-embedding-model-surface.md +13 -0
- package/repos/effect/.changeset/eff-725-fix-catch-jsdoc.md +5 -0
- package/repos/effect/.changeset/eff-726-model-dimensions.md +7 -0
- package/repos/effect/.changeset/eff-727-cli-help-alignment.md +5 -0
- package/repos/effect/.changeset/eff-730-language-model-incremental-fallback.md +5 -0
- package/repos/effect/.changeset/eff-736-cached-with-ttl.md +5 -0
- package/repos/effect/.changeset/eff-738-cron-prev.md +5 -0
- package/repos/effect/.changeset/eff-739-openai-function-call-done.md +5 -0
- package/repos/effect/.changeset/eff-740-missing-summary-parts.md +5 -0
- package/repos/effect/.changeset/eff-742-http-client-request-web.md +5 -0
- package/repos/effect/.changeset/eff-744-sqlite-migrator-lock.md +5 -0
- package/repos/effect/.changeset/eff-746-fixed-iteration-catchup.md +5 -0
- package/repos/effect/.changeset/eff-747-unify-effect.md +5 -0
- package/repos/effect/.changeset/eff-754-url-builder-any.md +6 -0
- package/repos/effect/.changeset/eff-755-references-core.md +5 -0
- package/repos/effect/.changeset/eff-769-select-text-highlight.md +5 -0
- package/repos/effect/.changeset/eff-774-mutable-list-append-all-empty-array.md +5 -0
- package/repos/effect/.changeset/eff-777-schema-make-effect.md +5 -0
- package/repos/effect/.changeset/eff-778-http-middleware-path-logger.md +5 -0
- package/repos/effect/.changeset/eff-779-keyvaluestore-layer-sql.md +5 -0
- package/repos/effect/.changeset/eff-780-layer-unify.md +5 -0
- package/repos/effect/.changeset/eff-781-fix-stream-toqueue-types.md +5 -0
- package/repos/effect/.changeset/eff-782-httpapi-status-literals.md +5 -0
- package/repos/effect/.changeset/eff-783-atom-http-api-errors.md +5 -0
- package/repos/effect/.changeset/eff-819-cluster-workflow-shard-groups.md +5 -0
- package/repos/effect/.changeset/eight-turkeys-own.md +7 -0
- package/repos/effect/.changeset/eighty-lies-deny.md +5 -0
- package/repos/effect/.changeset/eighty-poets-draw.md +9 -0
- package/repos/effect/.changeset/eighty-swans-scream.md +5 -0
- package/repos/effect/.changeset/eighty-teeth-sniff.md +5 -0
- package/repos/effect/.changeset/eleven-apes-share.md +5 -0
- package/repos/effect/.changeset/eleven-numbers-bake.md +5 -0
- package/repos/effect/.changeset/empty-gifts-beg.md +5 -0
- package/repos/effect/.changeset/empty-http-rpc-client.md +5 -0
- package/repos/effect/.changeset/eventlog-unencrypted.md +5 -0
- package/repos/effect/.changeset/expand-schema-filter-output.md +24 -0
- package/repos/effect/.changeset/export-schema-encode-keys-interface.md +7 -0
- package/repos/effect/.changeset/extract-semaphore-latch.md +10 -0
- package/repos/effect/.changeset/fair-bees-relax.md +5 -0
- package/repos/effect/.changeset/fair-buttons-share.md +7 -0
- package/repos/effect/.changeset/fair-cooks-stop.md +5 -0
- package/repos/effect/.changeset/fair-cups-train.md +5 -0
- package/repos/effect/.changeset/fair-dryers-speak.md +5 -0
- package/repos/effect/.changeset/fair-forks-shake.md +5 -0
- package/repos/effect/.changeset/fair-pandas-prove.md +5 -0
- package/repos/effect/.changeset/fair-pants-float.md +5 -0
- package/repos/effect/.changeset/fair-poems-visit.md +5 -0
- package/repos/effect/.changeset/famous-wolves-lead.md +5 -0
- package/repos/effect/.changeset/fancy-glasses-grow.md +5 -0
- package/repos/effect/.changeset/fast-times-camp.md +5 -0
- package/repos/effect/.changeset/few-birds-matter.md +5 -0
- package/repos/effect/.changeset/few-cougars-dig.md +5 -0
- package/repos/effect/.changeset/few-foxes-grin.md +5 -0
- package/repos/effect/.changeset/few-mirrors-pull.md +14 -0
- package/repos/effect/.changeset/few-socks-poke.md +5 -0
- package/repos/effect/.changeset/fiber-runtime-start-metrics.md +5 -0
- package/repos/effect/.changeset/fiery-jokes-care.md +5 -0
- package/repos/effect/.changeset/fiery-mammals-call.md +5 -0
- package/repos/effect/.changeset/fine-walls-decide.md +5 -0
- package/repos/effect/.changeset/first-success-of.md +5 -0
- package/repos/effect/.changeset/five-parents-relax.md +5 -0
- package/repos/effect/.changeset/five-worms-rhyme.md +5 -0
- package/repos/effect/.changeset/fix-1332.md +5 -0
- package/repos/effect/.changeset/fix-1917.md +11 -0
- package/repos/effect/.changeset/fix-1927.md +5 -0
- package/repos/effect/.changeset/fix-1940.md +7 -0
- package/repos/effect/.changeset/fix-1947.md +7 -0
- package/repos/effect/.changeset/fix-2002.md +5 -0
- package/repos/effect/.changeset/fix-2012.md +5 -0
- package/repos/effect/.changeset/fix-2015.md +5 -0
- package/repos/effect/.changeset/fix-2260.md +5 -0
- package/repos/effect/.changeset/fix-2268.md +5 -0
- package/repos/effect/.changeset/fix-2271.md +5 -0
- package/repos/effect/.changeset/fix-2384.md +7 -0
- package/repos/effect/.changeset/fix-ai-empty-params-structured-output.md +5 -0
- package/repos/effect/.changeset/fix-ai-text-toolkit-typing.md +5 -0
- package/repos/effect/.changeset/fix-catch-orelse-error-erasure.md +5 -0
- package/repos/effect/.changeset/fix-class-constructor-defaults.md +5 -0
- package/repos/effect/.changeset/fix-cli-mixed-global-flag-context.md +7 -0
- package/repos/effect/.changeset/fix-config-withDefault.md +5 -0
- package/repos/effect/.changeset/fix-config-withdefault-filter.md +7 -0
- package/repos/effect/.changeset/fix-datetime-gmt.md +5 -0
- package/repos/effect/.changeset/fix-devtools-flush-on-teardown.md +10 -0
- package/repos/effect/.changeset/fix-duration-symmetric-rounding.md +5 -0
- package/repos/effect/.changeset/fix-entity-manager-defect-replay.md +5 -0
- package/repos/effect/.changeset/fix-entity-proxy-rpc-handler-context.md +5 -0
- package/repos/effect/.changeset/fix-entity-proxy-server-path-params.md +5 -0
- package/repos/effect/.changeset/fix-from-readable-stream-cancel-defect.md +5 -0
- package/repos/effect/.changeset/fix-graph-undirected-traversal.md +5 -0
- package/repos/effect/.changeset/fix-has-interrupts-only-empty.md +5 -0
- package/repos/effect/.changeset/fix-hashmap-bit31-ordering.md +5 -0
- package/repos/effect/.changeset/fix-headers-proto-enumerability.md +5 -0
- package/repos/effect/.changeset/fix-http-incoming-message-parse-options.md +5 -0
- package/repos/effect/.changeset/fix-httpapi-endpoint-error-inference.md +5 -0
- package/repos/effect/.changeset/fix-httpapi-schema-types.md +5 -0
- package/repos/effect/.changeset/fix-httpapi-security-middleware-cache.md +5 -0
- package/repos/effect/.changeset/fix-is-json-dag.md +7 -0
- package/repos/effect/.changeset/fix-json-schema-anyof-oneof-siblings.md +5 -0
- package/repos/effect/.changeset/fix-json-schema-import-json.md +5 -0
- package/repos/effect/.changeset/fix-keepalive-blocked-timers.md +5 -0
- package/repos/effect/.changeset/fix-mcp-param-name-resolution.md +5 -0
- package/repos/effect/.changeset/fix-mermaid-escape-special-chars.md +5 -0
- package/repos/effect/.changeset/fix-mutable-list-filter-length.md +5 -0
- package/repos/effect/.changeset/fix-object-keyword-json-schema.md +5 -0
- package/repos/effect/.changeset/fix-openai-mcp-tool-names.md +5 -0
- package/repos/effect/.changeset/fix-openapi-generator-form-urlencoded.md +5 -0
- package/repos/effect/.changeset/fix-openapi-generator-swagger2openapi.md +5 -0
- package/repos/effect/.changeset/fix-openapi-preserve-multiple-response-content-types.md +5 -0
- package/repos/effect/.changeset/fix-openrouter-sparse-array.md +5 -0
- package/repos/effect/.changeset/fix-otel-logger-clock-skew.md +7 -0
- package/repos/effect/.changeset/fix-otel-logger-severity-number.md +20 -0
- package/repos/effect/.changeset/fix-queue-collect-duplication.md +5 -0
- package/repos/effect/.changeset/fix-random-string-seeds.md +5 -0
- package/repos/effect/.changeset/fix-ratelimiter-tokenbucket-redis-ttl.md +5 -0
- package/repos/effect/.changeset/fix-remainder-scientific-notation.md +5 -0
- package/repos/effect/.changeset/fix-request-resolver-pending-batches-leak.md +5 -0
- package/repos/effect/.changeset/fix-retry-transient-autocomplete.md +5 -0
- package/repos/effect/.changeset/fix-rpc-http-requestids-finalizer.md +5 -0
- package/repos/effect/.changeset/fix-rpc-json-id-edges.md +5 -0
- package/repos/effect/.changeset/fix-schedule-fixed-double-exec.md +9 -0
- package/repos/effect/.changeset/fix-schedule-reduce-sync-state.md +5 -0
- package/repos/effect/.changeset/fix-schema-arbitrary-exclusive-bounds.md +5 -0
- package/repos/effect/.changeset/fix-schema-defect-message.md +5 -0
- package/repos/effect/.changeset/fix-schema-encode-keys-property-keys.md +5 -0
- package/repos/effect/.changeset/fix-schema-encodekeys-class.md +5 -0
- package/repos/effect/.changeset/fix-schema-encodekeys-struct.md +5 -0
- package/repos/effect/.changeset/fix-schema-identifier-expected-message.md +5 -0
- package/repos/effect/.changeset/fix-schema-is-uuid.md +5 -0
- package/repos/effect/.changeset/fix-schema-option-non-schema-failures.md +17 -0
- package/repos/effect/.changeset/fix-schema-parser-checks.md +9 -0
- package/repos/effect/.changeset/fix-searchparam-initial-decode.md +5 -0
- package/repos/effect/.changeset/fix-serializable-wire-transfer.md +7 -0
- package/repos/effect/.changeset/fix-stream-grouped-within-flush.md +5 -0
- package/repos/effect/.changeset/fix-stream-run-for-each-while.md +5 -0
- package/repos/effect/.changeset/fix-stream-scan-effect.md +5 -0
- package/repos/effect/.changeset/fix-stream-scoped-scope.md +5 -0
- package/repos/effect/.changeset/fix-strip-approval-artifacts-multi-round.md +13 -0
- package/repos/effect/.changeset/fix-struct-utility-types-simplify.md +5 -0
- package/repos/effect/.changeset/fix-structwithrest-index-signatures.md +6 -0
- package/repos/effect/.changeset/fix-tagged-union-class-sentinels.md +5 -0
- package/repos/effect/.changeset/fix-tagged-union-match-unify.md +6 -0
- package/repos/effect/.changeset/fix-to-tagged-union-isanyof-custom-tags.md +10 -0
- package/repos/effect/.changeset/fix-tuple-with-rest-post-rest-index-drift.md +5 -0
- package/repos/effect/.changeset/fix-tuple-with-rest-post-rest-validation.md +5 -0
- package/repos/effect/.changeset/fix-types-voidifempty.md +5 -0
- package/repos/effect/.changeset/fix-void-response-encoding.md +5 -0
- package/repos/effect/.changeset/fix-workflow-proxy-rpc-handler-context.md +5 -0
- package/repos/effect/.changeset/flat-chicken-remain.md +5 -0
- package/repos/effect/.changeset/floppy-cows-spend.md +5 -0
- package/repos/effect/.changeset/floppy-items-admire.md +5 -0
- package/repos/effect/.changeset/floppy-pigs-kiss.md +5 -0
- package/repos/effect/.changeset/fluffy-meals-matter.md +5 -0
- package/repos/effect/.changeset/fluffy-pumas-push.md +5 -0
- package/repos/effect/.changeset/forked-memo-maps.md +6 -0
- package/repos/effect/.changeset/forty-hounds-cheer.md +5 -0
- package/repos/effect/.changeset/forty-otters-cry.md +5 -0
- package/repos/effect/.changeset/forty-rings-film.md +7 -0
- package/repos/effect/.changeset/forty-signs-stay.md +5 -0
- package/repos/effect/.changeset/forty-swans-divide.md +5 -0
- package/repos/effect/.changeset/forty-trees-pay.md +5 -0
- package/repos/effect/.changeset/four-papayas-bow.md +5 -0
- package/repos/effect/.changeset/four-points-repeat.md +5 -0
- package/repos/effect/.changeset/fresh-cats-smash.md +5 -0
- package/repos/effect/.changeset/fresh-emus-cheat.md +5 -0
- package/repos/effect/.changeset/fresh-monkeys-smoke.md +9 -0
- package/repos/effect/.changeset/fruity-houses-learn.md +6 -0
- package/repos/effect/.changeset/full-adults-double.md +5 -0
- package/repos/effect/.changeset/funny-crabs-hang.md +6 -0
- package/repos/effect/.changeset/funny-forks-move.md +5 -0
- package/repos/effect/.changeset/fuzzy-camels-hunt.md +5 -0
- package/repos/effect/.changeset/fuzzy-dodos-help.md +5 -0
- package/repos/effect/.changeset/fuzzy-lions-perform.md +5 -0
- package/repos/effect/.changeset/fuzzy-planets-sneeze.md +5 -0
- package/repos/effect/.changeset/gold-meteors-move.md +5 -0
- package/repos/effect/.changeset/gold-readers-hug.md +5 -0
- package/repos/effect/.changeset/gold-rings-start.md +5 -0
- package/repos/effect/.changeset/good-tools-work.md +7 -0
- package/repos/effect/.changeset/graph-algorithm-fixes.md +5 -0
- package/repos/effect/.changeset/great-trains-mate.md +5 -0
- package/repos/effect/.changeset/great-trams-report.md +5 -0
- package/repos/effect/.changeset/green-beds-unref.md +7 -0
- package/repos/effect/.changeset/green-chips-wash.md +5 -0
- package/repos/effect/.changeset/green-moons-smile.md +5 -0
- package/repos/effect/.changeset/green-pugs-play.md +5 -0
- package/repos/effect/.changeset/green-rings-prove.md +5 -0
- package/repos/effect/.changeset/happy-mirrors-dream.md +5 -0
- package/repos/effect/.changeset/heavy-loops-cut.md +5 -0
- package/repos/effect/.changeset/heavy-trams-fix.md +5 -0
- package/repos/effect/.changeset/hip-socks-travel.md +5 -0
- package/repos/effect/.changeset/honest-pens-thank.md +5 -0
- package/repos/effect/.changeset/honest-rivers-notice.md +5 -0
- package/repos/effect/.changeset/hot-taxis-fry.md +5 -0
- package/repos/effect/.changeset/httpapi-endpoint-relax-constraints.md +5 -0
- package/repos/effect/.changeset/httpapi-schema-service-types.md +6 -0
- package/repos/effect/.changeset/huge-moons-rhyme.md +5 -0
- package/repos/effect/.changeset/humble-pigs-dig.md +5 -0
- package/repos/effect/.changeset/icy-flies-cross.md +5 -0
- package/repos/effect/.changeset/itchy-radios-poke.md +5 -0
- package/repos/effect/.changeset/itchy-results-bet.md +5 -0
- package/repos/effect/.changeset/itchy-shrimps-deny.md +5 -0
- package/repos/effect/.changeset/itchy-toes-promise.md +5 -0
- package/repos/effect/.changeset/k8s-last-transition-null.md +5 -0
- package/repos/effect/.changeset/khaki-cats-learn.md +5 -0
- package/repos/effect/.changeset/khaki-melons-appear.md +5 -0
- package/repos/effect/.changeset/kind-hounds-float.md +5 -0
- package/repos/effect/.changeset/kind-windows-fall.md +5 -0
- package/repos/effect/.changeset/late-hotels-rule.md +5 -0
- package/repos/effect/.changeset/late-lamps-care.md +5 -0
- package/repos/effect/.changeset/late-rivers-applaud.md +5 -0
- package/repos/effect/.changeset/layer-map-dynamic-idle-ttl.md +5 -0
- package/repos/effect/.changeset/lazy-queens-rush.md +5 -0
- package/repos/effect/.changeset/lazy-recursive-forward-refs.md +5 -0
- package/repos/effect/.changeset/lazy-timers-exist.md +5 -0
- package/repos/effect/.changeset/legal-pants-drop.md +5 -0
- package/repos/effect/.changeset/lemon-taxis-sin.md +5 -0
- package/repos/effect/.changeset/light-kids-sneeze.md +5 -0
- package/repos/effect/.changeset/little-dryers-allow.md +7 -0
- package/repos/effect/.changeset/long-cameras-think.md +5 -0
- package/repos/effect/.changeset/lovely-cobras-change.md +5 -0
- package/repos/effect/.changeset/lovely-frogs-rescue.md +5 -0
- package/repos/effect/.changeset/lucky-buttons-jump.md +5 -0
- package/repos/effect/.changeset/lucky-phones-listen.md +5 -0
- package/repos/effect/.changeset/lucky-worms-type.md +5 -0
- package/repos/effect/.changeset/mean-dingos-share.md +5 -0
- package/repos/effect/.changeset/mean-trains-smash.md +5 -0
- package/repos/effect/.changeset/metal-parts-yell.md +5 -0
- package/repos/effect/.changeset/mighty-games-matter.md +5 -0
- package/repos/effect/.changeset/modern-uuid-guid-filter.md +5 -0
- package/repos/effect/.changeset/nasty-geese-grow.md +5 -0
- package/repos/effect/.changeset/neat-goats-wave.md +5 -0
- package/repos/effect/.changeset/neat-kings-chew.md +5 -0
- package/repos/effect/.changeset/neat-lions-rest.md +5 -0
- package/repos/effect/.changeset/neat-snails-wash.md +5 -0
- package/repos/effect/.changeset/neat-taxis-notice.md +5 -0
- package/repos/effect/.changeset/new-dogs-swim.md +5 -0
- package/repos/effect/.changeset/new-toes-stop.md +5 -0
- package/repos/effect/.changeset/ninety-geese-exist.md +5 -0
- package/repos/effect/.changeset/odd-boats-think.md +5 -0
- package/repos/effect/.changeset/odd-bulldogs-sleep.md +5 -0
- package/repos/effect/.changeset/odd-fans-glow.md +5 -0
- package/repos/effect/.changeset/odd-forks-talk.md +5 -0
- package/repos/effect/.changeset/odd-laws-draw.md +5 -0
- package/repos/effect/.changeset/odd-owls-smoke.md +5 -0
- package/repos/effect/.changeset/odd-socks-boil.md +5 -0
- package/repos/effect/.changeset/odd-suns-dance.md +5 -0
- package/repos/effect/.changeset/old-brooms-cry.md +5 -0
- package/repos/effect/.changeset/old-facts-stand.md +5 -0
- package/repos/effect/.changeset/old-mirrors-float.md +5 -0
- package/repos/effect/.changeset/olive-poems-visit.md +5 -0
- package/repos/effect/.changeset/open-hotels-remain.md +5 -0
- package/repos/effect/.changeset/openai-compat-nullable-tool-name.md +7 -0
- package/repos/effect/.changeset/openai-compat-reasoning.md +5 -0
- package/repos/effect/.changeset/otel-resource-env-precedence.md +5 -0
- package/repos/effect/.changeset/perfect-buckets-tickle.md +5 -0
- package/repos/effect/.changeset/petite-months-allow.md +6 -0
- package/repos/effect/.changeset/platform-crypto-service.md +9 -0
- package/repos/effect/.changeset/platform-node-shared-barrel.md +5 -0
- package/repos/effect/.changeset/plenty-moons-pull.md +5 -0
- package/repos/effect/.changeset/polite-brooms-tickle.md +5 -0
- package/repos/effect/.changeset/polite-pigs-speak.md +5 -0
- package/repos/effect/.changeset/polite-tables-kneel.md +5 -0
- package/repos/effect/.changeset/port-react-hydration.md +8 -0
- package/repos/effect/.changeset/pre.json +588 -0
- package/repos/effect/.changeset/public-deer-ring.md +5 -0
- package/repos/effect/.changeset/public-jeans-stop.md +5 -0
- package/repos/effect/.changeset/pubsub-publish-false.md +5 -0
- package/repos/effect/.changeset/puny-pens-clap.md +6 -0
- package/repos/effect/.changeset/purple-bars-prove.md +5 -0
- package/repos/effect/.changeset/purple-schools-float.md +5 -0
- package/repos/effect/.changeset/purple-turtles-draw.md +5 -0
- package/repos/effect/.changeset/quick-dragons-fix.md +5 -0
- package/repos/effect/.changeset/quick-falcons-travel.md +5 -0
- package/repos/effect/.changeset/quick-geese-relax.md +5 -0
- package/repos/effect/.changeset/quick-lamps-dig.md +5 -0
- package/repos/effect/.changeset/quick-lizards-fall.md +5 -0
- package/repos/effect/.changeset/quick-trees-join.md +5 -0
- package/repos/effect/.changeset/quiet-carpets-grin.md +5 -0
- package/repos/effect/.changeset/quiet-files-hunt.md +5 -0
- package/repos/effect/.changeset/quiet-lamps-jam.md +5 -0
- package/repos/effect/.changeset/quiet-radios-wave.md +5 -0
- package/repos/effect/.changeset/quiet-redis-scripts.md +5 -0
- package/repos/effect/.changeset/ready-olives-divide.md +5 -0
- package/repos/effect/.changeset/real-trains-ring.md +5 -0
- package/repos/effect/.changeset/red-pigs-repair.md +5 -0
- package/repos/effect/.changeset/redacted-representation-options.md +7 -0
- package/repos/effect/.changeset/refactor-cli-global-flags.md +27 -0
- package/repos/effect/.changeset/refactor-config-provider.md +23 -0
- package/repos/effect/.changeset/refactor-representation-references.md +5 -0
- package/repos/effect/.changeset/remove-effect-transactionwith.md +5 -0
- package/repos/effect/.changeset/remove-http-span-counter.md +5 -0
- package/repos/effect/.changeset/remove-nullor.md +5 -0
- package/repos/effect/.changeset/remove-openapi-fromapi-options.md +7 -0
- package/repos/effect/.changeset/remove-types-mergerecord.md +5 -0
- package/repos/effect/.changeset/remove-unused-utils-apis.md +5 -0
- package/repos/effect/.changeset/rename-rebuild-out.md +5 -0
- package/repos/effect/.changeset/restore-schema-parse-options.md +5 -0
- package/repos/effect/.changeset/rich-dots-push.md +5 -0
- package/repos/effect/.changeset/rich-hoops-nail.md +5 -0
- package/repos/effect/.changeset/rich-sloths-draw.md +5 -0
- package/repos/effect/.changeset/ripe-lies-battle.md +5 -0
- package/repos/effect/.changeset/rpc-middleware-provides-fix.md +5 -0
- package/repos/effect/.changeset/scalar-custom-fetch.md +5 -0
- package/repos/effect/.changeset/schema-as-class.md +17 -0
- package/repos/effect/.changeset/schema-asserts-signature.md +5 -0
- package/repos/effect/.changeset/schema-clean-up-additionalProperties.md +7 -0
- package/repos/effect/.changeset/schema-datetime-utc-from-string.md +5 -0
- package/repos/effect/.changeset/schema-decoding-defaults-services.md +7 -0
- package/repos/effect/.changeset/schema-defaults-issue-channel.md +7 -0
- package/repos/effect/.changeset/schema-dollar-prefix.md +5 -0
- package/repos/effect/.changeset/schema-missing-self-generic.md +5 -0
- package/repos/effect/.changeset/schema-ordered-arbitrary-constraints.md +12 -0
- package/repos/effect/.changeset/schema-parser-adapter-errors.md +5 -0
- package/repos/effect/.changeset/schema-refactor-toCodecJson.md +5 -0
- package/repos/effect/.changeset/schema-remove-annotate-in.md +5 -0
- package/repos/effect/.changeset/schema-rename-makeUnsafe-to-make.md +7 -0
- package/repos/effect/.changeset/schema-rename-parser-makeUnsafe.md +5 -0
- package/repos/effect/.changeset/schema-result-combinators.md +5 -0
- package/repos/effect/.changeset/schema-struct-simplify.md +5 -0
- package/repos/effect/.changeset/seven-mugs-marry.md +5 -0
- package/repos/effect/.changeset/shaggy-birds-stay.md +5 -0
- package/repos/effect/.changeset/shaggy-cities-push.md +5 -0
- package/repos/effect/.changeset/shaggy-numbers-accept.md +5 -0
- package/repos/effect/.changeset/sharp-emus-applaud.md +5 -0
- package/repos/effect/.changeset/sharp-goats-wink.md +5 -0
- package/repos/effect/.changeset/sharp-pandas-care.md +5 -0
- package/repos/effect/.changeset/sharp-peas-march.md +5 -0
- package/repos/effect/.changeset/sharp-rules-draw.md +5 -0
- package/repos/effect/.changeset/sharp-singers-sort.md +5 -0
- package/repos/effect/.changeset/shiny-trains-hug.md +5 -0
- package/repos/effect/.changeset/short-cows-relate.md +5 -0
- package/repos/effect/.changeset/short-foxes-admire.md +5 -0
- package/repos/effect/.changeset/shy-cycles-flow.md +5 -0
- package/repos/effect/.changeset/shy-geckos-sniff.md +30 -0
- package/repos/effect/.changeset/silent-geckos-matter.md +5 -0
- package/repos/effect/.changeset/silent-needles-design.md +6 -0
- package/repos/effect/.changeset/silent-plants-matter.md +8 -0
- package/repos/effect/.changeset/silent-spoons-stare.md +5 -0
- package/repos/effect/.changeset/silly-loops-tickle.md +5 -0
- package/repos/effect/.changeset/silver-bulk-indexeddb.md +5 -0
- package/repos/effect/.changeset/silver-emus-smoke.md +5 -0
- package/repos/effect/.changeset/silver-kings-poke.md +5 -0
- package/repos/effect/.changeset/silver-snails-sqlite.md +17 -0
- package/repos/effect/.changeset/silver-wings-watch.md +5 -0
- package/repos/effect/.changeset/six-cups-taste.md +5 -0
- package/repos/effect/.changeset/sixty-mails-shout.md +5 -0
- package/repos/effect/.changeset/sixty-socks-yell.md +5 -0
- package/repos/effect/.changeset/slimy-planets-divide.md +5 -0
- package/repos/effect/.changeset/slimy-turtles-juggle.md +5 -0
- package/repos/effect/.changeset/slow-beans-battle.md +28 -0
- package/repos/effect/.changeset/slow-berries-enjoy.md +5 -0
- package/repos/effect/.changeset/small-bugs-hunt.md +5 -0
- package/repos/effect/.changeset/small-crabs-care.md +9 -0
- package/repos/effect/.changeset/small-pets-sit.md +6 -0
- package/repos/effect/.changeset/smart-ducks-jump.md +6 -0
- package/repos/effect/.changeset/smart-pillows-buy.md +6 -0
- package/repos/effect/.changeset/smart-timers-fly.md +5 -0
- package/repos/effect/.changeset/smart-tips-sort.md +5 -0
- package/repos/effect/.changeset/social-pumas-prove.md +5 -0
- package/repos/effect/.changeset/soft-comics-wink.md +5 -0
- package/repos/effect/.changeset/soft-delete-sqlmodel.md +5 -0
- package/repos/effect/.changeset/soft-seals-allow.md +5 -0
- package/repos/effect/.changeset/solid-cougars-attack.md +5 -0
- package/repos/effect/.changeset/solid-doors-ring.md +5 -0
- package/repos/effect/.changeset/solid-items-tease.md +5 -0
- package/repos/effect/.changeset/solid-towns-smoke.md +5 -0
- package/repos/effect/.changeset/sour-canyons-rescue.md +5 -0
- package/repos/effect/.changeset/sparkly-bears-act.md +5 -0
- package/repos/effect/.changeset/sparkly-coins-sit.md +5 -0
- package/repos/effect/.changeset/spotty-comics-fry.md +5 -0
- package/repos/effect/.changeset/sql-migrator-mjs-mts.md +5 -0
- package/repos/effect/.changeset/stale-dots-tell.md +5 -0
- package/repos/effect/.changeset/stale-snakes-know.md +5 -0
- package/repos/effect/.changeset/strict-areas-end.md +5 -0
- package/repos/effect/.changeset/strict-buckets-hug.md +8 -0
- package/repos/effect/.changeset/strip-resolved-approvals.md +5 -0
- package/repos/effect/.changeset/strong-balloons-tickle.md +5 -0
- package/repos/effect/.changeset/strong-bees-queue.md +5 -0
- package/repos/effect/.changeset/struct-record.md +5 -0
- package/repos/effect/.changeset/sunny-ads-hang.md +5 -0
- package/repos/effect/.changeset/sunny-bikes-sleep.md +5 -0
- package/repos/effect/.changeset/sunny-rooms-invent.md +5 -0
- package/repos/effect/.changeset/sweet-donuts-bet.md +5 -0
- package/repos/effect/.changeset/sweet-hotels-give.md +5 -0
- package/repos/effect/.changeset/sweet-views-learn.md +5 -0
- package/repos/effect/.changeset/swift-spiders-unpack.md +5 -0
- package/repos/effect/.changeset/swift-symbols-stand.md +5 -0
- package/repos/effect/.changeset/tagged-error-class-optional-empty-props.md +5 -0
- package/repos/effect/.changeset/tall-hairs-return.md +5 -0
- package/repos/effect/.changeset/tall-mails-listen.md +5 -0
- package/repos/effect/.changeset/tall-queens-cheer.md +5 -0
- package/repos/effect/.changeset/tall-wombats-wave.md +5 -0
- package/repos/effect/.changeset/tangy-colts-lose.md +5 -0
- package/repos/effect/.changeset/tasty-comics-send.md +5 -0
- package/repos/effect/.changeset/ten-kings-fry.md +5 -0
- package/repos/effect/.changeset/thick-pandas-wait.md +5 -0
- package/repos/effect/.changeset/thin-ducks-wonder.md +5 -0
- package/repos/effect/.changeset/thirty-ducks-go.md +5 -0
- package/repos/effect/.changeset/thirty-pans-love.md +5 -0
- package/repos/effect/.changeset/three-corners-sort.md +5 -0
- package/repos/effect/.changeset/three-ravens-jam.md +5 -0
- package/repos/effect/.changeset/three-tomatoes-wave.md +5 -0
- package/repos/effect/.changeset/tidy-foxes-own.md +5 -0
- package/repos/effect/.changeset/tidy-icons-glow.md +5 -0
- package/repos/effect/.changeset/tidy-stacks-encode.md +5 -0
- package/repos/effect/.changeset/tidy-stars-drive.md +5 -0
- package/repos/effect/.changeset/tiny-buckets-wave.md +5 -0
- package/repos/effect/.changeset/tiny-lilies-flash.md +5 -0
- package/repos/effect/.changeset/tiny-rabbits-smile.md +5 -0
- package/repos/effect/.changeset/tocodecjson-return-json-type.md +10 -0
- package/repos/effect/.changeset/tool-get-json-schema-tests.md +5 -0
- package/repos/effect/.changeset/true-actors-battle.md +5 -0
- package/repos/effect/.changeset/twenty-buttons-cheer.md +5 -0
- package/repos/effect/.changeset/two-roses-double.md +5 -0
- package/repos/effect/.changeset/unify-error-defect-stack-options.md +23 -0
- package/repos/effect/.changeset/update-schema-arbitrary-report.md +22 -0
- package/repos/effect/.changeset/upset-colts-stick.md +5 -0
- package/repos/effect/.changeset/vast-bananas-send.md +5 -0
- package/repos/effect/.changeset/vast-deserts-travel.md +5 -0
- package/repos/effect/.changeset/violet-peaches-feel.md +5 -0
- package/repos/effect/.changeset/vitest-layer-top-level-options.md +5 -0
- package/repos/effect/.changeset/wacky-grapes-poke.md +5 -0
- package/repos/effect/.changeset/wacky-rice-add.md +5 -0
- package/repos/effect/.changeset/warm-dolls-brake.md +5 -0
- package/repos/effect/.changeset/warm-friends-tie.md +5 -0
- package/repos/effect/.changeset/warm-snails-shop.md +7 -0
- package/repos/effect/.changeset/wet-news-invent.md +5 -0
- package/repos/effect/.changeset/wild-readers-clean.md +5 -0
- package/repos/effect/.changeset/wild-suns-bearer-space.md +5 -0
- package/repos/effect/.changeset/wise-ants-wave.md +6 -0
- package/repos/effect/.changeset/wise-flags-shift.md +22 -0
- package/repos/effect/.changeset/wise-oranges-stay.md +5 -0
- package/repos/effect/.changeset/witty-lobsters-share.md +5 -0
- package/repos/effect/.changeset/yellow-adults-study.md +5 -0
- package/repos/effect/.changeset/yellow-clocks-dance.md +5 -0
- package/repos/effect/.changeset/yellow-dingos-jump.md +5 -0
- package/repos/effect/.changeset/young-doors-change.md +5 -0
- package/repos/effect/.envrc +1 -0
- package/repos/effect/.github/actions/setup/action.yaml +33 -0
- package/repos/effect/.github/workflows/ai-codegen.yml +66 -0
- package/repos/effect/.github/workflows/bundle-comment.yml +72 -0
- package/repos/effect/.github/workflows/check.yml +195 -0
- package/repos/effect/.github/workflows/release.yml +47 -0
- package/repos/effect/.github/workflows/snapshot.yml +34 -0
- package/repos/effect/.oxlintrc.json +25 -0
- package/repos/effect/.patterns/effect.md +102 -0
- package/repos/effect/.patterns/jsdoc.md +53 -0
- package/repos/effect/.patterns/testing.md +44 -0
- package/repos/effect/.specs/README.md +2 -0
- package/repos/effect/.vscode/extensions.json +6 -0
- package/repos/effect/.vscode/settings.json +44 -0
- package/repos/effect/AGENTS.md +139 -0
- package/repos/effect/LICENSE +21 -0
- package/repos/effect/LLMS.md +343 -0
- package/repos/effect/MIGRATION.md +83 -0
- package/repos/effect/README.md +3 -0
- package/repos/effect/TODOS.md +28 -0
- package/repos/effect/ai-docs/README.md +44 -0
- package/repos/effect/ai-docs/package.json +36 -0
- package/repos/effect/ai-docs/src/01_effect/01_basics/01_effect-gen.ts +30 -0
- package/repos/effect/ai-docs/src/01_effect/01_basics/02_effect-fn.ts +39 -0
- package/repos/effect/ai-docs/src/01_effect/01_basics/10_creating-effects.ts +74 -0
- package/repos/effect/ai-docs/src/01_effect/01_basics/index.md +5 -0
- package/repos/effect/ai-docs/src/01_effect/02_services/01_service.ts +45 -0
- package/repos/effect/ai-docs/src/01_effect/02_services/10_reference.ts +10 -0
- package/repos/effect/ai-docs/src/01_effect/02_services/20_layer-composition.ts +70 -0
- package/repos/effect/ai-docs/src/01_effect/02_services/20_layer-unwrap.ts +66 -0
- package/repos/effect/ai-docs/src/01_effect/02_services/index.md +5 -0
- package/repos/effect/ai-docs/src/01_effect/03_errors/01_error-handling.ts +30 -0
- package/repos/effect/ai-docs/src/01_effect/03_errors/10_catch-tags.ts +24 -0
- package/repos/effect/ai-docs/src/01_effect/03_errors/20_reason-errors.ts +64 -0
- package/repos/effect/ai-docs/src/01_effect/03_errors/index.md +1 -0
- package/repos/effect/ai-docs/src/01_effect/04_resources/10_acquire-release.ts +105 -0
- package/repos/effect/ai-docs/src/01_effect/04_resources/20_layer-side-effects.ts +31 -0
- package/repos/effect/ai-docs/src/01_effect/04_resources/30_layer-map.ts +86 -0
- package/repos/effect/ai-docs/src/01_effect/04_resources/index.md +3 -0
- package/repos/effect/ai-docs/src/01_effect/05_running/10_run-main.ts +30 -0
- package/repos/effect/ai-docs/src/01_effect/05_running/20_layer-launch.ts +27 -0
- package/repos/effect/ai-docs/src/01_effect/05_running/index.md +1 -0
- package/repos/effect/ai-docs/src/01_effect/06_pubsub/10_pubsub.ts +56 -0
- package/repos/effect/ai-docs/src/01_effect/06_pubsub/index.md +3 -0
- package/repos/effect/ai-docs/src/02_stream/10_creating-streams.ts +103 -0
- package/repos/effect/ai-docs/src/02_stream/20_consuming-streams.ts +137 -0
- package/repos/effect/ai-docs/src/02_stream/30_encoding.ts +165 -0
- package/repos/effect/ai-docs/src/02_stream/index.md +4 -0
- package/repos/effect/ai-docs/src/03_integration/10_managed-runtime.ts +129 -0
- package/repos/effect/ai-docs/src/03_integration/index.md +5 -0
- package/repos/effect/ai-docs/src/05_batching/10_request-resolver.ts +89 -0
- package/repos/effect/ai-docs/src/05_batching/index.md +3 -0
- package/repos/effect/ai-docs/src/06_schedule/10_schedules.ts +102 -0
- package/repos/effect/ai-docs/src/06_schedule/index.md +3 -0
- package/repos/effect/ai-docs/src/07_datetime/10_creating-and-formatting.ts +30 -0
- package/repos/effect/ai-docs/src/07_datetime/20_time-zones.ts +44 -0
- package/repos/effect/ai-docs/src/07_datetime/index.md +5 -0
- package/repos/effect/ai-docs/src/08_observability/10_logging.ts +66 -0
- package/repos/effect/ai-docs/src/08_observability/20_otlp-tracing.ts +95 -0
- package/repos/effect/ai-docs/src/08_observability/index.md +7 -0
- package/repos/effect/ai-docs/src/09_testing/10_effect-tests.ts +55 -0
- package/repos/effect/ai-docs/src/09_testing/20_layer-tests.ts +138 -0
- package/repos/effect/ai-docs/src/09_testing/index.md +1 -0
- package/repos/effect/ai-docs/src/50_http-client/10_basics.ts +102 -0
- package/repos/effect/ai-docs/src/50_http-client/index.md +3 -0
- package/repos/effect/ai-docs/src/51_http-server/10_basics.ts +116 -0
- package/repos/effect/ai-docs/src/51_http-server/fixtures/api/Api.ts +14 -0
- package/repos/effect/ai-docs/src/51_http-server/fixtures/api/Authorization.ts +36 -0
- package/repos/effect/ai-docs/src/51_http-server/fixtures/api/System.ts +10 -0
- package/repos/effect/ai-docs/src/51_http-server/fixtures/api/Users.ts +91 -0
- package/repos/effect/ai-docs/src/51_http-server/fixtures/domain/User.ts +12 -0
- package/repos/effect/ai-docs/src/51_http-server/fixtures/domain/UserErrors.ts +22 -0
- package/repos/effect/ai-docs/src/51_http-server/fixtures/server/Authorization.ts +36 -0
- package/repos/effect/ai-docs/src/51_http-server/fixtures/server/Users/http.ts +71 -0
- package/repos/effect/ai-docs/src/51_http-server/fixtures/server/Users.ts +62 -0
- package/repos/effect/ai-docs/src/51_http-server/index.md +3 -0
- package/repos/effect/ai-docs/src/60_child-process/10_working-with-child-processes.ts +117 -0
- package/repos/effect/ai-docs/src/60_child-process/index.md +3 -0
- package/repos/effect/ai-docs/src/70_cli/10_basics.ts +136 -0
- package/repos/effect/ai-docs/src/70_cli/index.md +5 -0
- package/repos/effect/ai-docs/src/71_ai/10_language-model.ts +156 -0
- package/repos/effect/ai-docs/src/71_ai/20_tools.ts +226 -0
- package/repos/effect/ai-docs/src/71_ai/30_chat.ts +158 -0
- package/repos/effect/ai-docs/src/71_ai/fixtures/domain/LaunchPlan.ts +9 -0
- package/repos/effect/ai-docs/src/71_ai/index.md +5 -0
- package/repos/effect/ai-docs/src/80_cluster/10_entities.ts +97 -0
- package/repos/effect/ai-docs/src/80_cluster/index.md +4 -0
- package/repos/effect/ai-docs/src/index.md +12 -0
- package/repos/effect/ai-docs/tsconfig.json +24 -0
- package/repos/effect/cookbooks/schedule.md +3507 -0
- package/repos/effect/deno.json +33 -0
- package/repos/effect/docker-compose.yaml +18 -0
- package/repos/effect/dprint.json +32 -0
- package/repos/effect/flake.lock +27 -0
- package/repos/effect/flake.nix +24 -0
- package/repos/effect/jsdocs.config.json +16 -0
- package/repos/effect/migration/cause.md +163 -0
- package/repos/effect/migration/equality.md +72 -0
- package/repos/effect/migration/error-handling.md +106 -0
- package/repos/effect/migration/fiber-keep-alive.md +74 -0
- package/repos/effect/migration/fiberref.md +109 -0
- package/repos/effect/migration/forking.md +94 -0
- package/repos/effect/migration/generators.md +32 -0
- package/repos/effect/migration/layer-memoization.md +98 -0
- package/repos/effect/migration/runtime.md +88 -0
- package/repos/effect/migration/schema.md +1032 -0
- package/repos/effect/migration/scope.md +50 -0
- package/repos/effect/migration/services.md +235 -0
- package/repos/effect/migration/v3-to-v4.md +421 -0
- package/repos/effect/migration/yieldable.md +173 -0
- package/repos/effect/package.json +104 -0
- package/repos/effect/packages/ai/anthropic/CHANGELOG.md +611 -0
- package/repos/effect/packages/ai/anthropic/codegen.yml +63 -0
- package/repos/effect/packages/ai/anthropic/docgen.json +26 -0
- package/repos/effect/packages/ai/anthropic/package.json +67 -0
- package/repos/effect/packages/ai/anthropic/src/AnthropicClient.ts +432 -0
- package/repos/effect/packages/ai/anthropic/src/AnthropicConfig.ts +84 -0
- package/repos/effect/packages/ai/anthropic/src/AnthropicError.ts +212 -0
- package/repos/effect/packages/ai/anthropic/src/AnthropicLanguageModel.ts +3098 -0
- package/repos/effect/packages/ai/anthropic/src/AnthropicTelemetry.ts +132 -0
- package/repos/effect/packages/ai/anthropic/src/AnthropicTool.ts +2512 -0
- package/repos/effect/packages/ai/anthropic/src/Generated.ts +12600 -0
- package/repos/effect/packages/ai/anthropic/src/index.ts +40 -0
- package/repos/effect/packages/ai/anthropic/src/internal/errors.ts +370 -0
- package/repos/effect/packages/ai/anthropic/src/internal/utilities.ts +26 -0
- package/repos/effect/packages/ai/anthropic/test/AnthropicLanguageModel.test.ts +300 -0
- package/repos/effect/packages/ai/anthropic/tsconfig.json +8 -0
- package/repos/effect/packages/ai/anthropic/vitest.config.ts +6 -0
- package/repos/effect/packages/ai/openai/CHANGELOG.md +668 -0
- package/repos/effect/packages/ai/openai/codegen.yaml +41 -0
- package/repos/effect/packages/ai/openai/docgen.json +24 -0
- package/repos/effect/packages/ai/openai/package.json +67 -0
- package/repos/effect/packages/ai/openai/src/Generated.ts +35774 -0
- package/repos/effect/packages/ai/openai/src/OpenAiClient.ts +730 -0
- package/repos/effect/packages/ai/openai/src/OpenAiClientGenerated.ts +202 -0
- package/repos/effect/packages/ai/openai/src/OpenAiConfig.ts +93 -0
- package/repos/effect/packages/ai/openai/src/OpenAiEmbeddingModel.ts +258 -0
- package/repos/effect/packages/ai/openai/src/OpenAiError.ts +242 -0
- package/repos/effect/packages/ai/openai/src/OpenAiLanguageModel.ts +3133 -0
- package/repos/effect/packages/ai/openai/src/OpenAiSchema.ts +1286 -0
- package/repos/effect/packages/ai/openai/src/OpenAiTelemetry.ts +162 -0
- package/repos/effect/packages/ai/openai/src/OpenAiTool.ts +342 -0
- package/repos/effect/packages/ai/openai/src/index.ts +55 -0
- package/repos/effect/packages/ai/openai/src/internal/errors.ts +349 -0
- package/repos/effect/packages/ai/openai/src/internal/utilities.ts +33 -0
- package/repos/effect/packages/ai/openai/test/OpenAiClient.test.ts +798 -0
- package/repos/effect/packages/ai/openai/test/OpenAiEmbeddingModel.test.ts +289 -0
- package/repos/effect/packages/ai/openai/test/OpenAiLanguageModel.test.ts +1528 -0
- package/repos/effect/packages/ai/openai/test/OpenAiSchema.test.ts +273 -0
- package/repos/effect/packages/ai/openai/tsconfig.json +8 -0
- package/repos/effect/packages/ai/openai/vitest.config.ts +6 -0
- package/repos/effect/packages/ai/openai-compat/CHANGELOG.md +626 -0
- package/repos/effect/packages/ai/openai-compat/docgen.json +24 -0
- package/repos/effect/packages/ai/openai-compat/package.json +69 -0
- package/repos/effect/packages/ai/openai-compat/src/OpenAiClient.ts +1221 -0
- package/repos/effect/packages/ai/openai-compat/src/OpenAiConfig.ts +87 -0
- package/repos/effect/packages/ai/openai-compat/src/OpenAiEmbeddingModel.ts +254 -0
- package/repos/effect/packages/ai/openai-compat/src/OpenAiError.ts +178 -0
- package/repos/effect/packages/ai/openai-compat/src/OpenAiLanguageModel.ts +1951 -0
- package/repos/effect/packages/ai/openai-compat/src/OpenAiTelemetry.ts +164 -0
- package/repos/effect/packages/ai/openai-compat/src/index.ts +35 -0
- package/repos/effect/packages/ai/openai-compat/src/internal/errors.ts +327 -0
- package/repos/effect/packages/ai/openai-compat/src/internal/utilities.ts +33 -0
- package/repos/effect/packages/ai/openai-compat/test/OpenAiClient.test.ts +474 -0
- package/repos/effect/packages/ai/openai-compat/test/OpenAiEmbeddingModel.test.ts +216 -0
- package/repos/effect/packages/ai/openai-compat/test/OpenAiLanguageModel.test.ts +1505 -0
- package/repos/effect/packages/ai/openai-compat/tsconfig.json +8 -0
- package/repos/effect/packages/ai/openai-compat/vitest.config.ts +6 -0
- package/repos/effect/packages/ai/openrouter/CHANGELOG.md +607 -0
- package/repos/effect/packages/ai/openrouter/codegen.yml +35 -0
- package/repos/effect/packages/ai/openrouter/docgen.json +24 -0
- package/repos/effect/packages/ai/openrouter/package.json +67 -0
- package/repos/effect/packages/ai/openrouter/src/Generated.ts +10028 -0
- package/repos/effect/packages/ai/openrouter/src/OpenRouterClient.ts +357 -0
- package/repos/effect/packages/ai/openrouter/src/OpenRouterConfig.ts +99 -0
- package/repos/effect/packages/ai/openrouter/src/OpenRouterError.ts +225 -0
- package/repos/effect/packages/ai/openrouter/src/OpenRouterLanguageModel.ts +1796 -0
- package/repos/effect/packages/ai/openrouter/src/index.ts +30 -0
- package/repos/effect/packages/ai/openrouter/src/internal/errors.ts +375 -0
- package/repos/effect/packages/ai/openrouter/src/internal/utilities.ts +92 -0
- package/repos/effect/packages/ai/openrouter/tsconfig.json +10 -0
- package/repos/effect/packages/ai/openrouter/vitest.config.ts +6 -0
- package/repos/effect/packages/atom/react/CHANGELOG.md +599 -0
- package/repos/effect/packages/atom/react/LICENSE +21 -0
- package/repos/effect/packages/atom/react/README.md +7 -0
- package/repos/effect/packages/atom/react/docgen.json +25 -0
- package/repos/effect/packages/atom/react/package.json +79 -0
- package/repos/effect/packages/atom/react/src/Hooks.ts +476 -0
- package/repos/effect/packages/atom/react/src/ReactHydration.ts +109 -0
- package/repos/effect/packages/atom/react/src/RegistryContext.ts +108 -0
- package/repos/effect/packages/atom/react/src/ScopedAtom.ts +151 -0
- package/repos/effect/packages/atom/react/src/index.ts +23 -0
- package/repos/effect/packages/atom/react/test/index.test.tsx +650 -0
- package/repos/effect/packages/atom/react/tsconfig.json +8 -0
- package/repos/effect/packages/atom/react/vitest.config.ts +9 -0
- package/repos/effect/packages/atom/react/vitest.setup.ts +8 -0
- package/repos/effect/packages/atom/solid/CHANGELOG.md +595 -0
- package/repos/effect/packages/atom/solid/LICENSE +21 -0
- package/repos/effect/packages/atom/solid/README.md +7 -0
- package/repos/effect/packages/atom/solid/docgen.json +26 -0
- package/repos/effect/packages/atom/solid/package.json +72 -0
- package/repos/effect/packages/atom/solid/src/Hooks.ts +359 -0
- package/repos/effect/packages/atom/solid/src/RegistryContext.ts +80 -0
- package/repos/effect/packages/atom/solid/src/index.ts +13 -0
- package/repos/effect/packages/atom/solid/test/index.test.tsx +296 -0
- package/repos/effect/packages/atom/solid/tsconfig.json +8 -0
- package/repos/effect/packages/atom/solid/vitest.config.ts +15 -0
- package/repos/effect/packages/atom/solid/vitest.setup.ts +8 -0
- package/repos/effect/packages/atom/vue/CHANGELOG.md +593 -0
- package/repos/effect/packages/atom/vue/LICENSE +21 -0
- package/repos/effect/packages/atom/vue/README.md +7 -0
- package/repos/effect/packages/atom/vue/docgen.json +24 -0
- package/repos/effect/packages/atom/vue/package.json +68 -0
- package/repos/effect/packages/atom/vue/src/index.ts +211 -0
- package/repos/effect/packages/atom/vue/test/index.test.ts +5 -0
- package/repos/effect/packages/atom/vue/tsconfig.json +14 -0
- package/repos/effect/packages/atom/vue/vitest.config.ts +8 -0
- package/repos/effect/packages/effect/CHANGELOG.md +1607 -0
- package/repos/effect/packages/effect/CONFIG.md +690 -0
- package/repos/effect/packages/effect/HTTPAPI.md +3213 -0
- package/repos/effect/packages/effect/LICENSE +21 -0
- package/repos/effect/packages/effect/MCP.md +369 -0
- package/repos/effect/packages/effect/OPTIC.md +620 -0
- package/repos/effect/packages/effect/README.md +53 -0
- package/repos/effect/packages/effect/SCHEMA.md +7284 -0
- package/repos/effect/packages/effect/benchmark/schema/Enums.ts +40 -0
- package/repos/effect/packages/effect/benchmark/schema/Optic.ts +79 -0
- package/repos/effect/packages/effect/benchmark/schema/array.ts +74 -0
- package/repos/effect/packages/effect/benchmark/schema/filter.ts +74 -0
- package/repos/effect/packages/effect/benchmark/schema/object.ts +82 -0
- package/repos/effect/packages/effect/benchmark/schema/tagged-union.ts +69 -0
- package/repos/effect/packages/effect/benchmark/schema/transformation.ts +91 -0
- package/repos/effect/packages/effect/benchmark/stream/splitLines.ts +46 -0
- package/repos/effect/packages/effect/docgen.json +38 -0
- package/repos/effect/packages/effect/package.json +127 -0
- package/repos/effect/packages/effect/src/Array.ts +4908 -0
- package/repos/effect/packages/effect/src/BigDecimal.ts +1943 -0
- package/repos/effect/packages/effect/src/BigInt.ts +1029 -0
- package/repos/effect/packages/effect/src/Boolean.ts +481 -0
- package/repos/effect/packages/effect/src/Brand.ts +318 -0
- package/repos/effect/packages/effect/src/Cache.ts +1295 -0
- package/repos/effect/packages/effect/src/Cause.ts +1939 -0
- package/repos/effect/packages/effect/src/Channel.ts +8615 -0
- package/repos/effect/packages/effect/src/ChannelSchema.ts +308 -0
- package/repos/effect/packages/effect/src/Chunk.ts +2976 -0
- package/repos/effect/packages/effect/src/Clock.ts +194 -0
- package/repos/effect/packages/effect/src/Combiner.ts +316 -0
- package/repos/effect/packages/effect/src/Config.ts +1416 -0
- package/repos/effect/packages/effect/src/ConfigProvider.ts +1159 -0
- package/repos/effect/packages/effect/src/Console.ts +653 -0
- package/repos/effect/packages/effect/src/Context.ts +1339 -0
- package/repos/effect/packages/effect/src/Cron.ts +1212 -0
- package/repos/effect/packages/effect/src/Crypto.ts +318 -0
- package/repos/effect/packages/effect/src/Data.ts +774 -0
- package/repos/effect/packages/effect/src/DateTime.ts +2922 -0
- package/repos/effect/packages/effect/src/Deferred.ts +917 -0
- package/repos/effect/packages/effect/src/Differ.ts +32 -0
- package/repos/effect/packages/effect/src/Duration.ts +1827 -0
- package/repos/effect/packages/effect/src/Effect.ts +15347 -0
- package/repos/effect/packages/effect/src/Effectable.ts +68 -0
- package/repos/effect/packages/effect/src/Encoding.ts +1046 -0
- package/repos/effect/packages/effect/src/Equal.ts +550 -0
- package/repos/effect/packages/effect/src/Equivalence.ts +870 -0
- package/repos/effect/packages/effect/src/ErrorReporter.ts +543 -0
- package/repos/effect/packages/effect/src/ExecutionPlan.ts +416 -0
- package/repos/effect/packages/effect/src/Exit.ts +1085 -0
- package/repos/effect/packages/effect/src/Fiber.ts +632 -0
- package/repos/effect/packages/effect/src/FiberHandle.ts +815 -0
- package/repos/effect/packages/effect/src/FiberMap.ts +1030 -0
- package/repos/effect/packages/effect/src/FiberSet.ts +713 -0
- package/repos/effect/packages/effect/src/FileSystem.ts +1394 -0
- package/repos/effect/packages/effect/src/Filter.ts +827 -0
- package/repos/effect/packages/effect/src/Formatter.ts +319 -0
- package/repos/effect/packages/effect/src/Function.ts +1415 -0
- package/repos/effect/packages/effect/src/Graph.ts +4892 -0
- package/repos/effect/packages/effect/src/HKT.ts +213 -0
- package/repos/effect/packages/effect/src/Hash.ts +539 -0
- package/repos/effect/packages/effect/src/HashMap.ts +1236 -0
- package/repos/effect/packages/effect/src/HashRing.ts +426 -0
- package/repos/effect/packages/effect/src/HashSet.ts +605 -0
- package/repos/effect/packages/effect/src/Inspectable.ts +329 -0
- package/repos/effect/packages/effect/src/Iterable.ts +2483 -0
- package/repos/effect/packages/effect/src/JsonPatch.ts +469 -0
- package/repos/effect/packages/effect/src/JsonPointer.ts +80 -0
- package/repos/effect/packages/effect/src/JsonSchema.ts +948 -0
- package/repos/effect/packages/effect/src/Latch.ts +373 -0
- package/repos/effect/packages/effect/src/Layer.ts +2773 -0
- package/repos/effect/packages/effect/src/LayerMap.ts +468 -0
- package/repos/effect/packages/effect/src/LogLevel.ts +412 -0
- package/repos/effect/packages/effect/src/Logger.ts +1284 -0
- package/repos/effect/packages/effect/src/ManagedRuntime.ts +381 -0
- package/repos/effect/packages/effect/src/Match.ts +2606 -0
- package/repos/effect/packages/effect/src/Metric.ts +4058 -0
- package/repos/effect/packages/effect/src/MutableHashMap.ts +845 -0
- package/repos/effect/packages/effect/src/MutableHashSet.ts +422 -0
- package/repos/effect/packages/effect/src/MutableList.ts +967 -0
- package/repos/effect/packages/effect/src/MutableRef.ts +822 -0
- package/repos/effect/packages/effect/src/Newtype.ts +319 -0
- package/repos/effect/packages/effect/src/NonEmptyIterable.ts +221 -0
- package/repos/effect/packages/effect/src/Number.ts +860 -0
- package/repos/effect/packages/effect/src/Optic.ts +1701 -0
- package/repos/effect/packages/effect/src/Option.ts +2664 -0
- package/repos/effect/packages/effect/src/Order.ts +982 -0
- package/repos/effect/packages/effect/src/Ordering.ts +182 -0
- package/repos/effect/packages/effect/src/PartitionedSemaphore.ts +561 -0
- package/repos/effect/packages/effect/src/Path.ts +870 -0
- package/repos/effect/packages/effect/src/Pipeable.ts +674 -0
- package/repos/effect/packages/effect/src/PlatformError.ts +221 -0
- package/repos/effect/packages/effect/src/Pool.ts +699 -0
- package/repos/effect/packages/effect/src/Predicate.ts +1872 -0
- package/repos/effect/packages/effect/src/PrimaryKey.ts +123 -0
- package/repos/effect/packages/effect/src/PubSub.ts +2797 -0
- package/repos/effect/packages/effect/src/Pull.ts +376 -0
- package/repos/effect/packages/effect/src/Queue.ts +1962 -0
- package/repos/effect/packages/effect/src/Random.ts +549 -0
- package/repos/effect/packages/effect/src/RcMap.ts +612 -0
- package/repos/effect/packages/effect/src/RcRef.ts +225 -0
- package/repos/effect/packages/effect/src/Record.ts +1563 -0
- package/repos/effect/packages/effect/src/Redactable.ts +168 -0
- package/repos/effect/packages/effect/src/Redacted.ts +314 -0
- package/repos/effect/packages/effect/src/Reducer.ts +178 -0
- package/repos/effect/packages/effect/src/Ref.ts +801 -0
- package/repos/effect/packages/effect/src/References.ts +786 -0
- package/repos/effect/packages/effect/src/RegExp.ts +82 -0
- package/repos/effect/packages/effect/src/Request.ts +598 -0
- package/repos/effect/packages/effect/src/RequestResolver.ts +1249 -0
- package/repos/effect/packages/effect/src/Resource.ts +184 -0
- package/repos/effect/packages/effect/src/Result.ts +1939 -0
- package/repos/effect/packages/effect/src/Runtime.ts +432 -0
- package/repos/effect/packages/effect/src/Schedule.ts +3564 -0
- package/repos/effect/packages/effect/src/Scheduler.ts +285 -0
- package/repos/effect/packages/effect/src/Schema.ts +14653 -0
- package/repos/effect/packages/effect/src/SchemaAST.ts +3903 -0
- package/repos/effect/packages/effect/src/SchemaGetter.ts +1870 -0
- package/repos/effect/packages/effect/src/SchemaIssue.ts +1176 -0
- package/repos/effect/packages/effect/src/SchemaParser.ts +1105 -0
- package/repos/effect/packages/effect/src/SchemaRepresentation.ts +3944 -0
- package/repos/effect/packages/effect/src/SchemaTransformation.ts +1818 -0
- package/repos/effect/packages/effect/src/SchemaUtils.ts +51 -0
- package/repos/effect/packages/effect/src/Scope.ts +572 -0
- package/repos/effect/packages/effect/src/ScopedCache.ts +820 -0
- package/repos/effect/packages/effect/src/ScopedRef.ts +192 -0
- package/repos/effect/packages/effect/src/Semaphore.ts +517 -0
- package/repos/effect/packages/effect/src/Sink.ts +2174 -0
- package/repos/effect/packages/effect/src/Stdio.ts +143 -0
- package/repos/effect/packages/effect/src/Stream.ts +11722 -0
- package/repos/effect/packages/effect/src/String.ts +1427 -0
- package/repos/effect/packages/effect/src/Struct.ts +979 -0
- package/repos/effect/packages/effect/src/SubscriptionRef.ts +1021 -0
- package/repos/effect/packages/effect/src/Symbol.ts +31 -0
- package/repos/effect/packages/effect/src/SynchronizedRef.ts +668 -0
- package/repos/effect/packages/effect/src/Take.ts +46 -0
- package/repos/effect/packages/effect/src/Terminal.ts +188 -0
- package/repos/effect/packages/effect/src/Tracer.ts +683 -0
- package/repos/effect/packages/effect/src/Trie.ts +953 -0
- package/repos/effect/packages/effect/src/Tuple.ts +737 -0
- package/repos/effect/packages/effect/src/TxChunk.ts +822 -0
- package/repos/effect/packages/effect/src/TxDeferred.ts +319 -0
- package/repos/effect/packages/effect/src/TxHashMap.ts +2165 -0
- package/repos/effect/packages/effect/src/TxHashSet.ts +908 -0
- package/repos/effect/packages/effect/src/TxPriorityQueue.ts +567 -0
- package/repos/effect/packages/effect/src/TxPubSub.ts +684 -0
- package/repos/effect/packages/effect/src/TxQueue.ts +1488 -0
- package/repos/effect/packages/effect/src/TxReentrantLock.ts +655 -0
- package/repos/effect/packages/effect/src/TxRef.ts +282 -0
- package/repos/effect/packages/effect/src/TxSemaphore.ts +707 -0
- package/repos/effect/packages/effect/src/TxSubscriptionRef.ts +518 -0
- package/repos/effect/packages/effect/src/Types.ts +1121 -0
- package/repos/effect/packages/effect/src/UndefinedOr.ts +239 -0
- package/repos/effect/packages/effect/src/Unify.ts +314 -0
- package/repos/effect/packages/effect/src/Utils.ts +221 -0
- package/repos/effect/packages/effect/src/index.ts +712 -0
- package/repos/effect/packages/effect/src/internal/array.ts +8 -0
- package/repos/effect/packages/effect/src/internal/concurrency.ts +52 -0
- package/repos/effect/packages/effect/src/internal/core.ts +666 -0
- package/repos/effect/packages/effect/src/internal/dateTime.ts +1264 -0
- package/repos/effect/packages/effect/src/internal/doNotation.ts +117 -0
- package/repos/effect/packages/effect/src/internal/effect.ts +6427 -0
- package/repos/effect/packages/effect/src/internal/equal.ts +28 -0
- package/repos/effect/packages/effect/src/internal/errors.ts +9 -0
- package/repos/effect/packages/effect/src/internal/executionPlan.ts +120 -0
- package/repos/effect/packages/effect/src/internal/hashMap.ts +1309 -0
- package/repos/effect/packages/effect/src/internal/hashSet.ts +190 -0
- package/repos/effect/packages/effect/src/internal/layer.ts +88 -0
- package/repos/effect/packages/effect/src/internal/matcher.ts +637 -0
- package/repos/effect/packages/effect/src/internal/metric.ts +2 -0
- package/repos/effect/packages/effect/src/internal/option.ts +98 -0
- package/repos/effect/packages/effect/src/internal/random.ts +20 -0
- package/repos/effect/packages/effect/src/internal/rcRef.ts +189 -0
- package/repos/effect/packages/effect/src/internal/record.ts +18 -0
- package/repos/effect/packages/effect/src/internal/redacted.ts +19 -0
- package/repos/effect/packages/effect/src/internal/references.ts +72 -0
- package/repos/effect/packages/effect/src/internal/request.ts +205 -0
- package/repos/effect/packages/effect/src/internal/result.ts +112 -0
- package/repos/effect/packages/effect/src/internal/schedule.ts +248 -0
- package/repos/effect/packages/effect/src/internal/schema/annotations.ts +37 -0
- package/repos/effect/packages/effect/src/internal/schema/arbitrary.ts +894 -0
- package/repos/effect/packages/effect/src/internal/schema/cause.ts +26 -0
- package/repos/effect/packages/effect/src/internal/schema/equivalence.ts +154 -0
- package/repos/effect/packages/effect/src/internal/schema/representation.ts +799 -0
- package/repos/effect/packages/effect/src/internal/schema/schema.ts +128 -0
- package/repos/effect/packages/effect/src/internal/stream.ts +28 -0
- package/repos/effect/packages/effect/src/internal/tracer.ts +41 -0
- package/repos/effect/packages/effect/src/internal/trie.ts +733 -0
- package/repos/effect/packages/effect/src/internal/version.ts +2 -0
- package/repos/effect/packages/effect/src/testing/FastCheck.ts +89 -0
- package/repos/effect/packages/effect/src/testing/TestClock.ts +547 -0
- package/repos/effect/packages/effect/src/testing/TestConsole.ts +369 -0
- package/repos/effect/packages/effect/src/testing/TestSchema.ts +567 -0
- package/repos/effect/packages/effect/src/testing/index.ts +25 -0
- package/repos/effect/packages/effect/src/unstable/ai/AiError.ts +1629 -0
- package/repos/effect/packages/effect/src/unstable/ai/AnthropicStructuredOutput.ts +407 -0
- package/repos/effect/packages/effect/src/unstable/ai/Chat.ts +931 -0
- package/repos/effect/packages/effect/src/unstable/ai/EmbeddingModel.ts +269 -0
- package/repos/effect/packages/effect/src/unstable/ai/IdGenerator.ts +300 -0
- package/repos/effect/packages/effect/src/unstable/ai/LanguageModel.ts +2221 -0
- package/repos/effect/packages/effect/src/unstable/ai/McpSchema.ts +2527 -0
- package/repos/effect/packages/effect/src/unstable/ai/McpServer.ts +1468 -0
- package/repos/effect/packages/effect/src/unstable/ai/Model.ts +166 -0
- package/repos/effect/packages/effect/src/unstable/ai/OpenAiStructuredOutput.ts +476 -0
- package/repos/effect/packages/effect/src/unstable/ai/Prompt.ts +2234 -0
- package/repos/effect/packages/effect/src/unstable/ai/Response.ts +2582 -0
- package/repos/effect/packages/effect/src/unstable/ai/ResponseIdTracker.ts +139 -0
- package/repos/effect/packages/effect/src/unstable/ai/Telemetry.ts +515 -0
- package/repos/effect/packages/effect/src/unstable/ai/Tokenizer.ts +176 -0
- package/repos/effect/packages/effect/src/unstable/ai/Tool.ts +2003 -0
- package/repos/effect/packages/effect/src/unstable/ai/Toolkit.ts +554 -0
- package/repos/effect/packages/effect/src/unstable/ai/index.ts +90 -0
- package/repos/effect/packages/effect/src/unstable/ai/internal/codec-transformer.ts +13 -0
- package/repos/effect/packages/effect/src/unstable/cli/Argument.ts +749 -0
- package/repos/effect/packages/effect/src/unstable/cli/CliError.ts +549 -0
- package/repos/effect/packages/effect/src/unstable/cli/CliOutput.ts +607 -0
- package/repos/effect/packages/effect/src/unstable/cli/Command.ts +1610 -0
- package/repos/effect/packages/effect/src/unstable/cli/Completions.ts +123 -0
- package/repos/effect/packages/effect/src/unstable/cli/Flag.ts +986 -0
- package/repos/effect/packages/effect/src/unstable/cli/GlobalFlag.ts +295 -0
- package/repos/effect/packages/effect/src/unstable/cli/HelpDoc.ts +323 -0
- package/repos/effect/packages/effect/src/unstable/cli/Param.ts +2193 -0
- package/repos/effect/packages/effect/src/unstable/cli/Primitive.ts +766 -0
- package/repos/effect/packages/effect/src/unstable/cli/Prompt.ts +3852 -0
- package/repos/effect/packages/effect/src/unstable/cli/SEMANTICS.md +157 -0
- package/repos/effect/packages/effect/src/unstable/cli/index.ts +60 -0
- package/repos/effect/packages/effect/src/unstable/cli/internal/ansi.ts +152 -0
- package/repos/effect/packages/effect/src/unstable/cli/internal/auto-suggest.ts +41 -0
- package/repos/effect/packages/effect/src/unstable/cli/internal/command.ts +340 -0
- package/repos/effect/packages/effect/src/unstable/cli/internal/completions/bash.ts +222 -0
- package/repos/effect/packages/effect/src/unstable/cli/internal/completions/descriptor.ts +133 -0
- package/repos/effect/packages/effect/src/unstable/cli/internal/completions/fish.ts +253 -0
- package/repos/effect/packages/effect/src/unstable/cli/internal/completions/zsh.ts +220 -0
- package/repos/effect/packages/effect/src/unstable/cli/internal/config.ts +272 -0
- package/repos/effect/packages/effect/src/unstable/cli/internal/help.ts +181 -0
- package/repos/effect/packages/effect/src/unstable/cli/internal/lexer.ts +70 -0
- package/repos/effect/packages/effect/src/unstable/cli/internal/parser.ts +932 -0
- package/repos/effect/packages/effect/src/unstable/cluster/ClusterCron.ts +163 -0
- package/repos/effect/packages/effect/src/unstable/cluster/ClusterError.ts +238 -0
- package/repos/effect/packages/effect/src/unstable/cluster/ClusterMetrics.ts +112 -0
- package/repos/effect/packages/effect/src/unstable/cluster/ClusterSchema.ts +170 -0
- package/repos/effect/packages/effect/src/unstable/cluster/ClusterWorkflowEngine.ts +778 -0
- package/repos/effect/packages/effect/src/unstable/cluster/DeliverAt.ts +58 -0
- package/repos/effect/packages/effect/src/unstable/cluster/Entity.ts +779 -0
- package/repos/effect/packages/effect/src/unstable/cluster/EntityAddress.ts +93 -0
- package/repos/effect/packages/effect/src/unstable/cluster/EntityId.ts +50 -0
- package/repos/effect/packages/effect/src/unstable/cluster/EntityProxy.ts +263 -0
- package/repos/effect/packages/effect/src/unstable/cluster/EntityProxyServer.ts +149 -0
- package/repos/effect/packages/effect/src/unstable/cluster/EntityResource.ts +184 -0
- package/repos/effect/packages/effect/src/unstable/cluster/EntityType.ts +52 -0
- package/repos/effect/packages/effect/src/unstable/cluster/Envelope.ts +433 -0
- package/repos/effect/packages/effect/src/unstable/cluster/HttpRunner.ts +345 -0
- package/repos/effect/packages/effect/src/unstable/cluster/K8sHttpClient.ts +297 -0
- package/repos/effect/packages/effect/src/unstable/cluster/MachineId.ts +54 -0
- package/repos/effect/packages/effect/src/unstable/cluster/Message.ts +314 -0
- package/repos/effect/packages/effect/src/unstable/cluster/MessageStorage.ts +1072 -0
- package/repos/effect/packages/effect/src/unstable/cluster/Reply.ts +455 -0
- package/repos/effect/packages/effect/src/unstable/cluster/Runner.ts +129 -0
- package/repos/effect/packages/effect/src/unstable/cluster/RunnerAddress.ts +112 -0
- package/repos/effect/packages/effect/src/unstable/cluster/RunnerHealth.ts +145 -0
- package/repos/effect/packages/effect/src/unstable/cluster/RunnerServer.ts +220 -0
- package/repos/effect/packages/effect/src/unstable/cluster/RunnerStorage.ts +243 -0
- package/repos/effect/packages/effect/src/unstable/cluster/Runners.ts +690 -0
- package/repos/effect/packages/effect/src/unstable/cluster/ShardId.ts +178 -0
- package/repos/effect/packages/effect/src/unstable/cluster/Sharding.ts +1488 -0
- package/repos/effect/packages/effect/src/unstable/cluster/ShardingConfig.ts +367 -0
- package/repos/effect/packages/effect/src/unstable/cluster/ShardingRegistrationEvent.ts +76 -0
- package/repos/effect/packages/effect/src/unstable/cluster/SingleRunner.ts +75 -0
- package/repos/effect/packages/effect/src/unstable/cluster/Singleton.ts +56 -0
- package/repos/effect/packages/effect/src/unstable/cluster/SingletonAddress.ts +49 -0
- package/repos/effect/packages/effect/src/unstable/cluster/Snowflake.ts +282 -0
- package/repos/effect/packages/effect/src/unstable/cluster/SocketRunner.ts +96 -0
- package/repos/effect/packages/effect/src/unstable/cluster/SqlMessageStorage.ts +1045 -0
- package/repos/effect/packages/effect/src/unstable/cluster/SqlRunnerStorage.ts +700 -0
- package/repos/effect/packages/effect/src/unstable/cluster/TestRunner.ts +36 -0
- package/repos/effect/packages/effect/src/unstable/cluster/index.ts +195 -0
- package/repos/effect/packages/effect/src/unstable/cluster/internal/entityManager.ts +678 -0
- package/repos/effect/packages/effect/src/unstable/cluster/internal/entityReaper.ts +58 -0
- package/repos/effect/packages/effect/src/unstable/cluster/internal/hash.ts +23 -0
- package/repos/effect/packages/effect/src/unstable/cluster/internal/interruptors.ts +2 -0
- package/repos/effect/packages/effect/src/unstable/cluster/internal/resourceMap.ts +100 -0
- package/repos/effect/packages/effect/src/unstable/cluster/internal/resourceRef.ts +99 -0
- package/repos/effect/packages/effect/src/unstable/devtools/DevTools.ts +68 -0
- package/repos/effect/packages/effect/src/unstable/devtools/DevToolsClient.ts +236 -0
- package/repos/effect/packages/effect/src/unstable/devtools/DevToolsSchema.ts +558 -0
- package/repos/effect/packages/effect/src/unstable/devtools/DevToolsServer.ts +94 -0
- package/repos/effect/packages/effect/src/unstable/devtools/index.ts +25 -0
- package/repos/effect/packages/effect/src/unstable/encoding/Msgpack.ts +383 -0
- package/repos/effect/packages/effect/src/unstable/encoding/Ndjson.ts +602 -0
- package/repos/effect/packages/effect/src/unstable/encoding/Sse.ts +593 -0
- package/repos/effect/packages/effect/src/unstable/encoding/index.ts +20 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/Event.ts +447 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/EventGroup.ts +193 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/EventJournal.ts +795 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/EventLog.ts +1030 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/EventLogEncryption.ts +169 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/EventLogMessage.ts +354 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/EventLogRemote.ts +377 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/EventLogServer.ts +242 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/EventLogServerEncrypted.ts +268 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/EventLogServerUnencrypted.ts +898 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/EventLogSessionAuth.ts +524 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/SqlEventJournal.ts +353 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/SqlEventLogServerEncrypted.ts +343 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/SqlEventLogServerUnencrypted.ts +527 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/index.ts +75 -0
- package/repos/effect/packages/effect/src/unstable/eventlog/internal/identityRootSecretDerivation.ts +153 -0
- package/repos/effect/packages/effect/src/unstable/http/Cookies.ts +952 -0
- package/repos/effect/packages/effect/src/unstable/http/Etag.ts +141 -0
- package/repos/effect/packages/effect/src/unstable/http/FetchHttpClient.ts +123 -0
- package/repos/effect/packages/effect/src/unstable/http/FindMyWay.ts +15 -0
- package/repos/effect/packages/effect/src/unstable/http/Headers.ts +438 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpBody.ts +545 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpClient.ts +1630 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpClientError.ts +328 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpClientRequest.ts +968 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpClientResponse.ts +408 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpEffect.ts +400 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpIncomingMessage.ts +153 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpMethod.ts +124 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpMiddleware.ts +394 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpPlatform.ts +165 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpRouter.ts +1341 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpServer.ts +329 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpServerError.ts +374 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpServerRequest.ts +1081 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpServerRespondable.ts +115 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpServerResponse.ts +1381 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpStaticServer.ts +464 -0
- package/repos/effect/packages/effect/src/unstable/http/HttpTraceContext.ts +160 -0
- package/repos/effect/packages/effect/src/unstable/http/Multipart.ts +830 -0
- package/repos/effect/packages/effect/src/unstable/http/Multipasta/HeadersParser.ts +14 -0
- package/repos/effect/packages/effect/src/unstable/http/Multipasta/Node.ts +14 -0
- package/repos/effect/packages/effect/src/unstable/http/Multipasta/Search.ts +14 -0
- package/repos/effect/packages/effect/src/unstable/http/Multipasta/Web.ts +14 -0
- package/repos/effect/packages/effect/src/unstable/http/Multipasta.ts +15 -0
- package/repos/effect/packages/effect/src/unstable/http/Template.ts +262 -0
- package/repos/effect/packages/effect/src/unstable/http/Url.ts +330 -0
- package/repos/effect/packages/effect/src/unstable/http/UrlParams.ts +678 -0
- package/repos/effect/packages/effect/src/unstable/http/index.ts +145 -0
- package/repos/effect/packages/effect/src/unstable/http/internal/preResponseHandler.ts +15 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/HttpApi.ts +316 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/HttpApiBuilder.ts +1015 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/HttpApiClient.ts +1005 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/HttpApiEndpoint.ts +1545 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/HttpApiError.ts +443 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/HttpApiGroup.ts +381 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/HttpApiMiddleware.ts +478 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/HttpApiScalar.ts +267 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/HttpApiSchema.ts +733 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/HttpApiSecurity.ts +244 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/HttpApiSwagger.ts +68 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/HttpApiTest.ts +112 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/OpenApi.ts +1098 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/index.ts +70 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/internal/html.ts +18 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/internal/httpApiScalar.ts +5 -0
- package/repos/effect/packages/effect/src/unstable/httpapi/internal/httpApiSwagger.ts +9 -0
- package/repos/effect/packages/effect/src/unstable/observability/Otlp.ts +172 -0
- package/repos/effect/packages/effect/src/unstable/observability/OtlpExporter.ts +149 -0
- package/repos/effect/packages/effect/src/unstable/observability/OtlpLogger.ts +340 -0
- package/repos/effect/packages/effect/src/unstable/observability/OtlpMetrics.ts +826 -0
- package/repos/effect/packages/effect/src/unstable/observability/OtlpResource.ts +288 -0
- package/repos/effect/packages/effect/src/unstable/observability/OtlpSerialization.ts +66 -0
- package/repos/effect/packages/effect/src/unstable/observability/OtlpTracer.ts +442 -0
- package/repos/effect/packages/effect/src/unstable/observability/PrometheusMetrics.ts +468 -0
- package/repos/effect/packages/effect/src/unstable/observability/index.ts +45 -0
- package/repos/effect/packages/effect/src/unstable/observability/internal/otlpEnv.ts +39 -0
- package/repos/effect/packages/effect/src/unstable/observability/internal/otlpProtobuf.ts +779 -0
- package/repos/effect/packages/effect/src/unstable/observability/internal/protobuf.ts +262 -0
- package/repos/effect/packages/effect/src/unstable/persistence/KeyValueStore.ts +864 -0
- package/repos/effect/packages/effect/src/unstable/persistence/Persistable.ts +252 -0
- package/repos/effect/packages/effect/src/unstable/persistence/PersistedCache.ts +111 -0
- package/repos/effect/packages/effect/src/unstable/persistence/PersistedQueue.ts +1196 -0
- package/repos/effect/packages/effect/src/unstable/persistence/Persistence.ts +1071 -0
- package/repos/effect/packages/effect/src/unstable/persistence/RateLimiter.ts +748 -0
- package/repos/effect/packages/effect/src/unstable/persistence/Redis.ts +188 -0
- package/repos/effect/packages/effect/src/unstable/persistence/index.ts +40 -0
- package/repos/effect/packages/effect/src/unstable/process/ChildProcess.ts +1036 -0
- package/repos/effect/packages/effect/src/unstable/process/ChildProcessSpawner.ts +285 -0
- package/repos/effect/packages/effect/src/unstable/process/index.ts +15 -0
- package/repos/effect/packages/effect/src/unstable/reactivity/AsyncResult.ts +1081 -0
- package/repos/effect/packages/effect/src/unstable/reactivity/Atom.ts +2520 -0
- package/repos/effect/packages/effect/src/unstable/reactivity/AtomHttpApi.ts +352 -0
- package/repos/effect/packages/effect/src/unstable/reactivity/AtomRef.ts +352 -0
- package/repos/effect/packages/effect/src/unstable/reactivity/AtomRegistry.ts +1127 -0
- package/repos/effect/packages/effect/src/unstable/reactivity/AtomRpc.ts +305 -0
- package/repos/effect/packages/effect/src/unstable/reactivity/Hydration.ts +155 -0
- package/repos/effect/packages/effect/src/unstable/reactivity/Reactivity.ts +348 -0
- package/repos/effect/packages/effect/src/unstable/reactivity/index.ts +45 -0
- package/repos/effect/packages/effect/src/unstable/rpc/Rpc.ts +1255 -0
- package/repos/effect/packages/effect/src/unstable/rpc/RpcClient.ts +1370 -0
- package/repos/effect/packages/effect/src/unstable/rpc/RpcClientError.ts +57 -0
- package/repos/effect/packages/effect/src/unstable/rpc/RpcGroup.ts +409 -0
- package/repos/effect/packages/effect/src/unstable/rpc/RpcMessage.ts +402 -0
- package/repos/effect/packages/effect/src/unstable/rpc/RpcMiddleware.ts +344 -0
- package/repos/effect/packages/effect/src/unstable/rpc/RpcSchema.ts +97 -0
- package/repos/effect/packages/effect/src/unstable/rpc/RpcSerialization.ts +546 -0
- package/repos/effect/packages/effect/src/unstable/rpc/RpcServer.ts +1492 -0
- package/repos/effect/packages/effect/src/unstable/rpc/RpcTest.ts +56 -0
- package/repos/effect/packages/effect/src/unstable/rpc/RpcWorker.ts +118 -0
- package/repos/effect/packages/effect/src/unstable/rpc/Utils.ts +120 -0
- package/repos/effect/packages/effect/src/unstable/rpc/index.ts +65 -0
- package/repos/effect/packages/effect/src/unstable/schema/Model.ts +862 -0
- package/repos/effect/packages/effect/src/unstable/schema/VariantSchema.ts +604 -0
- package/repos/effect/packages/effect/src/unstable/schema/index.ts +15 -0
- package/repos/effect/packages/effect/src/unstable/socket/Socket.ts +911 -0
- package/repos/effect/packages/effect/src/unstable/socket/SocketServer.ts +147 -0
- package/repos/effect/packages/effect/src/unstable/socket/index.ts +15 -0
- package/repos/effect/packages/effect/src/unstable/sql/Migrator.ts +440 -0
- package/repos/effect/packages/effect/src/unstable/sql/SqlClient.ts +342 -0
- package/repos/effect/packages/effect/src/unstable/sql/SqlConnection.ts +83 -0
- package/repos/effect/packages/effect/src/unstable/sql/SqlError.ts +590 -0
- package/repos/effect/packages/effect/src/unstable/sql/SqlModel.ts +359 -0
- package/repos/effect/packages/effect/src/unstable/sql/SqlResolver.ts +380 -0
- package/repos/effect/packages/effect/src/unstable/sql/SqlSchema.ts +172 -0
- package/repos/effect/packages/effect/src/unstable/sql/SqlStream.ts +81 -0
- package/repos/effect/packages/effect/src/unstable/sql/Statement.ts +1500 -0
- package/repos/effect/packages/effect/src/unstable/sql/index.ts +50 -0
- package/repos/effect/packages/effect/src/unstable/workers/Transferable.ts +191 -0
- package/repos/effect/packages/effect/src/unstable/workers/Worker.ts +245 -0
- package/repos/effect/packages/effect/src/unstable/workers/WorkerError.ts +148 -0
- package/repos/effect/packages/effect/src/unstable/workers/WorkerRunner.ts +57 -0
- package/repos/effect/packages/effect/src/unstable/workers/index.ts +25 -0
- package/repos/effect/packages/effect/src/unstable/workflow/Activity.ts +322 -0
- package/repos/effect/packages/effect/src/unstable/workflow/DurableClock.ts +117 -0
- package/repos/effect/packages/effect/src/unstable/workflow/DurableDeferred.ts +653 -0
- package/repos/effect/packages/effect/src/unstable/workflow/DurableQueue.ts +360 -0
- package/repos/effect/packages/effect/src/unstable/workflow/Workflow.ts +898 -0
- package/repos/effect/packages/effect/src/unstable/workflow/WorkflowEngine.ts +759 -0
- package/repos/effect/packages/effect/src/unstable/workflow/WorkflowProxy.ts +212 -0
- package/repos/effect/packages/effect/src/unstable/workflow/WorkflowProxyServer.ts +151 -0
- package/repos/effect/packages/effect/src/unstable/workflow/index.ts +45 -0
- package/repos/effect/packages/effect/src/unstable/workflow/internal/crypto.ts +15 -0
- package/repos/effect/packages/effect/test/Array.test.ts +1579 -0
- package/repos/effect/packages/effect/test/AtomRef.test.ts +27 -0
- package/repos/effect/packages/effect/test/BigDecimal.test.ts +525 -0
- package/repos/effect/packages/effect/test/BigInt.test.ts +57 -0
- package/repos/effect/packages/effect/test/Boolean.test.ts +289 -0
- package/repos/effect/packages/effect/test/Brand.test.ts +160 -0
- package/repos/effect/packages/effect/test/Cache.test.ts +1423 -0
- package/repos/effect/packages/effect/test/Cause.test.ts +834 -0
- package/repos/effect/packages/effect/test/Channel.test.ts +556 -0
- package/repos/effect/packages/effect/test/Chunk.test.ts +874 -0
- package/repos/effect/packages/effect/test/Combiner.test.ts +42 -0
- package/repos/effect/packages/effect/test/Config.test.ts +1416 -0
- package/repos/effect/packages/effect/test/ConfigProvider.test.ts +726 -0
- package/repos/effect/packages/effect/test/Cron.test.ts +401 -0
- package/repos/effect/packages/effect/test/Crypto.test.ts +86 -0
- package/repos/effect/packages/effect/test/Data.test.ts +269 -0
- package/repos/effect/packages/effect/test/DateTime.test.ts +953 -0
- package/repos/effect/packages/effect/test/Deferred.test.ts +165 -0
- package/repos/effect/packages/effect/test/Duration.test.ts +679 -0
- package/repos/effect/packages/effect/test/Effect.test.ts +2658 -0
- package/repos/effect/packages/effect/test/EffectEager.test.ts +678 -0
- package/repos/effect/packages/effect/test/EffectKeepAlive.test.ts +71 -0
- package/repos/effect/packages/effect/test/Equal.test.ts +1278 -0
- package/repos/effect/packages/effect/test/Equivalence.test.ts +170 -0
- package/repos/effect/packages/effect/test/ExecutionPlan.test.ts +117 -0
- package/repos/effect/packages/effect/test/Exit.test.ts +12 -0
- package/repos/effect/packages/effect/test/Fiber.test.ts +9 -0
- package/repos/effect/packages/effect/test/FiberHandle.test.ts +146 -0
- package/repos/effect/packages/effect/test/FiberMap.test.ts +171 -0
- package/repos/effect/packages/effect/test/FiberSet.test.ts +119 -0
- package/repos/effect/packages/effect/test/Formatter.test.ts +247 -0
- package/repos/effect/packages/effect/test/Function.test.ts +333 -0
- package/repos/effect/packages/effect/test/Graph.test.ts +3505 -0
- package/repos/effect/packages/effect/test/HashMap.test.ts +618 -0
- package/repos/effect/packages/effect/test/HashSet.test.ts +298 -0
- package/repos/effect/packages/effect/test/HttpClient.test.ts +131 -0
- package/repos/effect/packages/effect/test/Iterable.test.ts +486 -0
- package/repos/effect/packages/effect/test/JsonPatch.test.ts +948 -0
- package/repos/effect/packages/effect/test/JsonPointer.test.ts +353 -0
- package/repos/effect/packages/effect/test/JsonSchema.test.ts +1253 -0
- package/repos/effect/packages/effect/test/Latch.test.ts +21 -0
- package/repos/effect/packages/effect/test/Layer.test.ts +648 -0
- package/repos/effect/packages/effect/test/LayerMap.test.ts +98 -0
- package/repos/effect/packages/effect/test/LogLevel.test.ts +28 -0
- package/repos/effect/packages/effect/test/Logger.test.ts +154 -0
- package/repos/effect/packages/effect/test/ManagedRuntime.test.ts +58 -0
- package/repos/effect/packages/effect/test/Match.test.ts +27 -0
- package/repos/effect/packages/effect/test/Metric.test.ts +682 -0
- package/repos/effect/packages/effect/test/Migrator.test.ts +69 -0
- package/repos/effect/packages/effect/test/MutableHashMap.test.ts +309 -0
- package/repos/effect/packages/effect/test/MutableHashSet.test.ts +10 -0
- package/repos/effect/packages/effect/test/MutableList.test.ts +58 -0
- package/repos/effect/packages/effect/test/Newtype.test.ts +90 -0
- package/repos/effect/packages/effect/test/Number.test.ts +422 -0
- package/repos/effect/packages/effect/test/Optic.test.ts +452 -0
- package/repos/effect/packages/effect/test/Option.test.ts +564 -0
- package/repos/effect/packages/effect/test/Order.test.ts +163 -0
- package/repos/effect/packages/effect/test/Ordering.test.ts +18 -0
- package/repos/effect/packages/effect/test/PartitionedSemaphore.test.ts +74 -0
- package/repos/effect/packages/effect/test/Pathfinding.test.ts +426 -0
- package/repos/effect/packages/effect/test/Pool.test.ts +422 -0
- package/repos/effect/packages/effect/test/Predicate.test.ts +555 -0
- package/repos/effect/packages/effect/test/PubSub.test.ts +538 -0
- package/repos/effect/packages/effect/test/Queue.test.ts +317 -0
- package/repos/effect/packages/effect/test/Random.test.ts +238 -0
- package/repos/effect/packages/effect/test/RcMap.test.ts +237 -0
- package/repos/effect/packages/effect/test/RcRef.test.ts +97 -0
- package/repos/effect/packages/effect/test/Record.test.ts +395 -0
- package/repos/effect/packages/effect/test/Redacted.test.ts +59 -0
- package/repos/effect/packages/effect/test/Reducer.test.ts +12 -0
- package/repos/effect/packages/effect/test/Ref.test.ts +187 -0
- package/repos/effect/packages/effect/test/Request.test.ts +305 -0
- package/repos/effect/packages/effect/test/Resource.test.ts +59 -0
- package/repos/effect/packages/effect/test/Result.test.ts +517 -0
- package/repos/effect/packages/effect/test/Schedule.test.ts +395 -0
- package/repos/effect/packages/effect/test/Scheduler.test.ts +70 -0
- package/repos/effect/packages/effect/test/Scope.test.ts +19 -0
- package/repos/effect/packages/effect/test/ScopedCache.test.ts +2316 -0
- package/repos/effect/packages/effect/test/ScopedRef.test.ts +80 -0
- package/repos/effect/packages/effect/test/Semaphore.test.ts +469 -0
- package/repos/effect/packages/effect/test/Sink.test.ts +230 -0
- package/repos/effect/packages/effect/test/Stream.test.ts +4712 -0
- package/repos/effect/packages/effect/test/String.test.ts +690 -0
- package/repos/effect/packages/effect/test/Struct.test.ts +216 -0
- package/repos/effect/packages/effect/test/SubscriptionRef.test.ts +90 -0
- package/repos/effect/packages/effect/test/Symbol.test.ts +50 -0
- package/repos/effect/packages/effect/test/SynchronizedRef.test.ts +105 -0
- package/repos/effect/packages/effect/test/TestClock.test.ts +71 -0
- package/repos/effect/packages/effect/test/Tracer.test.ts +410 -0
- package/repos/effect/packages/effect/test/Trie.test.ts +531 -0
- package/repos/effect/packages/effect/test/Tuple.test.ts +127 -0
- package/repos/effect/packages/effect/test/TxChunk.test.ts +342 -0
- package/repos/effect/packages/effect/test/TxDeferred.test.ts +197 -0
- package/repos/effect/packages/effect/test/TxHashMap.test.ts +963 -0
- package/repos/effect/packages/effect/test/TxHashSet.test.ts +442 -0
- package/repos/effect/packages/effect/test/TxPriorityQueue.test.ts +187 -0
- package/repos/effect/packages/effect/test/TxPubSub.test.ts +391 -0
- package/repos/effect/packages/effect/test/TxQueue.test.ts +1260 -0
- package/repos/effect/packages/effect/test/TxReentrantLock.test.ts +413 -0
- package/repos/effect/packages/effect/test/TxSemaphore.test.ts +283 -0
- package/repos/effect/packages/effect/test/TxSubscriptionRef.test.ts +197 -0
- package/repos/effect/packages/effect/test/UndefinedOr.test.ts +65 -0
- package/repos/effect/packages/effect/test/cluster/ClusterWorkflowEngine.test.ts +652 -0
- package/repos/effect/packages/effect/test/cluster/Entity.test.ts +81 -0
- package/repos/effect/packages/effect/test/cluster/K8sHttpClient.test.ts +34 -0
- package/repos/effect/packages/effect/test/cluster/MessageStorage.test.ts +196 -0
- package/repos/effect/packages/effect/test/cluster/Sharding.test.ts +578 -0
- package/repos/effect/packages/effect/test/cluster/TestEntity.ts +132 -0
- package/repos/effect/packages/effect/test/reactivity/AsyncResult.test.ts +41 -0
- package/repos/effect/packages/effect/test/reactivity/Atom.test.ts +2551 -0
- package/repos/effect/packages/effect/test/reactivity/AtomHttpApi.test.ts +86 -0
- package/repos/effect/packages/effect/test/reactivity/AtomRpc.test.ts +70 -0
- package/repos/effect/packages/effect/test/rpc/Rpc.test.ts +73 -0
- package/repos/effect/packages/effect/test/rpc/RpcClient.test.ts +58 -0
- package/repos/effect/packages/effect/test/rpc/RpcSerialization.test.ts +171 -0
- package/repos/effect/packages/effect/test/schema/HMR.test.ts +72 -0
- package/repos/effect/packages/effect/test/schema/Schema.test.ts +9133 -0
- package/repos/effect/packages/effect/test/schema/SchemaAST.test.ts +280 -0
- package/repos/effect/packages/effect/test/schema/SchemaGetter.test.ts +383 -0
- package/repos/effect/packages/effect/test/schema/SchemaIssue.test.ts +9 -0
- package/repos/effect/packages/effect/test/schema/SchemaParser.test.ts +323 -0
- package/repos/effect/packages/effect/test/schema/fixtures/HMR-Class.ts +5 -0
- package/repos/effect/packages/effect/test/schema/fixtures/HMR-sanity-check.ts +3 -0
- package/repos/effect/packages/effect/test/schema/representation/fromASTs.test.ts +820 -0
- package/repos/effect/packages/effect/test/schema/representation/fromJsonSchemaDocument.test.ts +2137 -0
- package/repos/effect/packages/effect/test/schema/representation/toCodeDocument.test.ts +2089 -0
- package/repos/effect/packages/effect/test/schema/representation/toJsonSchemaMultiDocument.test.ts +39 -0
- package/repos/effect/packages/effect/test/schema/representation/toSchema.test.ts +506 -0
- package/repos/effect/packages/effect/test/schema/toArbitrary.test.ts +1693 -0
- package/repos/effect/packages/effect/test/schema/toCodec.test.ts +3149 -0
- package/repos/effect/packages/effect/test/schema/toDifferJsonPatch.test.ts +239 -0
- package/repos/effect/packages/effect/test/schema/toEquivalence.test.ts +519 -0
- package/repos/effect/packages/effect/test/schema/toFormatter.test.ts +565 -0
- package/repos/effect/packages/effect/test/schema/toIso.test.ts +394 -0
- package/repos/effect/packages/effect/test/schema/toJsonSchemaDocument.test.ts +3630 -0
- package/repos/effect/packages/effect/test/schema/toStandardJSONSchemaV1.test.ts +126 -0
- package/repos/effect/packages/effect/test/schema/toStandardSchemaV1.test.ts +495 -0
- package/repos/effect/packages/effect/test/schema/v3-v4.test.ts +250 -0
- package/repos/effect/packages/effect/test/testing/TestSchema.test.ts +78 -0
- package/repos/effect/packages/effect/test/unstable/ai/AiError.test.ts +823 -0
- package/repos/effect/packages/effect/test/unstable/ai/AnthropicStructuredOutput.test.ts +593 -0
- package/repos/effect/packages/effect/test/unstable/ai/Chat.test.ts +147 -0
- package/repos/effect/packages/effect/test/unstable/ai/EmbeddingModel.test.ts +185 -0
- package/repos/effect/packages/effect/test/unstable/ai/LanguageModel.test.ts +1714 -0
- package/repos/effect/packages/effect/test/unstable/ai/LanguageModelTrackerLifecycle.test.ts +413 -0
- package/repos/effect/packages/effect/test/unstable/ai/McpServer.test.ts +82 -0
- package/repos/effect/packages/effect/test/unstable/ai/Model.test.ts +16 -0
- package/repos/effect/packages/effect/test/unstable/ai/OpenAiStructuredOutput.test.ts +723 -0
- package/repos/effect/packages/effect/test/unstable/ai/Prompt.test.ts +346 -0
- package/repos/effect/packages/effect/test/unstable/ai/ResponseIdTracker.test.ts +424 -0
- package/repos/effect/packages/effect/test/unstable/ai/Tool.test.ts +1264 -0
- package/repos/effect/packages/effect/test/unstable/ai/utils.ts +68 -0
- package/repos/effect/packages/effect/test/unstable/cli/Arguments.test.ts +390 -0
- package/repos/effect/packages/effect/test/unstable/cli/Command.test.ts +1801 -0
- package/repos/effect/packages/effect/test/unstable/cli/Errors.test.ts +150 -0
- package/repos/effect/packages/effect/test/unstable/cli/Help.test.ts +572 -0
- package/repos/effect/packages/effect/test/unstable/cli/LogLevel.test.ts +202 -0
- package/repos/effect/packages/effect/test/unstable/cli/Param.test.ts +391 -0
- package/repos/effect/packages/effect/test/unstable/cli/Primitive.test.ts +321 -0
- package/repos/effect/packages/effect/test/unstable/cli/Prompt.test.ts +597 -0
- package/repos/effect/packages/effect/test/unstable/cli/completions/completions.test.ts +656 -0
- package/repos/effect/packages/effect/test/unstable/cli/completions/descriptor.test.ts +245 -0
- package/repos/effect/packages/effect/test/unstable/cli/fixtures/ComprehensiveCli.ts +422 -0
- package/repos/effect/packages/effect/test/unstable/cli/services/MockTerminal.ts +135 -0
- package/repos/effect/packages/effect/test/unstable/cli/services/TestActions.ts +36 -0
- package/repos/effect/packages/effect/test/unstable/encoding/Ndjson.test.ts +18 -0
- package/repos/effect/packages/effect/test/unstable/encoding/Sse.test.ts +62 -0
- package/repos/effect/packages/effect/test/unstable/eventlog/EventJournal.test.ts +25 -0
- package/repos/effect/packages/effect/test/unstable/eventlog/EventLog.test.ts +104 -0
- package/repos/effect/packages/effect/test/unstable/eventlog/EventLogIdentityDerivation.test.ts +85 -0
- package/repos/effect/packages/effect/test/unstable/eventlog/EventLogRemote.test.ts +176 -0
- package/repos/effect/packages/effect/test/unstable/eventlog/EventLogSessionAuth.test.ts +130 -0
- package/repos/effect/packages/effect/test/unstable/eventlog/SqlEventLogServerUnencryptedStorageTest.ts +169 -0
- package/repos/effect/packages/effect/test/unstable/http/Cookies.test.ts +80 -0
- package/repos/effect/packages/effect/test/unstable/http/Headers.test.ts +73 -0
- package/repos/effect/packages/effect/test/unstable/http/HttpClient.test.ts +306 -0
- package/repos/effect/packages/effect/test/unstable/http/HttpClientRequest.test.ts +164 -0
- package/repos/effect/packages/effect/test/unstable/http/HttpEffect.test.ts +254 -0
- package/repos/effect/packages/effect/test/unstable/http/HttpMiddleware.test.ts +57 -0
- package/repos/effect/packages/effect/test/unstable/http/HttpServerError.test.ts +121 -0
- package/repos/effect/packages/effect/test/unstable/http/HttpServerRequest.test.ts +157 -0
- package/repos/effect/packages/effect/test/unstable/http/HttpServerResponse.test.ts +76 -0
- package/repos/effect/packages/effect/test/unstable/http/Multipart.test.ts +69 -0
- package/repos/effect/packages/effect/test/unstable/http/Url.test.ts +98 -0
- package/repos/effect/packages/effect/test/unstable/http/UrlParams.test.ts +30 -0
- package/repos/effect/packages/effect/test/unstable/httpapi/HttpApiBuilder.test.ts +186 -0
- package/repos/effect/packages/effect/test/unstable/httpapi/HttpApiClient.test.ts +446 -0
- package/repos/effect/packages/effect/test/unstable/httpapi/HttpApiEndpoint.test.ts +160 -0
- package/repos/effect/packages/effect/test/unstable/httpapi/HttpApiSchema.test.ts +108 -0
- package/repos/effect/packages/effect/test/unstable/httpapi/HttpApiSecurity.test.ts +41 -0
- package/repos/effect/packages/effect/test/unstable/httpapi/OpenApi.test.ts +39 -0
- package/repos/effect/packages/effect/test/unstable/observability/OtlpConfig.test.ts +151 -0
- package/repos/effect/packages/effect/test/unstable/observability/OtlpExporter.test.ts +108 -0
- package/repos/effect/packages/effect/test/unstable/observability/OtlpMetrics.test.ts +518 -0
- package/repos/effect/packages/effect/test/unstable/observability/OtlpResource.test.ts +84 -0
- package/repos/effect/packages/effect/test/unstable/observability/PrometheusMetrics.test.ts +417 -0
- package/repos/effect/packages/effect/test/unstable/persistence/KeyValueStore.test.ts +164 -0
- package/repos/effect/packages/effect/test/unstable/persistence/KeyValueStoreTest.ts +85 -0
- package/repos/effect/packages/effect/test/unstable/persistence/PersistedCache.test.ts +4 -0
- package/repos/effect/packages/effect/test/unstable/persistence/PersistedCacheTest.ts +111 -0
- package/repos/effect/packages/effect/test/unstable/persistence/PersistedQueue.test.ts +4 -0
- package/repos/effect/packages/effect/test/unstable/persistence/PersistedQueueTest.ts +106 -0
- package/repos/effect/packages/effect/test/unstable/persistence/RateLimiter.test.ts +145 -0
- package/repos/effect/packages/effect/test/unstable/persistence/Redis.test.ts +43 -0
- package/repos/effect/packages/effect/test/unstable/process/ChildProcess.test.ts +352 -0
- package/repos/effect/packages/effect/test/unstable/schema/VariantSchema.test.ts +72 -0
- package/repos/effect/packages/effect/test/unstable/sql/SqlError.test.ts +228 -0
- package/repos/effect/packages/effect/test/unstable/sql/SqlSchema.test.ts +168 -0
- package/repos/effect/packages/effect/test/unstable/workers/WorkerError.test.ts +90 -0
- package/repos/effect/packages/effect/test/unstable/workflow/DurableQueue.test.ts +105 -0
- package/repos/effect/packages/effect/test/unstable/workflow/WorkflowEngine.test.ts +60 -0
- package/repos/effect/packages/effect/test/utils/assert.ts +182 -0
- package/repos/effect/packages/effect/test/utils/chunkCoordination.ts +36 -0
- package/repos/effect/packages/effect/test/utils/counter.ts +54 -0
- package/repos/effect/packages/effect/tsconfig.json +8 -0
- package/repos/effect/packages/effect/typetest/AiError.tst.ts +49 -0
- package/repos/effect/packages/effect/typetest/Array.tst.ts +1289 -0
- package/repos/effect/packages/effect/typetest/Brand.tst.ts +51 -0
- package/repos/effect/packages/effect/typetest/Channel.tst.ts +112 -0
- package/repos/effect/packages/effect/typetest/Config.tst.ts +31 -0
- package/repos/effect/packages/effect/typetest/Data.tst.ts +121 -0
- package/repos/effect/packages/effect/typetest/Effect.tst.ts +976 -0
- package/repos/effect/packages/effect/typetest/Equivalence.tst.ts +19 -0
- package/repos/effect/packages/effect/typetest/Newtype.tst.ts +72 -0
- package/repos/effect/packages/effect/typetest/Optic.tst.ts +130 -0
- package/repos/effect/packages/effect/typetest/Option.tst.ts +72 -0
- package/repos/effect/packages/effect/typetest/Order.tst.ts +19 -0
- package/repos/effect/packages/effect/typetest/Predicate.tst.ts +251 -0
- package/repos/effect/packages/effect/typetest/Result.tst.ts +353 -0
- package/repos/effect/packages/effect/typetest/Schedule.tst.ts +21 -0
- package/repos/effect/packages/effect/typetest/Stream.tst.ts +197 -0
- package/repos/effect/packages/effect/typetest/Struct.tst.ts +422 -0
- package/repos/effect/packages/effect/typetest/Tuple.tst.ts +177 -0
- package/repos/effect/packages/effect/typetest/Types.tst.ts +364 -0
- package/repos/effect/packages/effect/typetest/VariantSchema.tst.ts +76 -0
- package/repos/effect/packages/effect/typetest/schema/Array.tst.ts +46 -0
- package/repos/effect/packages/effect/typetest/schema/Literals.tst.ts +58 -0
- package/repos/effect/packages/effect/typetest/schema/Record.tst.ts +145 -0
- package/repos/effect/packages/effect/typetest/schema/Schema.tst.ts +1854 -0
- package/repos/effect/packages/effect/typetest/schema/Struct.tst.ts +745 -0
- package/repos/effect/packages/effect/typetest/schema/Tuple.tst.ts +199 -0
- package/repos/effect/packages/effect/typetest/schema/Union.tst.ts +198 -0
- package/repos/effect/packages/effect/typetest/schema/api.tst.ts +276 -0
- package/repos/effect/packages/effect/typetest/schema/toArbitrary.tst.ts +65 -0
- package/repos/effect/packages/effect/typetest/schema/toIso.tst.ts +282 -0
- package/repos/effect/packages/effect/typetest/unstable/ai/LanguageModel.tst.ts +191 -0
- package/repos/effect/packages/effect/typetest/unstable/ai/Tool.tst.ts +33 -0
- package/repos/effect/packages/effect/typetest/unstable/cli/Command.tst.ts +124 -0
- package/repos/effect/packages/effect/typetest/unstable/cli/Param.tst.ts +20 -0
- package/repos/effect/packages/effect/typetest/unstable/cli/Prompt.tst.ts +97 -0
- package/repos/effect/packages/effect/typetest/unstable/encoding/Ndjson.tst.ts +24 -0
- package/repos/effect/packages/effect/typetest/unstable/http/HttpClient.tst.ts +143 -0
- package/repos/effect/packages/effect/typetest/unstable/httpapi/HttpApiBuilder.tst.ts +98 -0
- package/repos/effect/packages/effect/typetest/unstable/httpapi/HttpApiClient.tst.ts +677 -0
- package/repos/effect/packages/effect/typetest/unstable/httpapi/HttpApiEndpoint.tst.ts +466 -0
- package/repos/effect/packages/effect/typetest/unstable/httpapi/HttpApiMiddleware.tst.ts +90 -0
- package/repos/effect/packages/effect/typetest/unstable/httpapi/HttpApiSchema.tst.ts +135 -0
- package/repos/effect/packages/effect/typetest/unstable/reactivity/AsyncResult.tst.ts +65 -0
- package/repos/effect/packages/effect/typetest/unstable/reactivity/AtomHttpApi.tst.ts +63 -0
- package/repos/effect/packages/effect/typetest/unstable/rpc/Rpc.tst.ts +74 -0
- package/repos/effect/packages/effect/typetest/unstable/rpc/RpcGroup.tst.ts +61 -0
- package/repos/effect/packages/effect/typetest/unstable/rpc/RpcMiddleware.tst.ts +41 -0
- package/repos/effect/packages/effect/typetest/unstable/rpc/RpcServer.tst.ts +26 -0
- package/repos/effect/packages/effect/typetest/unstable/sql/SqlSchema.tst.ts +75 -0
- package/repos/effect/packages/effect/typetest/unstable/workflow/Workflow.tst.ts +16 -0
- package/repos/effect/packages/effect/vitest.config.ts +11 -0
- package/repos/effect/packages/opentelemetry/CHANGELOG.md +620 -0
- package/repos/effect/packages/opentelemetry/LICENSE +21 -0
- package/repos/effect/packages/opentelemetry/README.md +5 -0
- package/repos/effect/packages/opentelemetry/docgen.json +30 -0
- package/repos/effect/packages/opentelemetry/package.json +126 -0
- package/repos/effect/packages/opentelemetry/src/Logger.ts +193 -0
- package/repos/effect/packages/opentelemetry/src/Metrics.ts +138 -0
- package/repos/effect/packages/opentelemetry/src/NodeSdk.ts +162 -0
- package/repos/effect/packages/opentelemetry/src/Resource.ts +147 -0
- package/repos/effect/packages/opentelemetry/src/Tracer.ts +594 -0
- package/repos/effect/packages/opentelemetry/src/WebSdk.ts +140 -0
- package/repos/effect/packages/opentelemetry/src/index.ts +35 -0
- package/repos/effect/packages/opentelemetry/src/internal/attributes.ts +28 -0
- package/repos/effect/packages/opentelemetry/src/internal/metrics.ts +463 -0
- package/repos/effect/packages/opentelemetry/src/internal/utilities.ts +5 -0
- package/repos/effect/packages/opentelemetry/test/Logger.test.ts +122 -0
- package/repos/effect/packages/opentelemetry/test/Metrics.test.ts +339 -0
- package/repos/effect/packages/opentelemetry/test/Tracer.test.ts +167 -0
- package/repos/effect/packages/opentelemetry/tsconfig.json +8 -0
- package/repos/effect/packages/opentelemetry/vitest.config.ts +6 -0
- package/repos/effect/packages/platform-browser/CHANGELOG.md +637 -0
- package/repos/effect/packages/platform-browser/LICENSE +21 -0
- package/repos/effect/packages/platform-browser/README.md +1 -0
- package/repos/effect/packages/platform-browser/docgen.json +21 -0
- package/repos/effect/packages/platform-browser/package.json +74 -0
- package/repos/effect/packages/platform-browser/src/BrowserCrypto.ts +97 -0
- package/repos/effect/packages/platform-browser/src/BrowserHttpClient.ts +430 -0
- package/repos/effect/packages/platform-browser/src/BrowserKeyValueStore.ts +177 -0
- package/repos/effect/packages/platform-browser/src/BrowserPersistence.ts +334 -0
- package/repos/effect/packages/platform-browser/src/BrowserRuntime.ts +53 -0
- package/repos/effect/packages/platform-browser/src/BrowserSocket.ts +52 -0
- package/repos/effect/packages/platform-browser/src/BrowserStream.ts +56 -0
- package/repos/effect/packages/platform-browser/src/BrowserWorker.ts +98 -0
- package/repos/effect/packages/platform-browser/src/BrowserWorkerRunner.ts +199 -0
- package/repos/effect/packages/platform-browser/src/Clipboard.ts +143 -0
- package/repos/effect/packages/platform-browser/src/Geolocation.ts +233 -0
- package/repos/effect/packages/platform-browser/src/IndexedDb.ts +113 -0
- package/repos/effect/packages/platform-browser/src/IndexedDbDatabase.ts +648 -0
- package/repos/effect/packages/platform-browser/src/IndexedDbQueryBuilder.ts +2032 -0
- package/repos/effect/packages/platform-browser/src/IndexedDbTable.ts +260 -0
- package/repos/effect/packages/platform-browser/src/IndexedDbVersion.ts +138 -0
- package/repos/effect/packages/platform-browser/src/Permissions.ts +146 -0
- package/repos/effect/packages/platform-browser/src/index.ts +90 -0
- package/repos/effect/packages/platform-browser/test/BrowserCrypto.test.ts +74 -0
- package/repos/effect/packages/platform-browser/test/BrowserHttpClient.test.ts +91 -0
- package/repos/effect/packages/platform-browser/test/BrowserKeyValueStore.test.ts +23 -0
- package/repos/effect/packages/platform-browser/test/BrowserPersistence.test.ts +209 -0
- package/repos/effect/packages/platform-browser/test/BrowserPersistencePersistedCache.test.ts +29 -0
- package/repos/effect/packages/platform-browser/test/IndexedDbDatabase.test.ts +253 -0
- package/repos/effect/packages/platform-browser/test/IndexedDbQueryBuilder.test.ts +1459 -0
- package/repos/effect/packages/platform-browser/test/IndexedDbTable.test.ts +101 -0
- package/repos/effect/packages/platform-browser/test/IndexedDbVersion.test.ts +50 -0
- package/repos/effect/packages/platform-browser/test/Permissions.test.ts +12 -0
- package/repos/effect/packages/platform-browser/test/RpcWorker.test.ts +19 -0
- package/repos/effect/packages/platform-browser/test/fixtures/rpc-e2e.ts +141 -0
- package/repos/effect/packages/platform-browser/test/fixtures/rpc-schemas.ts +157 -0
- package/repos/effect/packages/platform-browser/test/fixtures/rpc-worker.ts +12 -0
- package/repos/effect/packages/platform-browser/tsconfig.json +8 -0
- package/repos/effect/packages/platform-browser/vitest.config.ts +17 -0
- package/repos/effect/packages/platform-browser/vitest.setup.ts +5 -0
- package/repos/effect/packages/platform-bun/CHANGELOG.md +691 -0
- package/repos/effect/packages/platform-bun/LICENSE +21 -0
- package/repos/effect/packages/platform-bun/README.md +7 -0
- package/repos/effect/packages/platform-bun/docgen.json +20 -0
- package/repos/effect/packages/platform-bun/package.json +73 -0
- package/repos/effect/packages/platform-bun/src/BunChildProcessSpawner.ts +6 -0
- package/repos/effect/packages/platform-bun/src/BunClusterHttp.ts +174 -0
- package/repos/effect/packages/platform-bun/src/BunClusterSocket.ts +153 -0
- package/repos/effect/packages/platform-bun/src/BunCrypto.ts +24 -0
- package/repos/effect/packages/platform-bun/src/BunFileSystem.ts +20 -0
- package/repos/effect/packages/platform-bun/src/BunHttpClient.ts +9 -0
- package/repos/effect/packages/platform-bun/src/BunHttpPlatform.ts +50 -0
- package/repos/effect/packages/platform-bun/src/BunHttpServer.ts +600 -0
- package/repos/effect/packages/platform-bun/src/BunHttpServerRequest.ts +19 -0
- package/repos/effect/packages/platform-bun/src/BunMultipart.ts +54 -0
- package/repos/effect/packages/platform-bun/src/BunPath.ts +37 -0
- package/repos/effect/packages/platform-bun/src/BunRedis.ts +88 -0
- package/repos/effect/packages/platform-bun/src/BunRuntime.ts +52 -0
- package/repos/effect/packages/platform-bun/src/BunServices.ts +49 -0
- package/repos/effect/packages/platform-bun/src/BunSink.ts +8 -0
- package/repos/effect/packages/platform-bun/src/BunSocket.ts +54 -0
- package/repos/effect/packages/platform-bun/src/BunSocketServer.ts +8 -0
- package/repos/effect/packages/platform-bun/src/BunStdio.ts +22 -0
- package/repos/effect/packages/platform-bun/src/BunStream.ts +68 -0
- package/repos/effect/packages/platform-bun/src/BunTerminal.ts +32 -0
- package/repos/effect/packages/platform-bun/src/BunWorker.ts +92 -0
- package/repos/effect/packages/platform-bun/src/BunWorkerRunner.ts +113 -0
- package/repos/effect/packages/platform-bun/src/index.ts +115 -0
- package/repos/effect/packages/platform-bun/tsconfig.json +12 -0
- package/repos/effect/packages/platform-node/CHANGELOG.md +695 -0
- package/repos/effect/packages/platform-node/LICENSE +21 -0
- package/repos/effect/packages/platform-node/README.md +7 -0
- package/repos/effect/packages/platform-node/docgen.json +24 -0
- package/repos/effect/packages/platform-node/package.json +82 -0
- package/repos/effect/packages/platform-node/src/Mime.ts +25 -0
- package/repos/effect/packages/platform-node/src/NodeChildProcessSpawner.ts +6 -0
- package/repos/effect/packages/platform-node/src/NodeClusterHttp.ts +155 -0
- package/repos/effect/packages/platform-node/src/NodeClusterSocket.ts +176 -0
- package/repos/effect/packages/platform-node/src/NodeCrypto.ts +24 -0
- package/repos/effect/packages/platform-node/src/NodeFileSystem.ts +21 -0
- package/repos/effect/packages/platform-node/src/NodeHttpClient.ts +664 -0
- package/repos/effect/packages/platform-node/src/NodeHttpIncomingMessage.ts +141 -0
- package/repos/effect/packages/platform-node/src/NodeHttpPlatform.ts +70 -0
- package/repos/effect/packages/platform-node/src/NodeHttpServer.ts +646 -0
- package/repos/effect/packages/platform-node/src/NodeHttpServerRequest.ts +33 -0
- package/repos/effect/packages/platform-node/src/NodeMultipart.ts +183 -0
- package/repos/effect/packages/platform-node/src/NodePath.ts +40 -0
- package/repos/effect/packages/platform-node/src/NodeRedis.ts +92 -0
- package/repos/effect/packages/platform-node/src/NodeRuntime.ts +53 -0
- package/repos/effect/packages/platform-node/src/NodeServices.ts +50 -0
- package/repos/effect/packages/platform-node/src/NodeSink.ts +8 -0
- package/repos/effect/packages/platform-node/src/NodeSocket.ts +72 -0
- package/repos/effect/packages/platform-node/src/NodeSocketServer.ts +8 -0
- package/repos/effect/packages/platform-node/src/NodeStdio.ts +22 -0
- package/repos/effect/packages/platform-node/src/NodeStream.ts +8 -0
- package/repos/effect/packages/platform-node/src/NodeTerminal.ts +32 -0
- package/repos/effect/packages/platform-node/src/NodeWorker.ts +121 -0
- package/repos/effect/packages/platform-node/src/NodeWorkerRunner.ts +110 -0
- package/repos/effect/packages/platform-node/src/Undici.ts +29 -0
- package/repos/effect/packages/platform-node/src/index.ts +130 -0
- package/repos/effect/packages/platform-node/test/HttpApi.test.ts +1831 -0
- package/repos/effect/packages/platform-node/test/HttpStaticServer.test.ts +253 -0
- package/repos/effect/packages/platform-node/test/HttpStaticServerConditional.test.ts +296 -0
- package/repos/effect/packages/platform-node/test/NodeCrypto.test.ts +59 -0
- package/repos/effect/packages/platform-node/test/NodeHttpClient.test.ts +157 -0
- package/repos/effect/packages/platform-node/test/NodeHttpPlatform.test.ts +51 -0
- package/repos/effect/packages/platform-node/test/NodeHttpServer.test.ts +598 -0
- package/repos/effect/packages/platform-node/test/NodeRedis.test.ts +31 -0
- package/repos/effect/packages/platform-node/test/NodeSocket.test.ts +153 -0
- package/repos/effect/packages/platform-node/test/OpenApi.test.ts +1573 -0
- package/repos/effect/packages/platform-node/test/RpcServer.test.ts +213 -0
- package/repos/effect/packages/platform-node/test/__snapshots__/HttpApi.test.ts.snap +715 -0
- package/repos/effect/packages/platform-node/test/cluster/MessageStorageTest.ts +196 -0
- package/repos/effect/packages/platform-node/test/cluster/SocketRunner.test.ts +120 -0
- package/repos/effect/packages/platform-node/test/cluster/SqlMessageStorage.test.ts +222 -0
- package/repos/effect/packages/platform-node/test/cluster/SqlRunnerStorage.test.ts +101 -0
- package/repos/effect/packages/platform-node/test/fixtures/http-static-server/conditional.txt +1 -0
- package/repos/effect/packages/platform-node/test/fixtures/http-static-server/custom/home.html +1 -0
- package/repos/effect/packages/platform-node/test/fixtures/http-static-server/file.binx +1 -0
- package/repos/effect/packages/platform-node/test/fixtures/http-static-server/guide/index.html +1 -0
- package/repos/effect/packages/platform-node/test/fixtures/http-static-server/hello.txt +1 -0
- package/repos/effect/packages/platform-node/test/fixtures/http-static-server/index.html +1 -0
- package/repos/effect/packages/platform-node/test/fixtures/http-static-server/range.txt +1 -0
- package/repos/effect/packages/platform-node/test/fixtures/http-static-server-outside.txt +1 -0
- package/repos/effect/packages/platform-node/test/fixtures/mysql2-utils.ts +64 -0
- package/repos/effect/packages/platform-node/test/fixtures/pg-utils.ts +39 -0
- package/repos/effect/packages/platform-node/test/fixtures/rpc-e2e.ts +149 -0
- package/repos/effect/packages/platform-node/test/fixtures/rpc-schemas.ts +175 -0
- package/repos/effect/packages/platform-node/test/fixtures/text.txt +1 -0
- package/repos/effect/packages/platform-node/tsconfig.json +12 -0
- package/repos/effect/packages/platform-node/vitest.config.ts +6 -0
- package/repos/effect/packages/platform-node-shared/CHANGELOG.md +617 -0
- package/repos/effect/packages/platform-node-shared/LICENSE +21 -0
- package/repos/effect/packages/platform-node-shared/README.md +7 -0
- package/repos/effect/packages/platform-node-shared/docgen.json +38 -0
- package/repos/effect/packages/platform-node-shared/package.json +76 -0
- package/repos/effect/packages/platform-node-shared/src/NodeChildProcessSpawner.ts +713 -0
- package/repos/effect/packages/platform-node-shared/src/NodeClusterSocket.ts +70 -0
- package/repos/effect/packages/platform-node-shared/src/NodeCrypto.ts +60 -0
- package/repos/effect/packages/platform-node-shared/src/NodeFileSystem.ts +652 -0
- package/repos/effect/packages/platform-node-shared/src/NodePath.ts +80 -0
- package/repos/effect/packages/platform-node-shared/src/NodeRuntime.ts +59 -0
- package/repos/effect/packages/platform-node-shared/src/NodeSink.ts +116 -0
- package/repos/effect/packages/platform-node-shared/src/NodeSocket.ts +269 -0
- package/repos/effect/packages/platform-node-shared/src/NodeSocketServer.ts +301 -0
- package/repos/effect/packages/platform-node-shared/src/NodeStdio.ts +67 -0
- package/repos/effect/packages/platform-node-shared/src/NodeStream.ts +445 -0
- package/repos/effect/packages/platform-node-shared/src/NodeTerminal.ts +129 -0
- package/repos/effect/packages/platform-node-shared/src/index.ts +65 -0
- package/repos/effect/packages/platform-node-shared/src/internal/utils.ts +51 -0
- package/repos/effect/packages/platform-node-shared/test/NodeChildProcessSpawner.test.ts +1069 -0
- package/repos/effect/packages/platform-node-shared/test/NodeFileSystem.test.ts +214 -0
- package/repos/effect/packages/platform-node-shared/test/NodeSink.test.ts +153 -0
- package/repos/effect/packages/platform-node-shared/test/NodeStream.test.ts +173 -0
- package/repos/effect/packages/platform-node-shared/test/fixtures/bash/no-permissions.sh +3 -0
- package/repos/effect/packages/platform-node-shared/test/fixtures/bash/parent-exits-early.sh +31 -0
- package/repos/effect/packages/platform-node-shared/test/fixtures/bash/spawn-children.sh +32 -0
- package/repos/effect/packages/platform-node-shared/test/fixtures/config/SHOUTING +1 -0
- package/repos/effect/packages/platform-node-shared/test/fixtures/config/integer +1 -0
- package/repos/effect/packages/platform-node-shared/test/fixtures/config/nested/config +1 -0
- package/repos/effect/packages/platform-node-shared/test/fixtures/config/secret +1 -0
- package/repos/effect/packages/platform-node-shared/test/fixtures/helloworld.tar.gz +0 -0
- package/repos/effect/packages/platform-node-shared/test/fixtures/text.txt +1 -0
- package/repos/effect/packages/platform-node-shared/tsconfig.json +11 -0
- package/repos/effect/packages/platform-node-shared/vitest.config.ts +6 -0
- package/repos/effect/packages/sql/clickhouse/CHANGELOG.md +681 -0
- package/repos/effect/packages/sql/clickhouse/LICENSE +21 -0
- package/repos/effect/packages/sql/clickhouse/README.md +7 -0
- package/repos/effect/packages/sql/clickhouse/docgen.json +24 -0
- package/repos/effect/packages/sql/clickhouse/package.json +72 -0
- package/repos/effect/packages/sql/clickhouse/src/ClickhouseClient.ts +546 -0
- package/repos/effect/packages/sql/clickhouse/src/ClickhouseMigrator.ts +51 -0
- package/repos/effect/packages/sql/clickhouse/src/index.ts +15 -0
- package/repos/effect/packages/sql/clickhouse/test/Client.test.ts +6 -0
- package/repos/effect/packages/sql/clickhouse/test/SqlErrorClassification.test.ts +75 -0
- package/repos/effect/packages/sql/clickhouse/tsconfig.json +12 -0
- package/repos/effect/packages/sql/clickhouse/vitest.config.ts +6 -0
- package/repos/effect/packages/sql/d1/CHANGELOG.md +597 -0
- package/repos/effect/packages/sql/d1/LICENSE +21 -0
- package/repos/effect/packages/sql/d1/README.md +7 -0
- package/repos/effect/packages/sql/d1/docgen.json +24 -0
- package/repos/effect/packages/sql/d1/package.json +75 -0
- package/repos/effect/packages/sql/d1/src/D1Client.ts +249 -0
- package/repos/effect/packages/sql/d1/src/index.ts +10 -0
- package/repos/effect/packages/sql/d1/test/Client.test.ts +65 -0
- package/repos/effect/packages/sql/d1/test/Resolver.test.ts +176 -0
- package/repos/effect/packages/sql/d1/test/utils.ts +38 -0
- package/repos/effect/packages/sql/d1/tsconfig.json +8 -0
- package/repos/effect/packages/sql/d1/vitest.config.ts +6 -0
- package/repos/effect/packages/sql/libsql/CHANGELOG.md +601 -0
- package/repos/effect/packages/sql/libsql/LICENSE +21 -0
- package/repos/effect/packages/sql/libsql/README.md +7 -0
- package/repos/effect/packages/sql/libsql/docgen.json +24 -0
- package/repos/effect/packages/sql/libsql/package.json +73 -0
- package/repos/effect/packages/sql/libsql/src/LibsqlClient.ts +381 -0
- package/repos/effect/packages/sql/libsql/src/LibsqlMigrator.ts +46 -0
- package/repos/effect/packages/sql/libsql/src/index.ts +15 -0
- package/repos/effect/packages/sql/libsql/test/Client.test.ts +106 -0
- package/repos/effect/packages/sql/libsql/test/Resolver.test.ts +177 -0
- package/repos/effect/packages/sql/libsql/test/util.ts +54 -0
- package/repos/effect/packages/sql/libsql/tsconfig.json +9 -0
- package/repos/effect/packages/sql/libsql/vitest.config.ts +6 -0
- package/repos/effect/packages/sql/mssql/CHANGELOG.md +601 -0
- package/repos/effect/packages/sql/mssql/LICENSE +21 -0
- package/repos/effect/packages/sql/mssql/README.md +7 -0
- package/repos/effect/packages/sql/mssql/docgen.json +24 -0
- package/repos/effect/packages/sql/mssql/package.json +70 -0
- package/repos/effect/packages/sql/mssql/src/MssqlClient.ts +732 -0
- package/repos/effect/packages/sql/mssql/src/MssqlMigrator.ts +45 -0
- package/repos/effect/packages/sql/mssql/src/Parameter.ts +64 -0
- package/repos/effect/packages/sql/mssql/src/Procedure.ts +213 -0
- package/repos/effect/packages/sql/mssql/src/index.ts +32 -0
- package/repos/effect/packages/sql/mssql/test/Client.test.ts +91 -0
- package/repos/effect/packages/sql/mssql/test/SqlErrorClassification.test.ts +206 -0
- package/repos/effect/packages/sql/mssql/tsconfig.json +8 -0
- package/repos/effect/packages/sql/mssql/vitest.config.ts +6 -0
- package/repos/effect/packages/sql/mysql2/CHANGELOG.md +603 -0
- package/repos/effect/packages/sql/mysql2/LICENSE +21 -0
- package/repos/effect/packages/sql/mysql2/README.md +7 -0
- package/repos/effect/packages/sql/mysql2/docgen.json +24 -0
- package/repos/effect/packages/sql/mysql2/package.json +71 -0
- package/repos/effect/packages/sql/mysql2/src/MysqlClient.ts +517 -0
- package/repos/effect/packages/sql/mysql2/src/MysqlMigrator.ts +102 -0
- package/repos/effect/packages/sql/mysql2/src/index.ts +15 -0
- package/repos/effect/packages/sql/mysql2/test/Client.test.ts +34 -0
- package/repos/effect/packages/sql/mysql2/test/KeyValueStore.test.ts +16 -0
- package/repos/effect/packages/sql/mysql2/test/Model.test.ts +227 -0
- package/repos/effect/packages/sql/mysql2/test/MysqlClient.test.ts +35 -0
- package/repos/effect/packages/sql/mysql2/test/Persistence.test.ts +22 -0
- package/repos/effect/packages/sql/mysql2/test/SqlErrorClassification.test.ts +133 -0
- package/repos/effect/packages/sql/mysql2/test/SqlEventLogServerUnencrypted.test.ts +7 -0
- package/repos/effect/packages/sql/mysql2/test/utils.ts +64 -0
- package/repos/effect/packages/sql/mysql2/tsconfig.json +9 -0
- package/repos/effect/packages/sql/mysql2/vitest.config.ts +6 -0
- package/repos/effect/packages/sql/pg/CHANGELOG.md +3432 -0
- package/repos/effect/packages/sql/pg/LICENSE +21 -0
- package/repos/effect/packages/sql/pg/README.md +7 -0
- package/repos/effect/packages/sql/pg/docgen.json +24 -0
- package/repos/effect/packages/sql/pg/package.json +77 -0
- package/repos/effect/packages/sql/pg/src/PgClient.ts +947 -0
- package/repos/effect/packages/sql/pg/src/PgMigrator.ts +120 -0
- package/repos/effect/packages/sql/pg/src/index.ts +15 -0
- package/repos/effect/packages/sql/pg/test/Client.test.ts +373 -0
- package/repos/effect/packages/sql/pg/test/KeyValueStore.test.ts +16 -0
- package/repos/effect/packages/sql/pg/test/Persistence.test.ts +20 -0
- package/repos/effect/packages/sql/pg/test/SqlErrorClassification.test.ts +81 -0
- package/repos/effect/packages/sql/pg/test/SqlEventLogServerUnencrypted.test.ts +7 -0
- package/repos/effect/packages/sql/pg/test/TransactionAcquire.test.ts +52 -0
- package/repos/effect/packages/sql/pg/test/utils.ts +49 -0
- package/repos/effect/packages/sql/pg/tsconfig.json +9 -0
- package/repos/effect/packages/sql/pg/vitest.config.ts +6 -0
- package/repos/effect/packages/sql/pglite/CHANGELOG.md +198 -0
- package/repos/effect/packages/sql/pglite/LICENSE +21 -0
- package/repos/effect/packages/sql/pglite/README.md +7 -0
- package/repos/effect/packages/sql/pglite/docgen.json +24 -0
- package/repos/effect/packages/sql/pglite/package.json +74 -0
- package/repos/effect/packages/sql/pglite/src/PgliteClient.ts +503 -0
- package/repos/effect/packages/sql/pglite/src/PgliteMigrator.ts +44 -0
- package/repos/effect/packages/sql/pglite/src/index.ts +15 -0
- package/repos/effect/packages/sql/pglite/test/Client.test.ts +149 -0
- package/repos/effect/packages/sql/pglite/test/Migrator.test.ts +45 -0
- package/repos/effect/packages/sql/pglite/test/SqlErrorClassification.test.ts +56 -0
- package/repos/effect/packages/sql/pglite/test/Transaction.test.ts +62 -0
- package/repos/effect/packages/sql/pglite/tsconfig.json +8 -0
- package/repos/effect/packages/sql/pglite/vitest.config.ts +6 -0
- package/repos/effect/packages/sql/sqlite-bun/CHANGELOG.md +601 -0
- package/repos/effect/packages/sql/sqlite-bun/LICENSE +21 -0
- package/repos/effect/packages/sql/sqlite-bun/README.md +7 -0
- package/repos/effect/packages/sql/sqlite-bun/docgen.json +24 -0
- package/repos/effect/packages/sql/sqlite-bun/package.json +69 -0
- package/repos/effect/packages/sql/sqlite-bun/src/SqliteClient.ts +262 -0
- package/repos/effect/packages/sql/sqlite-bun/src/SqliteMigrator.ts +90 -0
- package/repos/effect/packages/sql/sqlite-bun/src/index.ts +15 -0
- package/repos/effect/packages/sql/sqlite-bun/test/Client.test.ts +6 -0
- package/repos/effect/packages/sql/sqlite-bun/tsconfig.json +11 -0
- package/repos/effect/packages/sql/sqlite-bun/vitest.config.ts +6 -0
- package/repos/effect/packages/sql/sqlite-do/CHANGELOG.md +601 -0
- package/repos/effect/packages/sql/sqlite-do/LICENSE +21 -0
- package/repos/effect/packages/sql/sqlite-do/README.md +7 -0
- package/repos/effect/packages/sql/sqlite-do/docgen.json +24 -0
- package/repos/effect/packages/sql/sqlite-do/package.json +68 -0
- package/repos/effect/packages/sql/sqlite-do/src/SqliteClient.ts +249 -0
- package/repos/effect/packages/sql/sqlite-do/src/SqliteMigrator.ts +45 -0
- package/repos/effect/packages/sql/sqlite-do/src/index.ts +15 -0
- package/repos/effect/packages/sql/sqlite-do/test/Client.test.ts +24 -0
- package/repos/effect/packages/sql/sqlite-do/tsconfig.json +8 -0
- package/repos/effect/packages/sql/sqlite-do/vitest.config.ts +6 -0
- package/repos/effect/packages/sql/sqlite-node/CHANGELOG.md +3415 -0
- package/repos/effect/packages/sql/sqlite-node/LICENSE +21 -0
- package/repos/effect/packages/sql/sqlite-node/README.md +7 -0
- package/repos/effect/packages/sql/sqlite-node/docgen.json +24 -0
- package/repos/effect/packages/sql/sqlite-node/package.json +72 -0
- package/repos/effect/packages/sql/sqlite-node/src/SqliteClient.ts +312 -0
- package/repos/effect/packages/sql/sqlite-node/src/SqliteMigrator.ts +90 -0
- package/repos/effect/packages/sql/sqlite-node/src/index.ts +15 -0
- package/repos/effect/packages/sql/sqlite-node/test/Client.test.ts +75 -0
- package/repos/effect/packages/sql/sqlite-node/test/KeyValueStore.test.ts +29 -0
- package/repos/effect/packages/sql/sqlite-node/test/Persistence.test.ts +109 -0
- package/repos/effect/packages/sql/sqlite-node/test/Resolver.test.ts +183 -0
- package/repos/effect/packages/sql/sqlite-node/test/SqlEventJournal.test.ts +84 -0
- package/repos/effect/packages/sql/sqlite-node/test/SqlEventLogServerEncrypted.test.ts +249 -0
- package/repos/effect/packages/sql/sqlite-node/test/SqlEventLogServerUnencrypted.test.ts +110 -0
- package/repos/effect/packages/sql/sqlite-node/test/SqliteMigrator.test.ts +48 -0
- package/repos/effect/packages/sql/sqlite-node/tsconfig.json +8 -0
- package/repos/effect/packages/sql/sqlite-node/vitest.config.ts +6 -0
- package/repos/effect/packages/sql/sqlite-react-native/CHANGELOG.md +601 -0
- package/repos/effect/packages/sql/sqlite-react-native/LICENSE +21 -0
- package/repos/effect/packages/sql/sqlite-react-native/README.md +7 -0
- package/repos/effect/packages/sql/sqlite-react-native/docgen.json +24 -0
- package/repos/effect/packages/sql/sqlite-react-native/package.json +69 -0
- package/repos/effect/packages/sql/sqlite-react-native/src/SqliteClient.ts +354 -0
- package/repos/effect/packages/sql/sqlite-react-native/src/SqliteMigrator.ts +55 -0
- package/repos/effect/packages/sql/sqlite-react-native/src/index.ts +15 -0
- package/repos/effect/packages/sql/sqlite-react-native/test/Client.test.ts +6 -0
- package/repos/effect/packages/sql/sqlite-react-native/tsconfig.json +8 -0
- package/repos/effect/packages/sql/sqlite-react-native/vitest.config.ts +6 -0
- package/repos/effect/packages/sql/sqlite-wasm/CHANGELOG.md +601 -0
- package/repos/effect/packages/sql/sqlite-wasm/LICENSE +21 -0
- package/repos/effect/packages/sql/sqlite-wasm/README.md +7 -0
- package/repos/effect/packages/sql/sqlite-wasm/docgen.json +24 -0
- package/repos/effect/packages/sql/sqlite-wasm/package.json +69 -0
- package/repos/effect/packages/sql/sqlite-wasm/src/OpfsWorker.ts +118 -0
- package/repos/effect/packages/sql/sqlite-wasm/src/SqliteClient.ts +551 -0
- package/repos/effect/packages/sql/sqlite-wasm/src/SqliteMigrator.ts +55 -0
- package/repos/effect/packages/sql/sqlite-wasm/src/index.ts +14 -0
- package/repos/effect/packages/sql/sqlite-wasm/src/internal/opfsWorker.ts +7 -0
- package/repos/effect/packages/sql/sqlite-wasm/src/sqlite-wasm.d.ts +47 -0
- package/repos/effect/packages/sql/sqlite-wasm/test/Client.test.ts +6 -0
- package/repos/effect/packages/sql/sqlite-wasm/tsconfig.json +8 -0
- package/repos/effect/packages/sql/sqlite-wasm/vitest.config.ts +6 -0
- package/repos/effect/packages/tools/ai-codegen/codegen.schema.json +92 -0
- package/repos/effect/packages/tools/ai-codegen/docgen.json +4 -0
- package/repos/effect/packages/tools/ai-codegen/package.json +61 -0
- package/repos/effect/packages/tools/ai-codegen/src/Config.ts +292 -0
- package/repos/effect/packages/tools/ai-codegen/src/Discovery.ts +197 -0
- package/repos/effect/packages/tools/ai-codegen/src/Generator.ts +183 -0
- package/repos/effect/packages/tools/ai-codegen/src/Glob.ts +56 -0
- package/repos/effect/packages/tools/ai-codegen/src/PostProcess.ts +157 -0
- package/repos/effect/packages/tools/ai-codegen/src/SpecFetcher.ts +154 -0
- package/repos/effect/packages/tools/ai-codegen/src/bin.ts +10 -0
- package/repos/effect/packages/tools/ai-codegen/src/main.ts +237 -0
- package/repos/effect/packages/tools/ai-codegen/tsconfig.json +15 -0
- package/repos/effect/packages/tools/ai-docgen/docgen.json +4 -0
- package/repos/effect/packages/tools/ai-docgen/package.json +60 -0
- package/repos/effect/packages/tools/ai-docgen/src/Glob.ts +48 -0
- package/repos/effect/packages/tools/ai-docgen/src/main.ts +186 -0
- package/repos/effect/packages/tools/ai-docgen/tsconfig.json +14 -0
- package/repos/effect/packages/tools/bundle/docgen.json +4 -0
- package/repos/effect/packages/tools/bundle/fixtures/basic.ts +3 -0
- package/repos/effect/packages/tools/bundle/fixtures/batching.ts +25 -0
- package/repos/effect/packages/tools/bundle/fixtures/brand.ts +5 -0
- package/repos/effect/packages/tools/bundle/fixtures/cache.ts +10 -0
- package/repos/effect/packages/tools/bundle/fixtures/config.ts +13 -0
- package/repos/effect/packages/tools/bundle/fixtures/differ.ts +9 -0
- package/repos/effect/packages/tools/bundle/fixtures/http-client.ts +12 -0
- package/repos/effect/packages/tools/bundle/fixtures/logger.ts +5 -0
- package/repos/effect/packages/tools/bundle/fixtures/metric.ts +13 -0
- package/repos/effect/packages/tools/bundle/fixtures/optic.ts +6 -0
- package/repos/effect/packages/tools/bundle/fixtures/pubsub.ts +22 -0
- package/repos/effect/packages/tools/bundle/fixtures/queue.ts +18 -0
- package/repos/effect/packages/tools/bundle/fixtures/schedule.ts +9 -0
- package/repos/effect/packages/tools/bundle/fixtures/schema-fromJsonSchemaDocument.ts +16 -0
- package/repos/effect/packages/tools/bundle/fixtures/schema-representation-roundtrip.ts +16 -0
- package/repos/effect/packages/tools/bundle/fixtures/schema-string-transformation.ts +20 -0
- package/repos/effect/packages/tools/bundle/fixtures/schema-string.ts +8 -0
- package/repos/effect/packages/tools/bundle/fixtures/schema-template-literal.ts +8 -0
- package/repos/effect/packages/tools/bundle/fixtures/schema-toArbitraryLazy.ts +9 -0
- package/repos/effect/packages/tools/bundle/fixtures/schema-toCodeDocument.ts +12 -0
- package/repos/effect/packages/tools/bundle/fixtures/schema-toCodecJson.ts +9 -0
- package/repos/effect/packages/tools/bundle/fixtures/schema-toEquivalence.ts +9 -0
- package/repos/effect/packages/tools/bundle/fixtures/schema-toFormatter.ts +9 -0
- package/repos/effect/packages/tools/bundle/fixtures/schema-toJsonSchemaDocument.ts +9 -0
- package/repos/effect/packages/tools/bundle/fixtures/schema-toRepresentation.ts +9 -0
- package/repos/effect/packages/tools/bundle/fixtures/schema.ts +12 -0
- package/repos/effect/packages/tools/bundle/fixtures/stm.ts +21 -0
- package/repos/effect/packages/tools/bundle/fixtures/stream.ts +7 -0
- package/repos/effect/packages/tools/bundle/package.json +52 -0
- package/repos/effect/packages/tools/bundle/src/Cli.ts +104 -0
- package/repos/effect/packages/tools/bundle/src/Fixtures.ts +51 -0
- package/repos/effect/packages/tools/bundle/src/Plugins.ts +131 -0
- package/repos/effect/packages/tools/bundle/src/Reporter.ts +200 -0
- package/repos/effect/packages/tools/bundle/src/Rollup.ts +179 -0
- package/repos/effect/packages/tools/bundle/src/bin.ts +23 -0
- package/repos/effect/packages/tools/bundle/tsconfig.fixtures.json +13 -0
- package/repos/effect/packages/tools/bundle/tsconfig.json +9 -0
- package/repos/effect/packages/tools/bundle/tsconfig.src.json +13 -0
- package/repos/effect/packages/tools/jsdocs/docgen.json +4 -0
- package/repos/effect/packages/tools/jsdocs/package.json +64 -0
- package/repos/effect/packages/tools/jsdocs/src/Jsdocs.ts +3303 -0
- package/repos/effect/packages/tools/jsdocs/src/bin.ts +23 -0
- package/repos/effect/packages/tools/jsdocs/test/jsdocs.test.ts +979 -0
- package/repos/effect/packages/tools/jsdocs/tsconfig.json +8 -0
- package/repos/effect/packages/tools/jsdocs/vitest.config.ts +6 -0
- package/repos/effect/packages/tools/openapi-generator/CHANGELOG.md +691 -0
- package/repos/effect/packages/tools/openapi-generator/LICENSE +21 -0
- package/repos/effect/packages/tools/openapi-generator/docgen.json +4 -0
- package/repos/effect/packages/tools/openapi-generator/package.json +78 -0
- package/repos/effect/packages/tools/openapi-generator/src/HttpApiTransformer.ts +552 -0
- package/repos/effect/packages/tools/openapi-generator/src/JsonSchemaGenerator.ts +319 -0
- package/repos/effect/packages/tools/openapi-generator/src/OpenApiGenerator.ts +1201 -0
- package/repos/effect/packages/tools/openapi-generator/src/OpenApiPatch.ts +539 -0
- package/repos/effect/packages/tools/openapi-generator/src/OpenApiTransformer.ts +1019 -0
- package/repos/effect/packages/tools/openapi-generator/src/ParsedOperation.ts +277 -0
- package/repos/effect/packages/tools/openapi-generator/src/Utils.ts +111 -0
- package/repos/effect/packages/tools/openapi-generator/src/bin.ts +10 -0
- package/repos/effect/packages/tools/openapi-generator/src/main.ts +116 -0
- package/repos/effect/packages/tools/openapi-generator/test/JsonSchemaGenerator.test.ts +173 -0
- package/repos/effect/packages/tools/openapi-generator/test/OpenApiGenerator.test.ts +2130 -0
- package/repos/effect/packages/tools/openapi-generator/test/OpenApiGeneratorCli.test.ts +147 -0
- package/repos/effect/packages/tools/openapi-generator/test/OpenApiPatch.test.ts +380 -0
- package/repos/effect/packages/tools/openapi-generator/test/Utils.test.ts +33 -0
- package/repos/effect/packages/tools/openapi-generator/test/fixtures/cli-basic-spec.json +35 -0
- package/repos/effect/packages/tools/openapi-generator/test/fixtures/cli-warning-spec.json +57 -0
- package/repos/effect/packages/tools/openapi-generator/test/fixtures/patches/invalid-op.json +7 -0
- package/repos/effect/packages/tools/openapi-generator/test/fixtures/patches/missing-path.json +6 -0
- package/repos/effect/packages/tools/openapi-generator/test/fixtures/patches/missing-value.json +6 -0
- package/repos/effect/packages/tools/openapi-generator/test/fixtures/patches/valid-add.json +8 -0
- package/repos/effect/packages/tools/openapi-generator/test/fixtures/patches/valid-multiple.json +17 -0
- package/repos/effect/packages/tools/openapi-generator/test/fixtures/patches/valid-patch.yaml +6 -0
- package/repos/effect/packages/tools/openapi-generator/test/fixtures/patches/valid-remove.json +6 -0
- package/repos/effect/packages/tools/openapi-generator/test/fixtures/patches/valid-replace.json +7 -0
- package/repos/effect/packages/tools/openapi-generator/tsconfig.json +9 -0
- package/repos/effect/packages/tools/openapi-generator/vitest.config.ts +6 -0
- package/repos/effect/packages/tools/oxc/docgen.json +4 -0
- package/repos/effect/packages/tools/oxc/oxlintrc.json +83 -0
- package/repos/effect/packages/tools/oxc/package.json +72 -0
- package/repos/effect/packages/tools/oxc/src/oxlint/index.ts +18 -0
- package/repos/effect/packages/tools/oxc/src/oxlint/rules/jsdocs.ts +108 -0
- package/repos/effect/packages/tools/oxc/src/oxlint/rules/no-bigint-literals.ts +25 -0
- package/repos/effect/packages/tools/oxc/src/oxlint/rules/no-import-from-barrel-package.ts +144 -0
- package/repos/effect/packages/tools/oxc/src/oxlint/rules/no-js-extension-imports.ts +73 -0
- package/repos/effect/packages/tools/oxc/src/oxlint/rules/no-opaque-instance-fields.ts +92 -0
- package/repos/effect/packages/tools/oxc/test/jsdocs.test.ts +75 -0
- package/repos/effect/packages/tools/oxc/test/no-import-from-barrel-package.test.ts +182 -0
- package/repos/effect/packages/tools/oxc/test/no-js-extension-imports.test.ts +120 -0
- package/repos/effect/packages/tools/oxc/test/no-opaque-instance-fields.test.ts +276 -0
- package/repos/effect/packages/tools/oxc/test/utils.ts +61 -0
- package/repos/effect/packages/tools/oxc/tsconfig.json +8 -0
- package/repos/effect/packages/tools/oxc/vitest.config.ts +6 -0
- package/repos/effect/packages/tools/utils/docgen.json +4 -0
- package/repos/effect/packages/tools/utils/package.json +59 -0
- package/repos/effect/packages/tools/utils/src/Codegen.ts +214 -0
- package/repos/effect/packages/tools/utils/src/Glob.ts +61 -0
- package/repos/effect/packages/tools/utils/src/bin.ts +16 -0
- package/repos/effect/packages/tools/utils/src/commands/codegen.ts +44 -0
- package/repos/effect/packages/tools/utils/tsconfig.json +9 -0
- package/repos/effect/packages/vitest/CHANGELOG.md +601 -0
- package/repos/effect/packages/vitest/LICENSE +21 -0
- package/repos/effect/packages/vitest/README.md +320 -0
- package/repos/effect/packages/vitest/docgen.json +24 -0
- package/repos/effect/packages/vitest/package.json +60 -0
- package/repos/effect/packages/vitest/src/index.ts +259 -0
- package/repos/effect/packages/vitest/src/internal/internal.ts +374 -0
- package/repos/effect/packages/vitest/src/utils.ts +321 -0
- package/repos/effect/packages/vitest/test/index.test.ts +222 -0
- package/repos/effect/packages/vitest/test/isolation.test.ts +105 -0
- package/repos/effect/packages/vitest/test/nested-isolation.test.ts +212 -0
- package/repos/effect/packages/vitest/tsconfig.json +11 -0
- package/repos/effect/packages/vitest/typetest/index.tst.ts +56 -0
- package/repos/effect/packages/vitest/vitest.config.ts +6 -0
- package/repos/effect/patches/@changesets__assemble-release-plan.patch +26 -0
- package/repos/effect/patches/@changesets__get-github-info.patch +44 -0
- package/repos/effect/pnpm-lock.yaml +13483 -0
- package/repos/effect/pnpm-workspace.yaml +10 -0
- package/repos/effect/scripts/bundle-compare.sh +42 -0
- package/repos/effect/scripts/check-cookbook-schedule.ts +390 -0
- package/repos/effect/scripts/circular.mjs +26 -0
- package/repos/effect/scripts/clean.mjs +19 -0
- package/repos/effect/scripts/codemod.mjs +22 -0
- package/repos/effect/scripts/codemods/jsdoc.ts +79 -0
- package/repos/effect/scripts/docs.mjs +64 -0
- package/repos/effect/scripts/package-scalar.mjs +14 -0
- package/repos/effect/scripts/package-swagger.mjs +23 -0
- package/repos/effect/scripts/package.json +22 -0
- package/repos/effect/scripts/tsconfig.json +18 -0
- package/repos/effect/scripts/version.mjs +9 -0
- package/repos/effect/scripts/version.template.txt +2 -0
- package/repos/effect/scripts/worktree-setup.sh +27 -0
- package/repos/effect/stats.txt +30 -0
- package/repos/effect/tsconfig.base.json +46 -0
- package/repos/effect/tsconfig.json +128 -0
- package/repos/effect/tsconfig.packages.json +39 -0
- package/repos/effect/tstyche.json +7 -0
- package/repos/effect/vitest.config.ts +31 -0
- package/repos/effect/vitest.setup.ts +4 -0
- package/repos/effect/vitest.shared.ts +61 -0
- package/repos/effect.subtree.json +16 -0
|
@@ -0,0 +1,3564 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Describes policies for retrying, repeating, and pacing Effect programs.
|
|
3
|
+
*
|
|
4
|
+
* A `Schedule<Output, Input, Error, Env>` is stepped with an input value. Each
|
|
5
|
+
* step either stops or produces an output together with the delay before the
|
|
6
|
+
* next step. Schedules are used by retry, repeat, stream, and channel APIs to
|
|
7
|
+
* decide when work should continue, how long to wait, and when to stop.
|
|
8
|
+
*
|
|
9
|
+
* @since 2.0.0
|
|
10
|
+
*/
|
|
11
|
+
import * as Cause from "./Cause.ts"
|
|
12
|
+
import * as Context from "./Context.ts"
|
|
13
|
+
import * as Cron from "./Cron.ts"
|
|
14
|
+
import type * as DateTime from "./DateTime.ts"
|
|
15
|
+
import * as Duration from "./Duration.ts"
|
|
16
|
+
import type { Effect } from "./Effect.ts"
|
|
17
|
+
import type { LazyArg } from "./Function.ts"
|
|
18
|
+
import { constant, dual, identity } from "./Function.ts"
|
|
19
|
+
import { isEffect } from "./internal/core.ts"
|
|
20
|
+
import * as effect from "./internal/effect.ts"
|
|
21
|
+
import * as random from "./internal/random.ts"
|
|
22
|
+
import { type Pipeable, pipeArguments } from "./Pipeable.ts"
|
|
23
|
+
import { hasProperty } from "./Predicate.ts"
|
|
24
|
+
import * as Pull from "./Pull.ts"
|
|
25
|
+
import * as Result from "./Result.ts"
|
|
26
|
+
import type { Contravariant, Covariant, Mutable } from "./Types.ts"
|
|
27
|
+
|
|
28
|
+
const TypeId = "~effect/Schedule"
|
|
29
|
+
|
|
30
|
+
const randomNext: Effect<number> = random.Random.useSync((random) => random.nextDoubleUnsafe())
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* A Schedule defines a strategy for repeating or retrying effects based on some policy.
|
|
34
|
+
*
|
|
35
|
+
* **Example** (Defining retry and repeat schedules)
|
|
36
|
+
*
|
|
37
|
+
* ```ts
|
|
38
|
+
* import { Console, Data, Effect, Schedule } from "effect"
|
|
39
|
+
*
|
|
40
|
+
* class NetworkError extends Data.TaggedError("NetworkError")<{
|
|
41
|
+
* readonly attempt: number
|
|
42
|
+
* }> {}
|
|
43
|
+
*
|
|
44
|
+
* // Basic retry schedule - retry up to 3 times with exponential backoff
|
|
45
|
+
* const retrySchedule = Schedule.exponential("100 millis").pipe(
|
|
46
|
+
* Schedule.both(Schedule.recurs(3))
|
|
47
|
+
* )
|
|
48
|
+
*
|
|
49
|
+
* // Basic repeat schedule - repeat every 30 seconds forever
|
|
50
|
+
* const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
|
|
51
|
+
* .spaced("30 seconds")
|
|
52
|
+
*
|
|
53
|
+
* const program = Effect.gen(function*() {
|
|
54
|
+
* let attempts = 0
|
|
55
|
+
*
|
|
56
|
+
* const result1 = yield* Effect.retry(
|
|
57
|
+
* Effect.gen(function*() {
|
|
58
|
+
* attempts++
|
|
59
|
+
* if (attempts < 3) {
|
|
60
|
+
* return yield* Effect.fail(new NetworkError({ attempt: attempts }))
|
|
61
|
+
* }
|
|
62
|
+
* return "Success"
|
|
63
|
+
* }),
|
|
64
|
+
* retrySchedule
|
|
65
|
+
* )
|
|
66
|
+
* console.log(result1) // "Success"
|
|
67
|
+
*
|
|
68
|
+
* yield* Console.log("heartbeat").pipe(
|
|
69
|
+
* Effect.repeat(repeatSchedule.pipe(Schedule.take(5)))
|
|
70
|
+
* )
|
|
71
|
+
* })
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* @category models
|
|
75
|
+
* @since 2.0.0
|
|
76
|
+
*/
|
|
77
|
+
export interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>
|
|
78
|
+
extends Schedule.Variance<Output, Input, Error, Env>, Pipeable
|
|
79
|
+
{}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Metadata provided to schedule functions containing timing and input information.
|
|
83
|
+
*
|
|
84
|
+
* **Example** (Reading schedule input metadata)
|
|
85
|
+
*
|
|
86
|
+
* ```ts
|
|
87
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
88
|
+
*
|
|
89
|
+
* // Custom schedule that uses input metadata
|
|
90
|
+
* const metadataAwareSchedule = Schedule.spaced("1 second").pipe(
|
|
91
|
+
* Schedule.collectWhile((metadata) =>
|
|
92
|
+
* Effect.succeed(metadata.attempt <= 5 && metadata.elapsed < 10000)
|
|
93
|
+
* )
|
|
94
|
+
* )
|
|
95
|
+
*
|
|
96
|
+
* const program = Effect.gen(function*() {
|
|
97
|
+
* yield* Effect.repeat(
|
|
98
|
+
* Console.log("Task execution"),
|
|
99
|
+
* metadataAwareSchedule
|
|
100
|
+
* )
|
|
101
|
+
* })
|
|
102
|
+
* ```
|
|
103
|
+
*
|
|
104
|
+
* @category metadata
|
|
105
|
+
* @since 4.0.0
|
|
106
|
+
*/
|
|
107
|
+
export interface InputMetadata<Input> {
|
|
108
|
+
readonly input: Input
|
|
109
|
+
readonly attempt: number
|
|
110
|
+
readonly start: number
|
|
111
|
+
readonly now: number
|
|
112
|
+
readonly elapsed: number
|
|
113
|
+
readonly elapsedSincePrevious: number
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Extended metadata that includes both input metadata and the output value from the schedule.
|
|
118
|
+
*
|
|
119
|
+
* **Example** (Logging schedule output metadata)
|
|
120
|
+
*
|
|
121
|
+
* ```ts
|
|
122
|
+
* import { Console, Duration, Effect, Schedule } from "effect"
|
|
123
|
+
*
|
|
124
|
+
* // Custom schedule that logs metadata and output for each recurrence
|
|
125
|
+
* const loggingSchedule = Schedule.unfold(0, (n) => Effect.succeed(n + 1)).pipe(
|
|
126
|
+
* Schedule.addDelay(() => Effect.succeed(Duration.millis(100))),
|
|
127
|
+
* Schedule.collectWhile((metadata) =>
|
|
128
|
+
* Console.log(
|
|
129
|
+
* `Output: ${metadata.output}, attempt: ${metadata.attempt}, elapsed: ${metadata.elapsed}ms`
|
|
130
|
+
* ).pipe(Effect.as(metadata.attempt <= 3))
|
|
131
|
+
* )
|
|
132
|
+
* )
|
|
133
|
+
*
|
|
134
|
+
* const program = Effect.gen(function*() {
|
|
135
|
+
* yield* Effect.repeat(
|
|
136
|
+
* Effect.succeed("task completed"),
|
|
137
|
+
* loggingSchedule.pipe(Schedule.take(3))
|
|
138
|
+
* )
|
|
139
|
+
* })
|
|
140
|
+
*
|
|
141
|
+
* // Output logs will show:
|
|
142
|
+
* // Output: 0, attempt: 1, elapsed: 0ms
|
|
143
|
+
* // Output: 1, attempt: 2, elapsed: 100ms
|
|
144
|
+
* // Output: 2, attempt: 3, elapsed: 200ms
|
|
145
|
+
* ```
|
|
146
|
+
*
|
|
147
|
+
* @category metadata
|
|
148
|
+
* @since 4.0.0
|
|
149
|
+
*/
|
|
150
|
+
export interface Metadata<Output = unknown, Input = unknown> extends InputMetadata<Input> {
|
|
151
|
+
readonly output: Output
|
|
152
|
+
readonly duration: Duration.Duration
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Context reference containing metadata for the currently running schedule step.
|
|
157
|
+
*
|
|
158
|
+
* **Details**
|
|
159
|
+
*
|
|
160
|
+
* Repeat, retry, stream, and channel scheduling operations provide this service
|
|
161
|
+
* to effects run between schedule steps. The default value contains undefined
|
|
162
|
+
* input and output values, zero duration, and zeroed timing fields before any
|
|
163
|
+
* schedule step has produced metadata.
|
|
164
|
+
*
|
|
165
|
+
* @category metadata
|
|
166
|
+
* @since 4.0.0
|
|
167
|
+
*/
|
|
168
|
+
export const CurrentMetadata = Context.Reference<Metadata>("effect/Schedule/CurrentMetadata", {
|
|
169
|
+
defaultValue: constant({
|
|
170
|
+
input: undefined,
|
|
171
|
+
output: undefined,
|
|
172
|
+
duration: Duration.zero,
|
|
173
|
+
attempt: 0,
|
|
174
|
+
start: 0,
|
|
175
|
+
now: 0,
|
|
176
|
+
elapsed: 0,
|
|
177
|
+
elapsedSincePrevious: 0
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* The Schedule namespace contains types and utilities for working with schedules.
|
|
183
|
+
*
|
|
184
|
+
* **Example** (Creating custom schedules with the namespace)
|
|
185
|
+
*
|
|
186
|
+
* ```ts
|
|
187
|
+
* import { Duration, Effect, Schedule } from "effect"
|
|
188
|
+
*
|
|
189
|
+
* // Usage of the Schedule namespace for creating schedules
|
|
190
|
+
*
|
|
191
|
+
* // Create custom schedule with metadata
|
|
192
|
+
* const customSchedule = Schedule.unfold(0, (n) => Effect.succeed(n + 1)).pipe(
|
|
193
|
+
* Schedule.addDelay((n) => Effect.succeed(Duration.millis(n * 100)))
|
|
194
|
+
* )
|
|
195
|
+
*
|
|
196
|
+
* const program = Effect.gen(function*() {
|
|
197
|
+
* let attempt = 0
|
|
198
|
+
*
|
|
199
|
+
* yield* Effect.retry(
|
|
200
|
+
* Effect.gen(function*() {
|
|
201
|
+
* attempt++
|
|
202
|
+
* if (attempt < 3) {
|
|
203
|
+
* return yield* Effect.fail(`Attempt ${attempt} failed`)
|
|
204
|
+
* }
|
|
205
|
+
* return `Success on attempt ${attempt}`
|
|
206
|
+
* }),
|
|
207
|
+
* customSchedule.pipe(Schedule.take(5))
|
|
208
|
+
* )
|
|
209
|
+
* })
|
|
210
|
+
* ```
|
|
211
|
+
*
|
|
212
|
+
* @since 2.0.0
|
|
213
|
+
*/
|
|
214
|
+
export declare namespace Schedule {
|
|
215
|
+
/**
|
|
216
|
+
* Variance interface that defines the type parameter relationships for Schedule.
|
|
217
|
+
*
|
|
218
|
+
* **Example** (Understanding schedule variance)
|
|
219
|
+
*
|
|
220
|
+
* ```ts
|
|
221
|
+
* import { Effect, Schedule } from "effect"
|
|
222
|
+
*
|
|
223
|
+
* // Understanding Schedule variance:
|
|
224
|
+
* // - Output: covariant (can be a subtype)
|
|
225
|
+
* // - Input: contravariant (can accept supertypes)
|
|
226
|
+
* // - Error: covariant (can be a subtype)
|
|
227
|
+
* // - Env: covariant (can be a subtype)
|
|
228
|
+
*
|
|
229
|
+
* // Schedule that produces strings, accepts any input
|
|
230
|
+
* const stringSchedule = Schedule.spaced("1 second").pipe(
|
|
231
|
+
* Schedule.map(() => Effect.succeed("tick"))
|
|
232
|
+
* )
|
|
233
|
+
*
|
|
234
|
+
* // Schedule that only accepts Error inputs
|
|
235
|
+
* const errorSchedule = Schedule.exponential("100 millis").pipe(
|
|
236
|
+
* Schedule.take(5)
|
|
237
|
+
* )
|
|
238
|
+
*
|
|
239
|
+
* // Schedule requiring a service environment
|
|
240
|
+
* const serviceSchedule = Schedule.spaced("5 seconds")
|
|
241
|
+
* ```
|
|
242
|
+
*
|
|
243
|
+
* @category models
|
|
244
|
+
* @since 2.0.0
|
|
245
|
+
*/
|
|
246
|
+
export interface Variance<out Output, in Input, out Error, out Env> {
|
|
247
|
+
readonly [TypeId]: VarianceStruct<Output, Input, Error, Env>
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Type-level marker used by `Schedule.Variance` to record the variance of
|
|
252
|
+
* `Schedule` type parameters.
|
|
253
|
+
*
|
|
254
|
+
* **Details**
|
|
255
|
+
*
|
|
256
|
+
* This interface exists for TypeScript inference and assignability. Users
|
|
257
|
+
* normally do not construct or inspect it directly.
|
|
258
|
+
*
|
|
259
|
+
* @category models
|
|
260
|
+
* @since 4.0.0
|
|
261
|
+
*/
|
|
262
|
+
export interface VarianceStruct<out Output, in Input, out Error, out Env> {
|
|
263
|
+
readonly _Out: Covariant<Output>
|
|
264
|
+
readonly _In: Contravariant<Input>
|
|
265
|
+
readonly _Error: Covariant<Error>
|
|
266
|
+
readonly _Env: Covariant<Env>
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const ScheduleProto = {
|
|
271
|
+
[TypeId]: {
|
|
272
|
+
_Out: identity,
|
|
273
|
+
_In: identity,
|
|
274
|
+
_Env: identity
|
|
275
|
+
},
|
|
276
|
+
pipe() {
|
|
277
|
+
return pipeArguments(this, arguments)
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Type guard that checks if a value is a Schedule.
|
|
283
|
+
*
|
|
284
|
+
* **Example** (Checking for schedules)
|
|
285
|
+
*
|
|
286
|
+
* ```ts
|
|
287
|
+
* import { Schedule } from "effect"
|
|
288
|
+
*
|
|
289
|
+
* const schedule = Schedule.exponential("100 millis")
|
|
290
|
+
* const notSchedule = { foo: "bar" }
|
|
291
|
+
*
|
|
292
|
+
* console.log(Schedule.isSchedule(schedule)) // true
|
|
293
|
+
* console.log(Schedule.isSchedule(notSchedule)) // false
|
|
294
|
+
* console.log(Schedule.isSchedule(null)) // false
|
|
295
|
+
* console.log(Schedule.isSchedule(undefined)) // false
|
|
296
|
+
* ```
|
|
297
|
+
*
|
|
298
|
+
* @category guards
|
|
299
|
+
* @since 2.0.0
|
|
300
|
+
*/
|
|
301
|
+
export const isSchedule = (u: unknown): u is Schedule<unknown, never, unknown, unknown> => hasProperty(u, TypeId)
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Creates a Schedule from a step function that returns a Pull.
|
|
305
|
+
*
|
|
306
|
+
* **Example** (Creating a custom schedule from a step function)
|
|
307
|
+
*
|
|
308
|
+
* ```ts
|
|
309
|
+
* import { Cause, Duration, Effect, Schedule } from "effect"
|
|
310
|
+
*
|
|
311
|
+
* const schedule = Schedule.fromStep(Effect.sync(() => {
|
|
312
|
+
* let count = 0
|
|
313
|
+
*
|
|
314
|
+
* return (_now: number, _input: string) => {
|
|
315
|
+
* if (count >= 3) {
|
|
316
|
+
* return Cause.done(count)
|
|
317
|
+
* }
|
|
318
|
+
* return Effect.succeed([count++, Duration.millis(100)] as [number, Duration.Duration])
|
|
319
|
+
* }
|
|
320
|
+
* }))
|
|
321
|
+
* ```
|
|
322
|
+
*
|
|
323
|
+
* @category constructors
|
|
324
|
+
* @since 4.0.0
|
|
325
|
+
*/
|
|
326
|
+
export const fromStep = <Input, Output, EnvX, Error, ErrorX, Env>(
|
|
327
|
+
step: Effect<
|
|
328
|
+
(now: number, input: Input) => Pull.Pull<[Output, Duration.Duration], ErrorX, Output, EnvX>,
|
|
329
|
+
Error,
|
|
330
|
+
Env
|
|
331
|
+
>
|
|
332
|
+
): Schedule<Output, Input, Error | Pull.ExcludeDone<ErrorX>, Env | EnvX> => {
|
|
333
|
+
const self = Object.create(ScheduleProto)
|
|
334
|
+
self.step = step
|
|
335
|
+
return self
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const metadataFn = () => {
|
|
339
|
+
let n = 0
|
|
340
|
+
let previous: number | undefined
|
|
341
|
+
let start: number | undefined
|
|
342
|
+
return <In>(now: number, input: In): InputMetadata<In> => {
|
|
343
|
+
if (start === undefined) start = now
|
|
344
|
+
const elapsed = now - start
|
|
345
|
+
const elapsedSincePrevious = previous === undefined ? 0 : now - previous
|
|
346
|
+
previous = now
|
|
347
|
+
return { input, attempt: ++n, start, now, elapsed, elapsedSincePrevious }
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Creates a Schedule from a step function that receives metadata about the schedule's execution.
|
|
353
|
+
*
|
|
354
|
+
* **Example** (Creating a metadata-aware schedule)
|
|
355
|
+
*
|
|
356
|
+
* ```ts
|
|
357
|
+
* import { Cause, Duration, Effect, Schedule } from "effect"
|
|
358
|
+
*
|
|
359
|
+
* const firstThreeInputs = Schedule.fromStepWithMetadata(Effect.succeed((metadata: Schedule.InputMetadata<string>) => {
|
|
360
|
+
* if (metadata.attempt > 3) {
|
|
361
|
+
* return Cause.done("finished")
|
|
362
|
+
* }
|
|
363
|
+
*
|
|
364
|
+
* return Effect.succeed([
|
|
365
|
+
* `attempt ${metadata.attempt}: ${metadata.input}`,
|
|
366
|
+
* Duration.millis(250)
|
|
367
|
+
* ] as [string, Duration.Duration])
|
|
368
|
+
* }))
|
|
369
|
+
* ```
|
|
370
|
+
*
|
|
371
|
+
* @category constructors
|
|
372
|
+
* @since 4.0.0
|
|
373
|
+
*/
|
|
374
|
+
export const fromStepWithMetadata = <Input, Output, EnvX, ErrorX, Error, Env>(
|
|
375
|
+
step: Effect<
|
|
376
|
+
(options: InputMetadata<Input>) => Pull.Pull<[Output, Duration.Duration], ErrorX, Output, EnvX>,
|
|
377
|
+
Error,
|
|
378
|
+
Env
|
|
379
|
+
>
|
|
380
|
+
): Schedule<Output, Input, Error | Pull.ExcludeDone<ErrorX>, Env | EnvX> =>
|
|
381
|
+
fromStep(effect.map(step, (f) => {
|
|
382
|
+
const meta = metadataFn()
|
|
383
|
+
return (now, input) => f(meta(now, input))
|
|
384
|
+
}))
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Extracts the step function from a Schedule.
|
|
388
|
+
*
|
|
389
|
+
* **Example** (Extracting a schedule step function)
|
|
390
|
+
*
|
|
391
|
+
* ```ts
|
|
392
|
+
* import { Effect, Schedule } from "effect"
|
|
393
|
+
*
|
|
394
|
+
* // Extract step function from an existing schedule
|
|
395
|
+
* const schedule = Schedule.exponential("100 millis").pipe(Schedule.take(3))
|
|
396
|
+
*
|
|
397
|
+
* const program = Effect.gen(function*() {
|
|
398
|
+
* const stepFn = yield* Schedule.toStep(schedule)
|
|
399
|
+
*
|
|
400
|
+
* // Use the step function directly for custom logic. The timestamp is
|
|
401
|
+
* // supplied by the caller, so tests can pass a deterministic value.
|
|
402
|
+
* const now = 0
|
|
403
|
+
* const result = yield* stepFn(now, "input")
|
|
404
|
+
*
|
|
405
|
+
* console.log(`Step result: ${result}`)
|
|
406
|
+
* })
|
|
407
|
+
* ```
|
|
408
|
+
*
|
|
409
|
+
* @category destructors
|
|
410
|
+
* @since 4.0.0
|
|
411
|
+
*/
|
|
412
|
+
export const toStep = <Output, Input, Error, Env>(
|
|
413
|
+
schedule: Schedule<Output, Input, Error, Env>
|
|
414
|
+
): Effect<
|
|
415
|
+
(now: number, input: Input) => Pull.Pull<[Output, Duration.Duration], Error, Output, Env>,
|
|
416
|
+
never,
|
|
417
|
+
Env
|
|
418
|
+
> =>
|
|
419
|
+
effect.catchCause(
|
|
420
|
+
(schedule as any).step,
|
|
421
|
+
(cause) => effect.succeed(() => effect.failCause(cause) as any)
|
|
422
|
+
)
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Extracts a step function from a `Schedule` that sleeps for each computed
|
|
426
|
+
* delay and returns metadata for the completed step.
|
|
427
|
+
*
|
|
428
|
+
* **When to use**
|
|
429
|
+
*
|
|
430
|
+
* Use to drive a schedule manually while preserving the computed output,
|
|
431
|
+
* delay, input, attempt, and elapsed timing metadata for each step.
|
|
432
|
+
*
|
|
433
|
+
* **Details**
|
|
434
|
+
*
|
|
435
|
+
* The returned step reads the current time from `Clock` when invoked, calls the
|
|
436
|
+
* schedule step with that timestamp and input, sleeps for the returned
|
|
437
|
+
* duration, and then yields `Metadata`.
|
|
438
|
+
*
|
|
439
|
+
* @see {@link toStep} for manually supplying the timestamp and handling the returned delay yourself
|
|
440
|
+
* @see {@link toStepWithSleep} for the same automatic sleeping behavior when only the schedule output is needed
|
|
441
|
+
*
|
|
442
|
+
* @category destructors
|
|
443
|
+
* @since 4.0.0
|
|
444
|
+
*/
|
|
445
|
+
export const toStepWithMetadata = <Output, Input, Error, Env>(
|
|
446
|
+
schedule: Schedule<Output, Input, Error, Env>
|
|
447
|
+
): Effect<
|
|
448
|
+
(input: Input) => Pull.Pull<Metadata<Output, Input>, Error, Output, Env>,
|
|
449
|
+
never,
|
|
450
|
+
Env
|
|
451
|
+
> =>
|
|
452
|
+
effect.clockWith((clock) =>
|
|
453
|
+
effect.map(
|
|
454
|
+
toStep(schedule),
|
|
455
|
+
(step) => {
|
|
456
|
+
const metaFn = metadataFn()
|
|
457
|
+
return (input) =>
|
|
458
|
+
effect.suspend(() => {
|
|
459
|
+
const now = clock.currentTimeMillisUnsafe()
|
|
460
|
+
return effect.flatMap(
|
|
461
|
+
step(now, input),
|
|
462
|
+
([output, duration]) => {
|
|
463
|
+
const meta = metaFn(now, input) as Mutable<Metadata<Output, Input>>
|
|
464
|
+
meta.output = output
|
|
465
|
+
meta.duration = duration
|
|
466
|
+
return effect.as(effect.sleep(duration), meta)
|
|
467
|
+
}
|
|
468
|
+
)
|
|
469
|
+
})
|
|
470
|
+
}
|
|
471
|
+
)
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Extracts a step function from a Schedule that automatically handles sleep delays.
|
|
476
|
+
*
|
|
477
|
+
* **Example** (Extracting a sleeping step function)
|
|
478
|
+
*
|
|
479
|
+
* ```ts
|
|
480
|
+
* import { Effect, Schedule } from "effect"
|
|
481
|
+
*
|
|
482
|
+
* // Convert schedule to step function with automatic sleeping
|
|
483
|
+
* const schedule = Schedule.spaced("1 second").pipe(Schedule.take(3))
|
|
484
|
+
*
|
|
485
|
+
* const program = Effect.gen(function*() {
|
|
486
|
+
* const stepWithSleep = yield* Schedule.toStepWithSleep(schedule)
|
|
487
|
+
*
|
|
488
|
+
* // Each call will automatically sleep for the scheduled delay
|
|
489
|
+
* console.log("Starting...")
|
|
490
|
+
* const result1 = yield* stepWithSleep("first")
|
|
491
|
+
* console.log(`First result: ${result1}`)
|
|
492
|
+
*
|
|
493
|
+
* const result2 = yield* stepWithSleep("second")
|
|
494
|
+
* console.log(`Second result: ${result2}`)
|
|
495
|
+
*
|
|
496
|
+
* const result3 = yield* stepWithSleep("third")
|
|
497
|
+
* console.log(`Third result: ${result3}`)
|
|
498
|
+
* })
|
|
499
|
+
* ```
|
|
500
|
+
*
|
|
501
|
+
* @category destructors
|
|
502
|
+
* @since 4.0.0
|
|
503
|
+
*/
|
|
504
|
+
export const toStepWithSleep = <Output, Input, Error, Env>(
|
|
505
|
+
schedule: Schedule<Output, Input, Error, Env>
|
|
506
|
+
): Effect<
|
|
507
|
+
(input: Input) => Pull.Pull<Output, Error, Output, Env>,
|
|
508
|
+
never,
|
|
509
|
+
Env
|
|
510
|
+
> =>
|
|
511
|
+
effect.map(
|
|
512
|
+
toStepWithMetadata(schedule),
|
|
513
|
+
(step) => (input) => effect.map(step(input), (meta) => meta.output)
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Returns a new `Schedule` that adds the delay computed by the specified
|
|
518
|
+
* effectful function to the next recurrence of the schedule.
|
|
519
|
+
*
|
|
520
|
+
* **Example** (Adding extra delay to a schedule)
|
|
521
|
+
*
|
|
522
|
+
* ```ts
|
|
523
|
+
* import { Console, Data, Duration, Effect, Schedule } from "effect"
|
|
524
|
+
*
|
|
525
|
+
* class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
|
|
526
|
+
*
|
|
527
|
+
* // Add a deterministic extra delay based on the schedule output
|
|
528
|
+
* const delayedSchedule = Schedule.addDelay(
|
|
529
|
+
* Schedule.exponential("100 millis").pipe(Schedule.take(5)),
|
|
530
|
+
* (output) =>
|
|
531
|
+
* Effect.succeed(Duration.millis(Duration.toMillis(output) * 0.25))
|
|
532
|
+
* )
|
|
533
|
+
*
|
|
534
|
+
* const repeatProgram = Effect.gen(function*() {
|
|
535
|
+
* yield* Effect.repeat(
|
|
536
|
+
* Effect.succeed("delayed task"),
|
|
537
|
+
* delayedSchedule.pipe(
|
|
538
|
+
* Schedule.tapOutput((delay) =>
|
|
539
|
+
* Console.log(`Base delay: ${delay}`)
|
|
540
|
+
* )
|
|
541
|
+
* )
|
|
542
|
+
* )
|
|
543
|
+
* })
|
|
544
|
+
*
|
|
545
|
+
* // Add adaptive delay based on execution count
|
|
546
|
+
* const adaptiveSchedule = Schedule.addDelay(
|
|
547
|
+
* Schedule.recurs(6),
|
|
548
|
+
* (executionCount) =>
|
|
549
|
+
* // Increase delay as execution count grows
|
|
550
|
+
* Effect.succeed(Duration.millis(executionCount * 200))
|
|
551
|
+
* )
|
|
552
|
+
*
|
|
553
|
+
* const adaptiveProgram = Effect.gen(function*() {
|
|
554
|
+
* yield* Effect.repeat(
|
|
555
|
+
* Effect.gen(function*() {
|
|
556
|
+
* yield* Console.log("Adaptive delay task")
|
|
557
|
+
* return "adaptive"
|
|
558
|
+
* }),
|
|
559
|
+
* adaptiveSchedule.pipe(
|
|
560
|
+
* Schedule.tapOutput((count) =>
|
|
561
|
+
* Console.log(`Execution ${count + 1} with adaptive delay`)
|
|
562
|
+
* )
|
|
563
|
+
* )
|
|
564
|
+
* )
|
|
565
|
+
* })
|
|
566
|
+
*
|
|
567
|
+
* // Add effectful delay computation from deterministic service data
|
|
568
|
+
* const loadByExecution = [1, 3, 2, 4] as const
|
|
569
|
+
*
|
|
570
|
+
* const dynamicSchedule = Schedule.addDelay(
|
|
571
|
+
* Schedule.spaced("1 second").pipe(Schedule.take(4)),
|
|
572
|
+
* (executionNumber) => {
|
|
573
|
+
* const load = loadByExecution[executionNumber] ?? 1
|
|
574
|
+
* return Effect.succeed(Duration.millis(load * 100))
|
|
575
|
+
* }
|
|
576
|
+
* )
|
|
577
|
+
*
|
|
578
|
+
* const dynamicProgram = Effect.gen(function*() {
|
|
579
|
+
* yield* Effect.repeat(
|
|
580
|
+
* Effect.gen(function*() {
|
|
581
|
+
* yield* Console.log("Dynamic delay task")
|
|
582
|
+
* return "dynamic"
|
|
583
|
+
* }),
|
|
584
|
+
* dynamicSchedule
|
|
585
|
+
* )
|
|
586
|
+
* })
|
|
587
|
+
*
|
|
588
|
+
* // Combine with retry for progressive backoff
|
|
589
|
+
* const progressiveRetrySchedule = Schedule.addDelay(
|
|
590
|
+
* Schedule.exponential("50 millis").pipe(Schedule.take(4)),
|
|
591
|
+
* () => Effect.succeed(Duration.millis(100)) // Fixed additional delay
|
|
592
|
+
* )
|
|
593
|
+
*
|
|
594
|
+
* const retryProgram = Effect.gen(function*() {
|
|
595
|
+
* let attempt = 0
|
|
596
|
+
*
|
|
597
|
+
* const result = yield* Effect.retry(
|
|
598
|
+
* Effect.gen(function*() {
|
|
599
|
+
* attempt++
|
|
600
|
+
* if (attempt < 5) {
|
|
601
|
+
* return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
|
|
602
|
+
* }
|
|
603
|
+
* return `Success on attempt ${attempt}`
|
|
604
|
+
* }),
|
|
605
|
+
* progressiveRetrySchedule
|
|
606
|
+
* )
|
|
607
|
+
*
|
|
608
|
+
* yield* Console.log(`Final result: ${result}`)
|
|
609
|
+
* })
|
|
610
|
+
* ```
|
|
611
|
+
*
|
|
612
|
+
* @category delays & timeouts
|
|
613
|
+
* @since 2.0.0
|
|
614
|
+
*/
|
|
615
|
+
export const addDelay: {
|
|
616
|
+
<Output, Error2 = never, Env2 = never>(
|
|
617
|
+
f: (output: Output) => Effect<Duration.Input, Error2, Env2>
|
|
618
|
+
): <Input, Error, Env>(
|
|
619
|
+
self: Schedule<Output, Input, Error, Env>
|
|
620
|
+
) => Schedule<Output, Input, Error | Error2, Env | Env2>
|
|
621
|
+
<Output, Input, Error, Env, Error2 = never, Env2 = never>(
|
|
622
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
623
|
+
f: (output: Output) => Effect<Duration.Input, Error2, Env2>
|
|
624
|
+
): Schedule<Output, Input, Error | Error2, Env | Env2>
|
|
625
|
+
} = dual(2, <Output, Input, Error, Env, Error2 = never, Env2 = never>(
|
|
626
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
627
|
+
f: (output: Output) => Effect<Duration.Input, Error2, Env2>
|
|
628
|
+
): Schedule<Output, Input, Error | Error2, Env | Env2> =>
|
|
629
|
+
modifyDelay(
|
|
630
|
+
self,
|
|
631
|
+
(output, delay) =>
|
|
632
|
+
effect.map(f(output), (d) => Duration.sum(Duration.fromInputUnsafe(d), Duration.fromInputUnsafe(delay)))
|
|
633
|
+
))
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Returns a schedule that runs `self` to completion, then runs `other`, and
|
|
637
|
+
* merges their outputs.
|
|
638
|
+
*
|
|
639
|
+
* **Example** (Sequencing quick and slow retries)
|
|
640
|
+
*
|
|
641
|
+
* ```ts
|
|
642
|
+
* import { Console, Data, Effect, Schedule } from "effect"
|
|
643
|
+
*
|
|
644
|
+
* class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
|
|
645
|
+
*
|
|
646
|
+
* // First retry 3 times quickly, then switch to slower retries
|
|
647
|
+
* const quickRetries = Schedule.exponential("100 millis").pipe(
|
|
648
|
+
* Schedule.take(3)
|
|
649
|
+
* )
|
|
650
|
+
* const slowRetries = Schedule.exponential("1 second").pipe(
|
|
651
|
+
* Schedule.take(2)
|
|
652
|
+
* )
|
|
653
|
+
*
|
|
654
|
+
* const combinedRetries = Schedule.andThen(quickRetries, slowRetries)
|
|
655
|
+
*
|
|
656
|
+
* const program = Effect.gen(function*() {
|
|
657
|
+
* let attempt = 0
|
|
658
|
+
* yield* Effect.retry(
|
|
659
|
+
* Effect.gen(function*() {
|
|
660
|
+
* attempt++
|
|
661
|
+
* yield* Console.log(`Attempt ${attempt}`)
|
|
662
|
+
* if (attempt < 6) {
|
|
663
|
+
* return yield* Effect.fail(new RetryAttemptError({ message: `Failure ${attempt}` }))
|
|
664
|
+
* }
|
|
665
|
+
* return `Success on attempt ${attempt}`
|
|
666
|
+
* }),
|
|
667
|
+
* combinedRetries
|
|
668
|
+
* )
|
|
669
|
+
* })
|
|
670
|
+
* ```
|
|
671
|
+
*
|
|
672
|
+
* @category sequencing
|
|
673
|
+
* @since 2.0.0
|
|
674
|
+
*/
|
|
675
|
+
export const andThen: {
|
|
676
|
+
<Output2, Input2, Error2, Env2>(
|
|
677
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
678
|
+
): <Output, Input, Error, Env>(
|
|
679
|
+
self: Schedule<Output, Input, Error, Env>
|
|
680
|
+
) => Schedule<Output | Output2, Input & Input2, Error | Error2, Env | Env2>
|
|
681
|
+
<Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
682
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
683
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
684
|
+
): Schedule<Output | Output2, Input & Input2, Error | Error2, Env | Env2>
|
|
685
|
+
} = dual(2, <Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
686
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
687
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
688
|
+
): Schedule<Output | Output2, Input & Input2, Error | Error2, Env | Env2> =>
|
|
689
|
+
map(andThenResult(self, other), (result) => effect.succeed(Result.merge(result))))
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* Returns a schedule that runs `self` to completion, then runs `other`, and
|
|
693
|
+
* preserves which schedule produced each output.
|
|
694
|
+
*
|
|
695
|
+
* **Details**
|
|
696
|
+
*
|
|
697
|
+
* The resulting schedule emits a `Result` to indicate which phase produced
|
|
698
|
+
* each output: outputs from `self` are emitted as `Failure`, and outputs from
|
|
699
|
+
* `other` are emitted as `Success`.
|
|
700
|
+
*
|
|
701
|
+
* **Example** (Tracking sequential schedule phases)
|
|
702
|
+
*
|
|
703
|
+
* ```ts
|
|
704
|
+
* import { Console, Effect, Result, Schedule } from "effect"
|
|
705
|
+
*
|
|
706
|
+
* // Track which phase of the schedule we're in
|
|
707
|
+
* const phaseTracker = Schedule.andThenResult(
|
|
708
|
+
* Schedule.exponential("100 millis").pipe(Schedule.take(2)),
|
|
709
|
+
* Schedule.spaced("500 millis").pipe(Schedule.take(2))
|
|
710
|
+
* )
|
|
711
|
+
*
|
|
712
|
+
* const program = Effect.gen(function*() {
|
|
713
|
+
* yield* Effect.repeat(
|
|
714
|
+
* Effect.gen(function*() {
|
|
715
|
+
* yield* Console.log("Task executed")
|
|
716
|
+
* return "task-result"
|
|
717
|
+
* }),
|
|
718
|
+
* phaseTracker.pipe(
|
|
719
|
+
* Schedule.tapOutput((result) =>
|
|
720
|
+
* Result.match(result, {
|
|
721
|
+
* onFailure: (phase1Output) => Console.log(`Phase 1: ${phase1Output}`),
|
|
722
|
+
* onSuccess: (phase2Output) => Console.log(`Phase 2: ${phase2Output}`)
|
|
723
|
+
* })
|
|
724
|
+
* )
|
|
725
|
+
* )
|
|
726
|
+
* )
|
|
727
|
+
* })
|
|
728
|
+
* ```
|
|
729
|
+
*
|
|
730
|
+
* @category sequencing
|
|
731
|
+
* @since 4.0.0
|
|
732
|
+
*/
|
|
733
|
+
export const andThenResult: {
|
|
734
|
+
<Output2, Input2, Error2, Env2>(
|
|
735
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
736
|
+
): <Output, Input, Error, Env>(
|
|
737
|
+
self: Schedule<Output, Input, Error, Env>
|
|
738
|
+
) => Schedule<Result.Result<Output2, Output>, Input & Input2, Error | Error2, Env | Env2>
|
|
739
|
+
<Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
740
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
741
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
742
|
+
): Schedule<Result.Result<Output2, Output>, Input & Input2, Error | Error2, Env | Env2>
|
|
743
|
+
} = dual(2, <Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
744
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
745
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
746
|
+
): Schedule<Result.Result<Output, Output2>, Input & Input2, Error | Error2, Env | Env2> =>
|
|
747
|
+
fromStep(effect.sync(() => {
|
|
748
|
+
let currentSide = 0
|
|
749
|
+
let currentStep:
|
|
750
|
+
| undefined
|
|
751
|
+
| ((now: number, input: Input & Input2) => Pull.Pull<
|
|
752
|
+
[Result.Result<Output, Output2>, Duration.Duration],
|
|
753
|
+
Error | Error2,
|
|
754
|
+
Result.Result<Output, Output2>,
|
|
755
|
+
Env | Env2
|
|
756
|
+
>)
|
|
757
|
+
const left = map(self, Result.succeed)
|
|
758
|
+
const right = map(other, Result.fail)
|
|
759
|
+
return function recur(
|
|
760
|
+
now,
|
|
761
|
+
input
|
|
762
|
+
): Pull.Pull<
|
|
763
|
+
[Result.Result<Output, Output2>, Duration.Duration],
|
|
764
|
+
Error | Error2,
|
|
765
|
+
Result.Result<Output, Output2>,
|
|
766
|
+
Env | Env2
|
|
767
|
+
> {
|
|
768
|
+
if (currentStep) return currentStep(now, input)
|
|
769
|
+
return toStep<
|
|
770
|
+
Result.Result<Output, Output2>,
|
|
771
|
+
Input & Input2,
|
|
772
|
+
Error | Error2,
|
|
773
|
+
Env | Env2
|
|
774
|
+
>(currentSide === 0 ? left : right).pipe(
|
|
775
|
+
effect.flatMap((step) => {
|
|
776
|
+
currentSide++
|
|
777
|
+
if (currentSide === 1) {
|
|
778
|
+
currentStep = (now, input) =>
|
|
779
|
+
Pull.catchDone(step(now, input), (_) => {
|
|
780
|
+
currentStep = undefined
|
|
781
|
+
return recur(now, input)
|
|
782
|
+
})
|
|
783
|
+
return currentStep(now, input)
|
|
784
|
+
}
|
|
785
|
+
currentStep = step
|
|
786
|
+
return currentStep(now, input)
|
|
787
|
+
})
|
|
788
|
+
)
|
|
789
|
+
}
|
|
790
|
+
})))
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* Combines two `Schedule`s by recurring if both of the two schedules want
|
|
794
|
+
* to recur, using the maximum of the two durations between recurrences and
|
|
795
|
+
* outputting a tuple of the outputs of both schedules.
|
|
796
|
+
*
|
|
797
|
+
* **When to use**
|
|
798
|
+
*
|
|
799
|
+
* Use when the combined schedule should continue only while both schedules still recur.
|
|
800
|
+
*
|
|
801
|
+
* **Example** (Combining time and attempt limits)
|
|
802
|
+
*
|
|
803
|
+
* ```ts
|
|
804
|
+
* import { Console, Data, Effect, Schedule } from "effect"
|
|
805
|
+
*
|
|
806
|
+
* class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
|
|
807
|
+
*
|
|
808
|
+
* // Both schedules must want to continue for the combined schedule to continue
|
|
809
|
+
* const timeLimit = Schedule.spaced("1 second").pipe(Schedule.take(5)) // max 5 times
|
|
810
|
+
* const attemptLimit = Schedule.recurs(3) // max 3 attempts
|
|
811
|
+
*
|
|
812
|
+
* // Continues only while BOTH schedules want to continue (intersection/AND logic)
|
|
813
|
+
* const bothSchedule = Schedule.both(timeLimit, attemptLimit)
|
|
814
|
+
* // Outputs: [time_result, attempt_count] tuple
|
|
815
|
+
*
|
|
816
|
+
* const program = Effect.gen(function*() {
|
|
817
|
+
* const results = yield* Effect.repeat(
|
|
818
|
+
* Effect.gen(function*() {
|
|
819
|
+
* yield* Console.log("Task executed")
|
|
820
|
+
* return "task completed"
|
|
821
|
+
* }),
|
|
822
|
+
* bothSchedule.pipe(
|
|
823
|
+
* Schedule.tapOutput(([timeResult, attemptResult]) =>
|
|
824
|
+
* Console.log(`Time: ${timeResult}, Attempts: ${attemptResult}`)
|
|
825
|
+
* )
|
|
826
|
+
* )
|
|
827
|
+
* )
|
|
828
|
+
*
|
|
829
|
+
* yield* Console.log("Completed all executions")
|
|
830
|
+
* })
|
|
831
|
+
*
|
|
832
|
+
* // Both with different delay strategies - uses maximum delay
|
|
833
|
+
* const fastSchedule = Schedule.fixed("500 millis").pipe(Schedule.take(4))
|
|
834
|
+
* const slowSchedule = Schedule.spaced("2 seconds").pipe(Schedule.take(6))
|
|
835
|
+
*
|
|
836
|
+
* // Will use the slower (maximum) delay and stop when first schedule exhausts
|
|
837
|
+
* const conservativeSchedule = Schedule.both(fastSchedule, slowSchedule)
|
|
838
|
+
*
|
|
839
|
+
* const retryProgram = Effect.gen(function*() {
|
|
840
|
+
* let attempt = 0
|
|
841
|
+
*
|
|
842
|
+
* const result = yield* Effect.retry(
|
|
843
|
+
* Effect.gen(function*() {
|
|
844
|
+
* attempt++
|
|
845
|
+
* yield* Console.log(`Retry attempt ${attempt}`)
|
|
846
|
+
*
|
|
847
|
+
* if (attempt < 3) {
|
|
848
|
+
* return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
|
|
849
|
+
* }
|
|
850
|
+
*
|
|
851
|
+
* return `Success on attempt ${attempt}`
|
|
852
|
+
* }),
|
|
853
|
+
* conservativeSchedule
|
|
854
|
+
* )
|
|
855
|
+
*
|
|
856
|
+
* yield* Console.log(`Final result: ${result}`)
|
|
857
|
+
* })
|
|
858
|
+
*
|
|
859
|
+
* // Both provides intersection semantics (AND logic)
|
|
860
|
+
* // Compare with either which provides union semantics (OR logic)
|
|
861
|
+
* ```
|
|
862
|
+
*
|
|
863
|
+
* @see {@link either} for continuing while either schedule still recurs
|
|
864
|
+
*
|
|
865
|
+
* @category combining
|
|
866
|
+
* @since 2.0.0
|
|
867
|
+
*/
|
|
868
|
+
export const both: {
|
|
869
|
+
<Output2, Input2, Error2, Env2, Output>(
|
|
870
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
871
|
+
): <Input, Error, Env>(
|
|
872
|
+
self: Schedule<Output, Input, Error, Env>
|
|
873
|
+
) => Schedule<[Output, Output2], Input & Input2, Error | Error2, Env | Env2>
|
|
874
|
+
<Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
875
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
876
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
877
|
+
): Schedule<[Output, Output2], Input & Input2, Error | Error2, Env | Env2>
|
|
878
|
+
} = dual(2, <Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
879
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
880
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
881
|
+
): Schedule<[Output, Output2], Input & Input2, Error | Error2, Env | Env2> =>
|
|
882
|
+
bothWith(self, other, (left, right) => [left, right]))
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Combines two `Schedule`s by recurring if both of the two schedules want
|
|
886
|
+
* to recur, using the maximum of the two durations between recurrences and
|
|
887
|
+
* outputting the result of the left schedule (i.e. `self`).
|
|
888
|
+
*
|
|
889
|
+
* **When to use**
|
|
890
|
+
*
|
|
891
|
+
* Use when two schedules must both allow recurrence and only the left schedule's
|
|
892
|
+
* output is needed.
|
|
893
|
+
*
|
|
894
|
+
* **Example** (Combining schedules and keeping the left output)
|
|
895
|
+
*
|
|
896
|
+
* ```ts
|
|
897
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
898
|
+
*
|
|
899
|
+
* // Combine two schedules, keeping left output
|
|
900
|
+
* const leftSchedule = Schedule.exponential("100 millis").pipe(
|
|
901
|
+
* Schedule.map(() => Effect.succeed("left-result"))
|
|
902
|
+
* )
|
|
903
|
+
* const rightSchedule = Schedule.spaced("50 millis")
|
|
904
|
+
*
|
|
905
|
+
* const combined = Schedule.bothLeft(leftSchedule, rightSchedule)
|
|
906
|
+
*
|
|
907
|
+
* const program = Effect.gen(function*() {
|
|
908
|
+
* yield* Effect.repeat(
|
|
909
|
+
* Effect.gen(function*() {
|
|
910
|
+
* yield* Console.log("Task executed")
|
|
911
|
+
* return "task-done"
|
|
912
|
+
* }),
|
|
913
|
+
* combined.pipe(Schedule.take(3))
|
|
914
|
+
* )
|
|
915
|
+
* })
|
|
916
|
+
* ```
|
|
917
|
+
*
|
|
918
|
+
* @category combining
|
|
919
|
+
* @since 2.0.0
|
|
920
|
+
*/
|
|
921
|
+
export const bothLeft: {
|
|
922
|
+
<Output2, Input2, Error2, Env2>(
|
|
923
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
924
|
+
): <Output, Input, Error, Env>(
|
|
925
|
+
self: Schedule<Output, Input, Error, Env>
|
|
926
|
+
) => Schedule<Output, Input & Input2, Error | Error2, Env | Env2>
|
|
927
|
+
<Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
928
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
929
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
930
|
+
): Schedule<Output, Input & Input2, Error | Error2, Env | Env2>
|
|
931
|
+
} = dual(2, <Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
932
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
933
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
934
|
+
): Schedule<Output, Input & Input2, Error | Error2, Env | Env2> => bothWith(self, other, (output) => output))
|
|
935
|
+
|
|
936
|
+
/**
|
|
937
|
+
* Combines two `Schedule`s by recurring if both of the two schedules want
|
|
938
|
+
* to recur, using the maximum of the two durations between recurrences and
|
|
939
|
+
* outputting the result of the right schedule (i.e. `other`).
|
|
940
|
+
*
|
|
941
|
+
* **When to use**
|
|
942
|
+
*
|
|
943
|
+
* Use when two schedules must both allow recurrence and only the right
|
|
944
|
+
* schedule's output is needed.
|
|
945
|
+
*
|
|
946
|
+
* **Example** (Combining schedules and keeping the right output)
|
|
947
|
+
*
|
|
948
|
+
* ```ts
|
|
949
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
950
|
+
*
|
|
951
|
+
* // Combine two schedules, keeping right output
|
|
952
|
+
* const leftSchedule = Schedule.exponential("100 millis").pipe(
|
|
953
|
+
* Schedule.map(() => Effect.succeed("left-result"))
|
|
954
|
+
* )
|
|
955
|
+
* const rightSchedule = Schedule.spaced("50 millis").pipe(
|
|
956
|
+
* Schedule.map(() => Effect.succeed("right-result"))
|
|
957
|
+
* )
|
|
958
|
+
*
|
|
959
|
+
* const combined = Schedule.bothRight(leftSchedule, rightSchedule)
|
|
960
|
+
*
|
|
961
|
+
* const program = Effect.gen(function*() {
|
|
962
|
+
* yield* Effect.repeat(
|
|
963
|
+
* Effect.gen(function*() {
|
|
964
|
+
* yield* Console.log("Task executed")
|
|
965
|
+
* return "task-done"
|
|
966
|
+
* }),
|
|
967
|
+
* combined.pipe(Schedule.take(3))
|
|
968
|
+
* )
|
|
969
|
+
* })
|
|
970
|
+
* ```
|
|
971
|
+
*
|
|
972
|
+
* @category combining
|
|
973
|
+
* @since 2.0.0
|
|
974
|
+
*/
|
|
975
|
+
export const bothRight: {
|
|
976
|
+
<Output2, Input2, Error2, Env2>(
|
|
977
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
978
|
+
): <Output, Input, Error, Env>(
|
|
979
|
+
self: Schedule<Output, Input, Error, Env>
|
|
980
|
+
) => Schedule<Output, Input & Input2, Error | Error2, Env | Env2>
|
|
981
|
+
<Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
982
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
983
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
984
|
+
): Schedule<Output, Input & Input2, Error | Error2, Env | Env2>
|
|
985
|
+
} = dual(2, <Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
986
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
987
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
988
|
+
): Schedule<Output2, Input & Input2, Error | Error2, Env | Env2> => bothWith(self, other, (_, output) => output))
|
|
989
|
+
|
|
990
|
+
/**
|
|
991
|
+
* Combines two `Schedule`s by recurring if both of the two schedules want
|
|
992
|
+
* to recur, using the maximum of the two durations between recurrences and
|
|
993
|
+
* outputting the result of the combination of both schedule outputs using the
|
|
994
|
+
* specified `combine` function.
|
|
995
|
+
*
|
|
996
|
+
* **When to use**
|
|
997
|
+
*
|
|
998
|
+
* Use when two schedules must both allow recurrence and their outputs should be
|
|
999
|
+
* combined into a custom value.
|
|
1000
|
+
*
|
|
1001
|
+
* **Example** (Combining schedule outputs)
|
|
1002
|
+
*
|
|
1003
|
+
* ```ts
|
|
1004
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
1005
|
+
*
|
|
1006
|
+
* // Combine two schedules with custom output combination
|
|
1007
|
+
* const leftSchedule = Schedule.exponential("100 millis").pipe(
|
|
1008
|
+
* Schedule.map(() => Effect.succeed("left"))
|
|
1009
|
+
* )
|
|
1010
|
+
* const rightSchedule = Schedule.spaced("50 millis").pipe(
|
|
1011
|
+
* Schedule.map(() => Effect.succeed("right"))
|
|
1012
|
+
* )
|
|
1013
|
+
*
|
|
1014
|
+
* const combined = Schedule.bothWith(
|
|
1015
|
+
* leftSchedule,
|
|
1016
|
+
* rightSchedule,
|
|
1017
|
+
* (left, right) => `${left}-${right}`
|
|
1018
|
+
* )
|
|
1019
|
+
*
|
|
1020
|
+
* const program = Effect.gen(function*() {
|
|
1021
|
+
* yield* Effect.repeat(
|
|
1022
|
+
* Effect.gen(function*() {
|
|
1023
|
+
* yield* Console.log("Task executed")
|
|
1024
|
+
* return "task-result"
|
|
1025
|
+
* }),
|
|
1026
|
+
* combined.pipe(Schedule.take(3))
|
|
1027
|
+
* )
|
|
1028
|
+
* })
|
|
1029
|
+
* ```
|
|
1030
|
+
*
|
|
1031
|
+
* @category combining
|
|
1032
|
+
* @since 2.0.0
|
|
1033
|
+
*/
|
|
1034
|
+
export const bothWith: {
|
|
1035
|
+
<Output2, Input2, Error2, Env2, Output, Output3>(
|
|
1036
|
+
other: Schedule<Output2, Input2, Error2, Env2>,
|
|
1037
|
+
combine: (selfOutput: Output, otherOutput: Output2) => Output3
|
|
1038
|
+
): <Output, Input, Error, Env>(
|
|
1039
|
+
self: Schedule<Output, Input, Error, Env>
|
|
1040
|
+
) => Schedule<Output3, Input & Input2, Error | Error2, Env | Env2>
|
|
1041
|
+
<Output, Input, Error, Env, Output2, Input2, Error2, Env2, Output3>(
|
|
1042
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
1043
|
+
other: Schedule<Output2, Input2, Error2, Env2>,
|
|
1044
|
+
combine: (selfOutput: Output, otherOutput: Output2) => Output3
|
|
1045
|
+
): Schedule<Output3, Input & Input2, Error | Error2, Env | Env2>
|
|
1046
|
+
} = dual(3, <Output, Input, Error, Env, Output2, Input2, Error2, Env2, Output3>(
|
|
1047
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
1048
|
+
other: Schedule<Output2, Input2, Error2, Env2>,
|
|
1049
|
+
combine: (selfOutput: Output, otherOutput: Output2) => Output3
|
|
1050
|
+
): Schedule<Output3, Input & Input2, Error | Error2, Env | Env2> =>
|
|
1051
|
+
fromStep(effect.map(
|
|
1052
|
+
effect.zip(toStep(self), toStep(other)),
|
|
1053
|
+
([stepLeft, stepRight]) => (now, input) =>
|
|
1054
|
+
Pull.matchEffect(stepLeft(now, input as Input), {
|
|
1055
|
+
onSuccess: (leftResult) =>
|
|
1056
|
+
stepRight(now, input as Input2).pipe(
|
|
1057
|
+
effect.map((rightResult) =>
|
|
1058
|
+
[
|
|
1059
|
+
combine(leftResult[0], rightResult[0]),
|
|
1060
|
+
Duration.max(leftResult[1], rightResult[1])
|
|
1061
|
+
] as [Output3, Duration.Duration]
|
|
1062
|
+
),
|
|
1063
|
+
Pull.catchDone((rightDone) => Cause.done(combine(leftResult[0], rightDone as Output2)))
|
|
1064
|
+
),
|
|
1065
|
+
onDone: (leftDone) =>
|
|
1066
|
+
stepRight(now, input as Input2).pipe(
|
|
1067
|
+
effect.flatMap((rightResult) => Cause.done(combine(leftDone, rightResult[0]))),
|
|
1068
|
+
Pull.catchDone((rightDone) => Cause.done(combine(leftDone, rightDone as Output2)))
|
|
1069
|
+
),
|
|
1070
|
+
onFailure: effect.failCause
|
|
1071
|
+
})
|
|
1072
|
+
)))
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* Returns a new `Schedule` that follows `self` and outputs the inputs seen so
|
|
1076
|
+
* far as an array.
|
|
1077
|
+
*
|
|
1078
|
+
* **Details**
|
|
1079
|
+
*
|
|
1080
|
+
* This does not make the schedule run forever. The collected schedule stops
|
|
1081
|
+
* when `self` stops and fails when `self` fails.
|
|
1082
|
+
*
|
|
1083
|
+
* **Example** (Collecting schedule inputs)
|
|
1084
|
+
*
|
|
1085
|
+
* ```ts
|
|
1086
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
1087
|
+
*
|
|
1088
|
+
* // Collect all inputs passed to the schedule
|
|
1089
|
+
* const inputCollector = Schedule.collectInputs(
|
|
1090
|
+
* Schedule.spaced("100 millis")
|
|
1091
|
+
* )
|
|
1092
|
+
*
|
|
1093
|
+
* const program = Effect.gen(function*() {
|
|
1094
|
+
* let counter = 0
|
|
1095
|
+
* yield* Effect.repeat(
|
|
1096
|
+
* Effect.gen(function*() {
|
|
1097
|
+
* counter++
|
|
1098
|
+
* yield* Console.log(`Iteration ${counter}`)
|
|
1099
|
+
* return `result-${counter}`
|
|
1100
|
+
* }),
|
|
1101
|
+
* inputCollector.pipe(Schedule.take(4))
|
|
1102
|
+
* )
|
|
1103
|
+
* })
|
|
1104
|
+
* ```
|
|
1105
|
+
*
|
|
1106
|
+
* @category collecting
|
|
1107
|
+
* @since 4.0.0
|
|
1108
|
+
*/
|
|
1109
|
+
export const collectInputs = <Output, Input, Error, Env>(
|
|
1110
|
+
self: Schedule<Output, Input, Error, Env>
|
|
1111
|
+
): Schedule<Array<Input>, Input, Error, Env> => collectWhile(passthrough(self), () => effect.succeed(true))
|
|
1112
|
+
|
|
1113
|
+
/**
|
|
1114
|
+
* Returns a new `Schedule` that follows `self` and outputs the schedule outputs
|
|
1115
|
+
* seen so far as an array.
|
|
1116
|
+
*
|
|
1117
|
+
* **Details**
|
|
1118
|
+
*
|
|
1119
|
+
* This does not make the schedule run forever. The collected schedule stops
|
|
1120
|
+
* when `self` stops and fails when `self` fails.
|
|
1121
|
+
*
|
|
1122
|
+
* **Example** (Collecting schedule outputs)
|
|
1123
|
+
*
|
|
1124
|
+
* ```ts
|
|
1125
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
1126
|
+
*
|
|
1127
|
+
* // Collect all outputs from the schedule
|
|
1128
|
+
* const outputCollector = Schedule.collectOutputs(
|
|
1129
|
+
* Schedule.recurs(4)
|
|
1130
|
+
* )
|
|
1131
|
+
*
|
|
1132
|
+
* const program = Effect.gen(function*() {
|
|
1133
|
+
* yield* Effect.repeat(
|
|
1134
|
+
* Effect.gen(function*() {
|
|
1135
|
+
* yield* Console.log("Task executed")
|
|
1136
|
+
* return "task-result"
|
|
1137
|
+
* }),
|
|
1138
|
+
* outputCollector.pipe(Schedule.take(4))
|
|
1139
|
+
* )
|
|
1140
|
+
* })
|
|
1141
|
+
* ```
|
|
1142
|
+
*
|
|
1143
|
+
* @category collecting
|
|
1144
|
+
* @since 4.0.0
|
|
1145
|
+
*/
|
|
1146
|
+
export const collectOutputs = <Output, Input, Error, Env>(
|
|
1147
|
+
self: Schedule<Output, Input, Error, Env>
|
|
1148
|
+
): Schedule<Array<Output>, Input, Error, Env> => collectWhile(self, () => effect.succeed(true))
|
|
1149
|
+
|
|
1150
|
+
/**
|
|
1151
|
+
* Returns a new `Schedule` that recurs as long as the specified `predicate`
|
|
1152
|
+
* returns `true`, collecting all outputs of the schedule into an array.
|
|
1153
|
+
*
|
|
1154
|
+
* **Example** (Collecting outputs while a condition holds)
|
|
1155
|
+
*
|
|
1156
|
+
* ```ts
|
|
1157
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
1158
|
+
*
|
|
1159
|
+
* // Collect outputs while condition is met
|
|
1160
|
+
* const collectWhileSmall = Schedule.collectWhile(
|
|
1161
|
+
* Schedule.exponential("100 millis"),
|
|
1162
|
+
* (metadata) =>
|
|
1163
|
+
* Effect.succeed(metadata.attempt <= 5 && metadata.elapsed < 2000)
|
|
1164
|
+
* )
|
|
1165
|
+
*
|
|
1166
|
+
* const conditionalProgram = Effect.gen(function*() {
|
|
1167
|
+
* let attempt = 0
|
|
1168
|
+
*
|
|
1169
|
+
* const attempts = yield* Effect.repeat(
|
|
1170
|
+
* Effect.gen(function*() {
|
|
1171
|
+
* attempt++
|
|
1172
|
+
* yield* Console.log(`Retry attempt ${attempt}`)
|
|
1173
|
+
* return `attempt-${attempt}`
|
|
1174
|
+
* }),
|
|
1175
|
+
* collectWhileSmall
|
|
1176
|
+
* )
|
|
1177
|
+
*
|
|
1178
|
+
* yield* Console.log(`Collected attempts: [${attempts.join(", ")}]`)
|
|
1179
|
+
* })
|
|
1180
|
+
*
|
|
1181
|
+
* // Collect with effectful predicate
|
|
1182
|
+
* const collectWithCheck = Schedule.collectWhile(
|
|
1183
|
+
* Schedule.fixed("1 second"),
|
|
1184
|
+
* (metadata) =>
|
|
1185
|
+
* Effect.gen(function*() {
|
|
1186
|
+
* const shouldContinue = metadata.attempt < 5
|
|
1187
|
+
* yield* Console.log(
|
|
1188
|
+
* `Check ${metadata.attempt}: continue = ${shouldContinue}`
|
|
1189
|
+
* )
|
|
1190
|
+
* return shouldContinue
|
|
1191
|
+
* })
|
|
1192
|
+
* )
|
|
1193
|
+
*
|
|
1194
|
+
* const effectfulProgram = Effect.gen(function*() {
|
|
1195
|
+
* const results = yield* Effect.repeat(
|
|
1196
|
+
* Effect.succeed("checked"),
|
|
1197
|
+
* collectWithCheck
|
|
1198
|
+
* )
|
|
1199
|
+
*
|
|
1200
|
+
* yield* Console.log(`Final collection: ${results.length} items`)
|
|
1201
|
+
* })
|
|
1202
|
+
*
|
|
1203
|
+
* // Collect samples with condition
|
|
1204
|
+
* const samples = [12, 18, 24, 30, 36]
|
|
1205
|
+
*
|
|
1206
|
+
* const collectSamples = Schedule.collectWhile(
|
|
1207
|
+
* Schedule.spaced("200 millis"),
|
|
1208
|
+
* (metadata) =>
|
|
1209
|
+
* Effect.succeed(metadata.attempt <= 5 && metadata.elapsed < 2000)
|
|
1210
|
+
* )
|
|
1211
|
+
*
|
|
1212
|
+
* const samplingProgram = Effect.gen(function*() {
|
|
1213
|
+
* let index = 0
|
|
1214
|
+
* const collected = yield* Effect.repeat(
|
|
1215
|
+
* Effect.gen(function*() {
|
|
1216
|
+
* const sample = samples[index++]
|
|
1217
|
+
* yield* Console.log(`Sample: ${sample}`)
|
|
1218
|
+
* return sample
|
|
1219
|
+
* }),
|
|
1220
|
+
* collectSamples
|
|
1221
|
+
* )
|
|
1222
|
+
*
|
|
1223
|
+
* const average = collected.reduce((sum, s) => sum + s, 0) / collected.length
|
|
1224
|
+
* yield* Console.log(
|
|
1225
|
+
* `Collected ${collected.length} samples, average: ${average.toFixed(1)}`
|
|
1226
|
+
* )
|
|
1227
|
+
* })
|
|
1228
|
+
* ```
|
|
1229
|
+
*
|
|
1230
|
+
* @category collecting
|
|
1231
|
+
* @since 2.0.0
|
|
1232
|
+
*/
|
|
1233
|
+
export const collectWhile: {
|
|
1234
|
+
<Input, Output, Error2 = never, Env2 = never>(
|
|
1235
|
+
predicate: (
|
|
1236
|
+
metadata: Metadata<Output, Input>
|
|
1237
|
+
) => boolean | Effect<boolean, Error2, Env2>
|
|
1238
|
+
): <Error, Env>(
|
|
1239
|
+
self: Schedule<Output, Input, Error, Env>
|
|
1240
|
+
) => Schedule<Array<Output>, Input, Error | Error2, Env | Env2>
|
|
1241
|
+
<Output, Input, Error, Env, Error2 = never, Env2 = never>(
|
|
1242
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
1243
|
+
predicate: (
|
|
1244
|
+
metadata: Metadata<Output, Input>
|
|
1245
|
+
) => boolean | Effect<boolean, Error2, Env2>
|
|
1246
|
+
): Schedule<Array<Output>, Input, Error | Error2, Env | Env2>
|
|
1247
|
+
} = dual(2, <Output, Input, Error, Env, Error2 = never, Env2 = never>(
|
|
1248
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
1249
|
+
predicate: (
|
|
1250
|
+
metadata: Metadata<Output, Input>
|
|
1251
|
+
) => boolean | Effect<boolean, Error2, Env2>
|
|
1252
|
+
): Schedule<Array<Output>, Input, Error | Error2, Env | Env2> =>
|
|
1253
|
+
reduce(while_(self, predicate), () => [] as Array<Output>, (outputs, output) => {
|
|
1254
|
+
outputs.push(output)
|
|
1255
|
+
return outputs
|
|
1256
|
+
}))
|
|
1257
|
+
|
|
1258
|
+
/**
|
|
1259
|
+
* Returns a new `Schedule` that recurs on the specified `Cron` schedule and
|
|
1260
|
+
* outputs the duration between recurrences.
|
|
1261
|
+
*
|
|
1262
|
+
* **Example** (Scheduling work with cron expressions)
|
|
1263
|
+
*
|
|
1264
|
+
* ```ts
|
|
1265
|
+
* import { Console, Data, Effect, Schedule } from "effect"
|
|
1266
|
+
*
|
|
1267
|
+
* class ScheduledTaskError extends Data.TaggedError("ScheduledTaskError")<{ readonly message: string }> {}
|
|
1268
|
+
*
|
|
1269
|
+
* // Run every minute
|
|
1270
|
+
* const everyMinute = Schedule.cron("* * * * *")
|
|
1271
|
+
*
|
|
1272
|
+
* const minutelyProgram = Effect.gen(function*() {
|
|
1273
|
+
* yield* Effect.repeat(
|
|
1274
|
+
* Effect.gen(function*() {
|
|
1275
|
+
* yield* Console.log("Running minutely task")
|
|
1276
|
+
* return "minute"
|
|
1277
|
+
* }),
|
|
1278
|
+
* everyMinute.pipe(
|
|
1279
|
+
* Schedule.take(3), // Run only 3 times for demo
|
|
1280
|
+
* Schedule.tapOutput((duration) =>
|
|
1281
|
+
* Console.log(`Next execution in: ${duration}`)
|
|
1282
|
+
* )
|
|
1283
|
+
* )
|
|
1284
|
+
* )
|
|
1285
|
+
* })
|
|
1286
|
+
*
|
|
1287
|
+
* // Run every day at 2:30 AM
|
|
1288
|
+
* const dailyBackup = Schedule.cron("30 2 * * *")
|
|
1289
|
+
*
|
|
1290
|
+
* const backupProgram = Effect.gen(function*() {
|
|
1291
|
+
* yield* Effect.repeat(
|
|
1292
|
+
* Effect.gen(function*() {
|
|
1293
|
+
* yield* Console.log("Running daily backup...")
|
|
1294
|
+
* // Simulate backup process
|
|
1295
|
+
* yield* Effect.sleep("2 seconds")
|
|
1296
|
+
* yield* Console.log("Backup completed")
|
|
1297
|
+
* return "backup-done"
|
|
1298
|
+
* }),
|
|
1299
|
+
* dailyBackup.pipe(
|
|
1300
|
+
* Schedule.take(2) // Run 2 times for demo
|
|
1301
|
+
* )
|
|
1302
|
+
* )
|
|
1303
|
+
* })
|
|
1304
|
+
*
|
|
1305
|
+
* // Run every Monday at 9:00 AM with timezone
|
|
1306
|
+
* const weeklyReport = Schedule.cron("0 9 * * 1", "America/New_York")
|
|
1307
|
+
*
|
|
1308
|
+
* const reportProgram = Effect.gen(function*() {
|
|
1309
|
+
* yield* Effect.repeat(
|
|
1310
|
+
* Effect.gen(function*() {
|
|
1311
|
+
* yield* Console.log("Generating weekly report...")
|
|
1312
|
+
* const report = {
|
|
1313
|
+
* week: 42,
|
|
1314
|
+
* status: "ready" as const
|
|
1315
|
+
* }
|
|
1316
|
+
* yield* Console.log(`Report generated: ${JSON.stringify(report)}`)
|
|
1317
|
+
* return report
|
|
1318
|
+
* }),
|
|
1319
|
+
* weeklyReport.pipe(Schedule.take(1))
|
|
1320
|
+
* )
|
|
1321
|
+
* })
|
|
1322
|
+
*
|
|
1323
|
+
* // Run every 15 minutes during business hours (9 AM - 5 PM)
|
|
1324
|
+
* const businessHoursCheck = Schedule.cron("0,15,30,45 9-17 * * 1-5")
|
|
1325
|
+
*
|
|
1326
|
+
* const businessProgram = Effect.gen(function*() {
|
|
1327
|
+
* const statuses = ["healthy", "healthy", "degraded", "healthy"] as const
|
|
1328
|
+
* let index = 0
|
|
1329
|
+
*
|
|
1330
|
+
* yield* Effect.repeat(
|
|
1331
|
+
* Effect.gen(function*() {
|
|
1332
|
+
* yield* Console.log("Business hours health check...")
|
|
1333
|
+
* const status = statuses[index++]
|
|
1334
|
+
* yield* Console.log(`System status: ${status}`)
|
|
1335
|
+
* return status
|
|
1336
|
+
* }),
|
|
1337
|
+
* businessHoursCheck.pipe(
|
|
1338
|
+
* Schedule.take(4) // Demo with 4 checks
|
|
1339
|
+
* )
|
|
1340
|
+
* )
|
|
1341
|
+
* })
|
|
1342
|
+
*
|
|
1343
|
+
* // Run on specific days of the month
|
|
1344
|
+
* const monthlyInvoice = Schedule.cron("0 10 1,15 * *") // 1st and 15th at 10 AM
|
|
1345
|
+
*
|
|
1346
|
+
* const invoiceProgram = Effect.gen(function*() {
|
|
1347
|
+
* yield* Effect.repeat(
|
|
1348
|
+
* Effect.gen(function*() {
|
|
1349
|
+
* yield* Console.log("Processing monthly invoices...")
|
|
1350
|
+
* const invoiceCount = 72
|
|
1351
|
+
* yield* Console.log(`Processed ${invoiceCount} invoices`)
|
|
1352
|
+
* return { count: invoiceCount, batch: "2024-01-a" }
|
|
1353
|
+
* }),
|
|
1354
|
+
* monthlyInvoice.pipe(Schedule.take(1))
|
|
1355
|
+
* )
|
|
1356
|
+
* })
|
|
1357
|
+
*
|
|
1358
|
+
* // Complex cron with error handling
|
|
1359
|
+
* const complexCron = Schedule.cron("0 2,4,6 * * *").pipe(
|
|
1360
|
+
* Schedule.tapOutput((duration) =>
|
|
1361
|
+
* Console.log(`Scheduled to run again in ${duration}`)
|
|
1362
|
+
* )
|
|
1363
|
+
* )
|
|
1364
|
+
*
|
|
1365
|
+
* const robustProgram = Effect.gen(function*() {
|
|
1366
|
+
* let attempt = 0
|
|
1367
|
+
*
|
|
1368
|
+
* yield* Effect.repeat(
|
|
1369
|
+
* Effect.gen(function*() {
|
|
1370
|
+
* attempt++
|
|
1371
|
+
* yield* Console.log("Complex scheduled task...")
|
|
1372
|
+
* if (attempt === 1) {
|
|
1373
|
+
* return yield* Effect.fail(new ScheduledTaskError({ message: "Scheduled task failed" }))
|
|
1374
|
+
* }
|
|
1375
|
+
* return "success"
|
|
1376
|
+
* }),
|
|
1377
|
+
* complexCron.pipe(Schedule.take(3))
|
|
1378
|
+
* ).pipe(
|
|
1379
|
+
* Effect.catch((error: unknown) =>
|
|
1380
|
+
* Console.log(`Cron task error: ${String(error)}`)
|
|
1381
|
+
* )
|
|
1382
|
+
* )
|
|
1383
|
+
* })
|
|
1384
|
+
* ```
|
|
1385
|
+
*
|
|
1386
|
+
* @category constructors
|
|
1387
|
+
* @since 2.0.0
|
|
1388
|
+
*/
|
|
1389
|
+
export const cron: {
|
|
1390
|
+
(expression: Cron.Cron): Schedule<Duration.Duration, unknown, Cron.CronParseError>
|
|
1391
|
+
(expression: string, tz?: string | DateTime.TimeZone): Schedule<Duration.Duration, unknown, Cron.CronParseError>
|
|
1392
|
+
} = (expression: string | Cron.Cron, tz?: string | DateTime.TimeZone) => {
|
|
1393
|
+
const parsed = Cron.isCron(expression) ? Result.succeed(expression) : Cron.parse(expression, tz)
|
|
1394
|
+
return fromStep(effect.map(effect.fromResult(parsed), (cron) => (now, _) =>
|
|
1395
|
+
effect.sync(() => {
|
|
1396
|
+
const next = Cron.next(cron, now).getTime()
|
|
1397
|
+
const duration = Duration.millis(next - now)
|
|
1398
|
+
return [duration, duration]
|
|
1399
|
+
})))
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
/**
|
|
1403
|
+
* Returns a new schedule that outputs the delay between each occurrence.
|
|
1404
|
+
*
|
|
1405
|
+
* **Example** (Extracting schedule delays)
|
|
1406
|
+
*
|
|
1407
|
+
* ```ts
|
|
1408
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
1409
|
+
*
|
|
1410
|
+
* // Extract delays from an exponential backoff schedule
|
|
1411
|
+
* const exponentialDelays = Schedule.delays(
|
|
1412
|
+
* Schedule.exponential("100 millis").pipe(Schedule.take(5))
|
|
1413
|
+
* )
|
|
1414
|
+
*
|
|
1415
|
+
* const delayProgram = Effect.gen(function*() {
|
|
1416
|
+
* yield* Effect.repeat(
|
|
1417
|
+
* Effect.gen(function*() {
|
|
1418
|
+
* yield* Console.log("Task executed")
|
|
1419
|
+
* return "task result"
|
|
1420
|
+
* }),
|
|
1421
|
+
* exponentialDelays.pipe(
|
|
1422
|
+
* Schedule.tapOutput((delay) =>
|
|
1423
|
+
* Console.log(`Waiting ${delay} before next execution`)
|
|
1424
|
+
* )
|
|
1425
|
+
* )
|
|
1426
|
+
* )
|
|
1427
|
+
* })
|
|
1428
|
+
*
|
|
1429
|
+
* // Monitor delays from a Fibonacci schedule
|
|
1430
|
+
* const fibonacciDelays = Schedule.delays(
|
|
1431
|
+
* Schedule.fibonacci("200 millis").pipe(Schedule.take(8))
|
|
1432
|
+
* )
|
|
1433
|
+
*
|
|
1434
|
+
* const fibDelayProgram = Effect.gen(function*() {
|
|
1435
|
+
* yield* Effect.repeat(
|
|
1436
|
+
* Console.log("Fibonacci task"),
|
|
1437
|
+
* fibonacciDelays.pipe(
|
|
1438
|
+
* Schedule.tapOutput((delay) => Console.log(`Fibonacci delay: ${delay}`))
|
|
1439
|
+
* )
|
|
1440
|
+
* )
|
|
1441
|
+
* })
|
|
1442
|
+
*
|
|
1443
|
+
* // Extract delays for analysis or logging
|
|
1444
|
+
* const analyzeDelays = Schedule.delays(
|
|
1445
|
+
* Schedule.spaced("1 second").pipe(Schedule.take(3))
|
|
1446
|
+
* ).pipe(
|
|
1447
|
+
* Schedule.tapOutput((delay) =>
|
|
1448
|
+
* Effect.gen(function*() {
|
|
1449
|
+
* yield* Console.log(`Recorded delay: ${delay}`)
|
|
1450
|
+
* // In real applications, might send to metrics system
|
|
1451
|
+
* })
|
|
1452
|
+
* )
|
|
1453
|
+
* )
|
|
1454
|
+
*
|
|
1455
|
+
* // Combine delays with other schedules for complex timing
|
|
1456
|
+
* const adaptiveSchedule = Schedule.unfold(100, (delay) => Effect.succeed(delay * 1.5)).pipe(
|
|
1457
|
+
* Schedule.take(6)
|
|
1458
|
+
* )
|
|
1459
|
+
*
|
|
1460
|
+
* const adaptiveDelays = Schedule.delays(adaptiveSchedule)
|
|
1461
|
+
*
|
|
1462
|
+
* const adaptiveProgram = Effect.gen(function*() {
|
|
1463
|
+
* yield* Effect.repeat(
|
|
1464
|
+
* Effect.gen(function*() {
|
|
1465
|
+
* yield* Console.log("Adaptive task execution")
|
|
1466
|
+
* return "completed"
|
|
1467
|
+
* }),
|
|
1468
|
+
* adaptiveDelays.pipe(
|
|
1469
|
+
* Schedule.tapOutput((delay) => Console.log(`Adaptive delay: ${delay}`))
|
|
1470
|
+
* )
|
|
1471
|
+
* )
|
|
1472
|
+
* })
|
|
1473
|
+
*
|
|
1474
|
+
* // Use delays to implement custom timing logic
|
|
1475
|
+
* const customTimingSchedule = Schedule.delays(
|
|
1476
|
+
* Schedule.exponential("50 millis").pipe(Schedule.take(4))
|
|
1477
|
+
* ).pipe(
|
|
1478
|
+
* Schedule.map((delay) => Effect.succeed(`Next execution in ${delay}`)),
|
|
1479
|
+
* Schedule.tapOutput((message) => Console.log(message))
|
|
1480
|
+
* )
|
|
1481
|
+
* ```
|
|
1482
|
+
*
|
|
1483
|
+
* @category constructors
|
|
1484
|
+
* @since 2.0.0
|
|
1485
|
+
*/
|
|
1486
|
+
export const delays = <Out, In, E, R>(self: Schedule<Out, In, E, R>): Schedule<Duration.Duration, In, E, R> =>
|
|
1487
|
+
fromStep(
|
|
1488
|
+
effect.map(
|
|
1489
|
+
toStep(self),
|
|
1490
|
+
(step) => (now, input) =>
|
|
1491
|
+
Pull.catchDone(
|
|
1492
|
+
effect.map(step(now, input), ([_, duration]) => [duration, duration]),
|
|
1493
|
+
(_) => Cause.done(Duration.zero)
|
|
1494
|
+
)
|
|
1495
|
+
)
|
|
1496
|
+
)
|
|
1497
|
+
|
|
1498
|
+
/**
|
|
1499
|
+
* Returns a schedule that recurs once after the specified duration.
|
|
1500
|
+
*
|
|
1501
|
+
* **When to use**
|
|
1502
|
+
*
|
|
1503
|
+
* Use when you need a schedule that recurs once after a fixed delay.
|
|
1504
|
+
*
|
|
1505
|
+
* **Details**
|
|
1506
|
+
*
|
|
1507
|
+
* The schedule outputs the configured duration for its first recurrence and
|
|
1508
|
+
* then completes.
|
|
1509
|
+
*
|
|
1510
|
+
* **Example** (Recurring once after a duration)
|
|
1511
|
+
*
|
|
1512
|
+
* ```ts
|
|
1513
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
1514
|
+
*
|
|
1515
|
+
* const program = Effect.repeat(
|
|
1516
|
+
* Console.log("runs again after one second"),
|
|
1517
|
+
* Schedule.duration("1 second")
|
|
1518
|
+
* )
|
|
1519
|
+
* ```
|
|
1520
|
+
*
|
|
1521
|
+
* @see {@link during} for recurring until a duration has elapsed
|
|
1522
|
+
*
|
|
1523
|
+
* @category constructors
|
|
1524
|
+
* @since 2.0.0
|
|
1525
|
+
*/
|
|
1526
|
+
export const duration = (durationInput: Duration.Input): Schedule<Duration.Duration> => {
|
|
1527
|
+
const duration = Duration.fromInputUnsafe(durationInput)
|
|
1528
|
+
return fromStepWithMetadata(effect.succeed((meta) =>
|
|
1529
|
+
meta.attempt === 1
|
|
1530
|
+
? effect.succeed([duration, duration])
|
|
1531
|
+
: Cause.done(Duration.zero)
|
|
1532
|
+
))
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
/**
|
|
1536
|
+
* Returns a new `Schedule` that will always recur, but only during the
|
|
1537
|
+
* specified `duration` of time.
|
|
1538
|
+
*
|
|
1539
|
+
* **When to use**
|
|
1540
|
+
*
|
|
1541
|
+
* Use to bound a repeating or retrying schedule by elapsed time.
|
|
1542
|
+
*
|
|
1543
|
+
* **Example** (Repeating work during a duration)
|
|
1544
|
+
*
|
|
1545
|
+
* ```ts
|
|
1546
|
+
* import { Console, Data, Effect, Schedule } from "effect"
|
|
1547
|
+
*
|
|
1548
|
+
* class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
|
|
1549
|
+
*
|
|
1550
|
+
* // Run a task for exactly 5 seconds, regardless of how many iterations
|
|
1551
|
+
* const fiveSecondSchedule = Schedule.during("5 seconds")
|
|
1552
|
+
*
|
|
1553
|
+
* const timedProgram = Effect.gen(function*() {
|
|
1554
|
+
* yield* Effect.repeat(
|
|
1555
|
+
* Effect.gen(function*() {
|
|
1556
|
+
* yield* Console.log("Task executed inside the time window")
|
|
1557
|
+
* yield* Effect.sleep("500 millis") // Each task takes 500ms
|
|
1558
|
+
* return "task done"
|
|
1559
|
+
* }),
|
|
1560
|
+
* fiveSecondSchedule.pipe(
|
|
1561
|
+
* Schedule.tapOutput((elapsedDuration) =>
|
|
1562
|
+
* Console.log(`Total elapsed: ${elapsedDuration}`)
|
|
1563
|
+
* )
|
|
1564
|
+
* )
|
|
1565
|
+
* )
|
|
1566
|
+
*
|
|
1567
|
+
* yield* Console.log("Time limit reached!")
|
|
1568
|
+
* })
|
|
1569
|
+
*
|
|
1570
|
+
* // Combine with other schedules for time-bounded execution
|
|
1571
|
+
* const timeAndCountLimited = Schedule.spaced("1 second").pipe(
|
|
1572
|
+
* Schedule.both(Schedule.during("10 seconds")), // Stop after 10 seconds OR
|
|
1573
|
+
* Schedule.both(Schedule.recurs(15)) // 15 attempts, whichever comes first
|
|
1574
|
+
* )
|
|
1575
|
+
*
|
|
1576
|
+
* // Burst execution within time window
|
|
1577
|
+
* const burstWindow = Schedule.during("3 seconds")
|
|
1578
|
+
*
|
|
1579
|
+
* const burstProgram = Effect.gen(function*() {
|
|
1580
|
+
* yield* Console.log("Starting burst execution...")
|
|
1581
|
+
*
|
|
1582
|
+
* yield* Effect.repeat(
|
|
1583
|
+
* Effect.gen(function*() {
|
|
1584
|
+
* yield* Console.log("Burst task")
|
|
1585
|
+
* return "burst"
|
|
1586
|
+
* }),
|
|
1587
|
+
* burstWindow
|
|
1588
|
+
* )
|
|
1589
|
+
*
|
|
1590
|
+
* yield* Console.log("Burst window completed")
|
|
1591
|
+
* })
|
|
1592
|
+
*
|
|
1593
|
+
* // Timed retry window - retry for up to 30 seconds
|
|
1594
|
+
* const timedRetry = Schedule.exponential("200 millis").pipe(
|
|
1595
|
+
* Schedule.both(Schedule.during("30 seconds"))
|
|
1596
|
+
* )
|
|
1597
|
+
*
|
|
1598
|
+
* const retryProgram = Effect.gen(function*() {
|
|
1599
|
+
* let attempt = 0
|
|
1600
|
+
*
|
|
1601
|
+
* const result = yield* Effect.retry(
|
|
1602
|
+
* Effect.gen(function*() {
|
|
1603
|
+
* attempt++
|
|
1604
|
+
* yield* Console.log(`Retry attempt ${attempt}`)
|
|
1605
|
+
*
|
|
1606
|
+
* if (attempt < 4) {
|
|
1607
|
+
* return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
|
|
1608
|
+
* }
|
|
1609
|
+
*
|
|
1610
|
+
* return `Success on attempt ${attempt}`
|
|
1611
|
+
* }),
|
|
1612
|
+
* timedRetry
|
|
1613
|
+
* )
|
|
1614
|
+
*
|
|
1615
|
+
* yield* Console.log(`Result: ${result}`)
|
|
1616
|
+
* }).pipe(
|
|
1617
|
+
* Effect.catch((error: unknown) => Console.log(`Timed out: ${String(error)}`))
|
|
1618
|
+
* )
|
|
1619
|
+
* ```
|
|
1620
|
+
*
|
|
1621
|
+
* @see {@link duration} for one delayed recurrence
|
|
1622
|
+
*
|
|
1623
|
+
* @category constructors
|
|
1624
|
+
* @since 4.0.0
|
|
1625
|
+
*/
|
|
1626
|
+
export const during = (duration: Duration.Input): Schedule<Duration.Duration> =>
|
|
1627
|
+
while_(
|
|
1628
|
+
elapsed,
|
|
1629
|
+
({ output }) => effect.succeed(Duration.isLessThanOrEqualTo(output, Duration.fromInputUnsafe(duration)))
|
|
1630
|
+
)
|
|
1631
|
+
|
|
1632
|
+
/**
|
|
1633
|
+
* Combines two `Schedule`s by recurring if either of the two schedules wants
|
|
1634
|
+
* to recur, using the minimum of the two durations between recurrences and
|
|
1635
|
+
* outputting a tuple of the outputs of both schedules.
|
|
1636
|
+
*
|
|
1637
|
+
* **When to use**
|
|
1638
|
+
*
|
|
1639
|
+
* Use when the combined schedule should continue while at least one schedule still recurs.
|
|
1640
|
+
*
|
|
1641
|
+
* **Example** (Combining schedules with either semantics)
|
|
1642
|
+
*
|
|
1643
|
+
* ```ts
|
|
1644
|
+
* import { Console, Data, Effect, Schedule } from "effect"
|
|
1645
|
+
*
|
|
1646
|
+
* class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
|
|
1647
|
+
*
|
|
1648
|
+
* // Either continues as long as at least one schedule wants to continue
|
|
1649
|
+
* const timeBasedSchedule = Schedule.spaced("2 seconds").pipe(Schedule.take(3))
|
|
1650
|
+
* const countBasedSchedule = Schedule.recurs(5)
|
|
1651
|
+
*
|
|
1652
|
+
* // Continues until both schedules are exhausted (either still wants to recur)
|
|
1653
|
+
* const eitherSchedule = Schedule.either(timeBasedSchedule, countBasedSchedule)
|
|
1654
|
+
* // Outputs: [time_result, count_result] tuple
|
|
1655
|
+
*
|
|
1656
|
+
* const program = Effect.gen(function*() {
|
|
1657
|
+
* const results = yield* Effect.repeat(
|
|
1658
|
+
* Effect.gen(function*() {
|
|
1659
|
+
* yield* Console.log("Task executed")
|
|
1660
|
+
* return "task completed"
|
|
1661
|
+
* }),
|
|
1662
|
+
* eitherSchedule.pipe(
|
|
1663
|
+
* Schedule.tapOutput(([timeResult, countResult]) =>
|
|
1664
|
+
* Console.log(`Time: ${timeResult}, Count: ${countResult}`)
|
|
1665
|
+
* )
|
|
1666
|
+
* )
|
|
1667
|
+
* )
|
|
1668
|
+
*
|
|
1669
|
+
* yield* Console.log(`Total executions: ${results.length}`)
|
|
1670
|
+
* })
|
|
1671
|
+
*
|
|
1672
|
+
* // Either with different delay strategies
|
|
1673
|
+
* const aggressiveRetry = Schedule.exponential("100 millis").pipe(
|
|
1674
|
+
* Schedule.take(3)
|
|
1675
|
+
* )
|
|
1676
|
+
* const fallbackRetry = Schedule.fixed("5 seconds").pipe(Schedule.take(2))
|
|
1677
|
+
*
|
|
1678
|
+
* // Will use the more aggressive retry until it's exhausted, then fallback
|
|
1679
|
+
* const combinedRetry = Schedule.either(aggressiveRetry, fallbackRetry)
|
|
1680
|
+
*
|
|
1681
|
+
* const retryProgram = Effect.gen(function*() {
|
|
1682
|
+
* let attempt = 0
|
|
1683
|
+
*
|
|
1684
|
+
* const result = yield* Effect.retry(
|
|
1685
|
+
* Effect.gen(function*() {
|
|
1686
|
+
* attempt++
|
|
1687
|
+
* yield* Console.log(`Retry attempt ${attempt}`)
|
|
1688
|
+
*
|
|
1689
|
+
* if (attempt < 6) {
|
|
1690
|
+
* return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
|
|
1691
|
+
* }
|
|
1692
|
+
*
|
|
1693
|
+
* return `Success on attempt ${attempt}`
|
|
1694
|
+
* }),
|
|
1695
|
+
* combinedRetry
|
|
1696
|
+
* )
|
|
1697
|
+
*
|
|
1698
|
+
* yield* Console.log(`Final result: ${result}`)
|
|
1699
|
+
* })
|
|
1700
|
+
*
|
|
1701
|
+
* // Either provides union semantics (OR logic)
|
|
1702
|
+
* // Compare with both, which provides intersection semantics (AND logic)
|
|
1703
|
+
* ```
|
|
1704
|
+
*
|
|
1705
|
+
* @see {@link both} for continuing only while both schedules still recur
|
|
1706
|
+
*
|
|
1707
|
+
* @category combining
|
|
1708
|
+
* @since 2.0.0
|
|
1709
|
+
*/
|
|
1710
|
+
export const either: {
|
|
1711
|
+
<Output2, Input2, Error2, Env2>(
|
|
1712
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
1713
|
+
): <Output, Input, Error, Env>(
|
|
1714
|
+
self: Schedule<Output, Input, Error, Env>
|
|
1715
|
+
) => Schedule<[Output, Output2], Input & Input2, Error | Error2, Env | Env2>
|
|
1716
|
+
<Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
1717
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
1718
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
1719
|
+
): Schedule<[Output, Output2], Input & Input2, Error | Error2, Env | Env2>
|
|
1720
|
+
} = dual(2, <Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
1721
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
1722
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
1723
|
+
): Schedule<[Output, Output2], Input & Input2, Error | Error2, Env | Env2> =>
|
|
1724
|
+
eitherWith(self, other, (left, right) => [left, right]))
|
|
1725
|
+
|
|
1726
|
+
/**
|
|
1727
|
+
* Combines two `Schedule`s by recurring if either of the two schedules wants
|
|
1728
|
+
* to recur, using the minimum of the two durations between recurrences and
|
|
1729
|
+
* outputting the result of the left schedule (i.e. `self`).
|
|
1730
|
+
*
|
|
1731
|
+
* **When to use**
|
|
1732
|
+
*
|
|
1733
|
+
* Use when either schedule may keep recurrence going and only the left
|
|
1734
|
+
* schedule's output is needed.
|
|
1735
|
+
*
|
|
1736
|
+
* **Example** (Combining either schedules and keeping the left output)
|
|
1737
|
+
*
|
|
1738
|
+
* ```ts
|
|
1739
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
1740
|
+
*
|
|
1741
|
+
* // Combine two schedules with either semantics, keeping left output
|
|
1742
|
+
* const primarySchedule = Schedule.exponential("100 millis").pipe(
|
|
1743
|
+
* Schedule.map(() => Effect.succeed("primary-result")),
|
|
1744
|
+
* Schedule.take(2)
|
|
1745
|
+
* )
|
|
1746
|
+
* const backupSchedule = Schedule.spaced("500 millis").pipe(
|
|
1747
|
+
* Schedule.map(() => Effect.succeed("backup-result"))
|
|
1748
|
+
* )
|
|
1749
|
+
*
|
|
1750
|
+
* const combined = Schedule.eitherLeft(primarySchedule, backupSchedule)
|
|
1751
|
+
*
|
|
1752
|
+
* const program = Effect.gen(function*() {
|
|
1753
|
+
* yield* Effect.repeat(
|
|
1754
|
+
* Effect.gen(function*() {
|
|
1755
|
+
* yield* Console.log("Task executed")
|
|
1756
|
+
* return "task-done"
|
|
1757
|
+
* }),
|
|
1758
|
+
* combined.pipe(Schedule.take(5))
|
|
1759
|
+
* )
|
|
1760
|
+
* })
|
|
1761
|
+
* ```
|
|
1762
|
+
*
|
|
1763
|
+
* @category combining
|
|
1764
|
+
* @since 4.0.0
|
|
1765
|
+
*/
|
|
1766
|
+
export const eitherLeft: {
|
|
1767
|
+
<Output2, Input2, Error2, Env2>(
|
|
1768
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
1769
|
+
): <Output, Input, Error, Env>(
|
|
1770
|
+
self: Schedule<Output, Input, Error, Env>
|
|
1771
|
+
) => Schedule<Output, Input & Input2, Error | Error2, Env | Env2>
|
|
1772
|
+
<Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
1773
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
1774
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
1775
|
+
): Schedule<Output, Input & Input2, Error | Error2, Env | Env2>
|
|
1776
|
+
} = dual(2, <Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
1777
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
1778
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
1779
|
+
): Schedule<Output, Input & Input2, Error | Error2, Env | Env2> => eitherWith(self, other, (output) => output))
|
|
1780
|
+
|
|
1781
|
+
/**
|
|
1782
|
+
* Combines two `Schedule`s by recurring if either of the two schedules wants
|
|
1783
|
+
* to recur, using the minimum of the two durations between recurrences and
|
|
1784
|
+
* outputting the result of the right schedule (i.e. `other`).
|
|
1785
|
+
*
|
|
1786
|
+
* **When to use**
|
|
1787
|
+
*
|
|
1788
|
+
* Use when either schedule may keep recurrence going and only the right
|
|
1789
|
+
* schedule's output is needed.
|
|
1790
|
+
*
|
|
1791
|
+
* **Example** (Combining either schedules and keeping the right output)
|
|
1792
|
+
*
|
|
1793
|
+
* ```ts
|
|
1794
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
1795
|
+
*
|
|
1796
|
+
* // Combine two schedules with either semantics, keeping right output
|
|
1797
|
+
* const primarySchedule = Schedule.exponential("100 millis").pipe(
|
|
1798
|
+
* Schedule.map(() => Effect.succeed("primary-result")),
|
|
1799
|
+
* Schedule.take(2)
|
|
1800
|
+
* )
|
|
1801
|
+
* const backupSchedule = Schedule.spaced("500 millis").pipe(
|
|
1802
|
+
* Schedule.map(() => Effect.succeed("backup-result"))
|
|
1803
|
+
* )
|
|
1804
|
+
*
|
|
1805
|
+
* const combined = Schedule.eitherRight(primarySchedule, backupSchedule)
|
|
1806
|
+
*
|
|
1807
|
+
* const program = Effect.gen(function*() {
|
|
1808
|
+
* yield* Effect.repeat(
|
|
1809
|
+
* Effect.gen(function*() {
|
|
1810
|
+
* yield* Console.log("Task executed")
|
|
1811
|
+
* return "task-done"
|
|
1812
|
+
* }),
|
|
1813
|
+
* combined.pipe(Schedule.take(5))
|
|
1814
|
+
* )
|
|
1815
|
+
* })
|
|
1816
|
+
* ```
|
|
1817
|
+
*
|
|
1818
|
+
* @category combining
|
|
1819
|
+
* @since 4.0.0
|
|
1820
|
+
*/
|
|
1821
|
+
export const eitherRight: {
|
|
1822
|
+
<Output2, Input2, Error2, Env2>(
|
|
1823
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
1824
|
+
): <Output, Input, Error, Env>(
|
|
1825
|
+
self: Schedule<Output, Input, Error, Env>
|
|
1826
|
+
) => Schedule<Output2, Input & Input2, Error | Error2, Env | Env2>
|
|
1827
|
+
<Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
1828
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
1829
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
1830
|
+
): Schedule<Output2, Input & Input2, Error | Error2, Env | Env2>
|
|
1831
|
+
} = dual(2, <Output, Input, Error, Env, Output2, Input2, Error2, Env2>(
|
|
1832
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
1833
|
+
other: Schedule<Output2, Input2, Error2, Env2>
|
|
1834
|
+
): Schedule<Output2, Input & Input2, Error | Error2, Env | Env2> => eitherWith(self, other, (_, output) => output))
|
|
1835
|
+
|
|
1836
|
+
/**
|
|
1837
|
+
* Combines two `Schedule`s by recurring if either of the two schedules wants
|
|
1838
|
+
* to recur, using the minimum of the two durations between recurrences and
|
|
1839
|
+
* outputting the result of the combination of both schedule outputs using the
|
|
1840
|
+
* specified `combine` function.
|
|
1841
|
+
*
|
|
1842
|
+
* **When to use**
|
|
1843
|
+
*
|
|
1844
|
+
* Use when either schedule may keep recurrence going and their outputs should be
|
|
1845
|
+
* combined into a custom value.
|
|
1846
|
+
*
|
|
1847
|
+
* **Example** (Combining either schedule outputs)
|
|
1848
|
+
*
|
|
1849
|
+
* ```ts
|
|
1850
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
1851
|
+
*
|
|
1852
|
+
* // Combine schedules with either semantics and custom combination
|
|
1853
|
+
* const primarySchedule = Schedule.exponential("100 millis").pipe(
|
|
1854
|
+
* Schedule.map(() => Effect.succeed("primary")),
|
|
1855
|
+
* Schedule.take(2)
|
|
1856
|
+
* )
|
|
1857
|
+
* const fallbackSchedule = Schedule.spaced("500 millis").pipe(
|
|
1858
|
+
* Schedule.map(() => Effect.succeed("fallback"))
|
|
1859
|
+
* )
|
|
1860
|
+
*
|
|
1861
|
+
* const combined = Schedule.eitherWith(
|
|
1862
|
+
* primarySchedule,
|
|
1863
|
+
* fallbackSchedule,
|
|
1864
|
+
* (primary, fallback) => `${primary}+${fallback}`
|
|
1865
|
+
* )
|
|
1866
|
+
*
|
|
1867
|
+
* const program = Effect.gen(function*() {
|
|
1868
|
+
* yield* Effect.repeat(
|
|
1869
|
+
* Effect.gen(function*() {
|
|
1870
|
+
* yield* Console.log("Task executed")
|
|
1871
|
+
* return "task-result"
|
|
1872
|
+
* }),
|
|
1873
|
+
* combined.pipe(Schedule.take(5))
|
|
1874
|
+
* )
|
|
1875
|
+
* })
|
|
1876
|
+
* ```
|
|
1877
|
+
*
|
|
1878
|
+
* @category combining
|
|
1879
|
+
* @since 2.0.0
|
|
1880
|
+
*/
|
|
1881
|
+
export const eitherWith: {
|
|
1882
|
+
<Output2, Input2, Error2, Env2, Output, Output3>(
|
|
1883
|
+
other: Schedule<Output2, Input2, Error2, Env2>,
|
|
1884
|
+
combine: (selfOutput: Output, otherOutput: Output2) => Output3
|
|
1885
|
+
): <Input, Error, Env>(
|
|
1886
|
+
self: Schedule<Output, Input, Error, Env>
|
|
1887
|
+
) => Schedule<Output3, Input & Input2, Error | Error2, Env | Env2>
|
|
1888
|
+
<Output, Input, Error, Env, Output2, Input2, Error2, Env2, Output3>(
|
|
1889
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
1890
|
+
other: Schedule<Output2, Input2, Error2, Env2>,
|
|
1891
|
+
combine: (selfOutput: Output, otherOutput: Output2) => Output3
|
|
1892
|
+
): Schedule<Output3, Input & Input2, Error | Error2, Env | Env2>
|
|
1893
|
+
} = dual(3, <Output, Input, Error, Env, Output2, Input2, Error2, Env2, Output3>(
|
|
1894
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
1895
|
+
other: Schedule<Output2, Input2, Error2, Env2>,
|
|
1896
|
+
combine: (selfOutput: Output, otherOutput: Output2) => Output3
|
|
1897
|
+
): Schedule<Output3, Input & Input2, Error | Error2, Env | Env2> =>
|
|
1898
|
+
fromStep(effect.map(
|
|
1899
|
+
effect.zip(toStep(self), toStep(other)),
|
|
1900
|
+
([stepLeft, stepRight]) => (now, input) =>
|
|
1901
|
+
Pull.matchEffect(stepLeft(now, input as Input), {
|
|
1902
|
+
onSuccess: (leftResult) =>
|
|
1903
|
+
stepRight(now, input as Input2).pipe(
|
|
1904
|
+
effect.map((rightResult) =>
|
|
1905
|
+
[combine(leftResult[0], rightResult[0]), Duration.min(leftResult[1], rightResult[1])] as [
|
|
1906
|
+
Output3,
|
|
1907
|
+
Duration.Duration
|
|
1908
|
+
]
|
|
1909
|
+
),
|
|
1910
|
+
Pull.catchDone((rightDone) =>
|
|
1911
|
+
effect.succeed<[Output3, Duration.Duration]>([
|
|
1912
|
+
combine(leftResult[0], rightDone as Output2),
|
|
1913
|
+
leftResult[1]
|
|
1914
|
+
])
|
|
1915
|
+
)
|
|
1916
|
+
),
|
|
1917
|
+
onFailure: effect.failCause,
|
|
1918
|
+
onDone: (leftDone) =>
|
|
1919
|
+
stepRight(now, input as Input2).pipe(
|
|
1920
|
+
effect.map((rightResult) =>
|
|
1921
|
+
[combine(leftDone, rightResult[0]), rightResult[1]] as [
|
|
1922
|
+
Output3,
|
|
1923
|
+
Duration.Duration
|
|
1924
|
+
]
|
|
1925
|
+
),
|
|
1926
|
+
Pull.catchDone((rightDone) => Cause.done(combine(leftDone, rightDone as Output2)))
|
|
1927
|
+
)
|
|
1928
|
+
})
|
|
1929
|
+
)))
|
|
1930
|
+
|
|
1931
|
+
/**
|
|
1932
|
+
* Schedule that always recurs and returns the total elapsed duration since the
|
|
1933
|
+
* first recurrence.
|
|
1934
|
+
*
|
|
1935
|
+
* **Details**
|
|
1936
|
+
*
|
|
1937
|
+
* This schedule never stops and outputs the cumulative time that has passed since the schedule
|
|
1938
|
+
* started executing. Useful for tracking execution time or implementing time-based logic.
|
|
1939
|
+
*
|
|
1940
|
+
* **Example** (Measuring elapsed schedule time)
|
|
1941
|
+
*
|
|
1942
|
+
* ```ts
|
|
1943
|
+
* import { Console, Duration, Effect, Schedule } from "effect"
|
|
1944
|
+
*
|
|
1945
|
+
* const program = Effect.gen(function*() {
|
|
1946
|
+
* yield* Effect.repeat(
|
|
1947
|
+
* Console.log("Running task..."),
|
|
1948
|
+
* Schedule.spaced("1 second").pipe(
|
|
1949
|
+
* Schedule.both(Schedule.elapsed),
|
|
1950
|
+
* Schedule.tapOutput(([count, duration]) =>
|
|
1951
|
+
* Console.log(`Run ${count}, elapsed: ${Duration.toMillis(duration)}ms`)
|
|
1952
|
+
* ),
|
|
1953
|
+
* Schedule.take(5)
|
|
1954
|
+
* )
|
|
1955
|
+
* )
|
|
1956
|
+
* })
|
|
1957
|
+
* ```
|
|
1958
|
+
*
|
|
1959
|
+
* @category constructors
|
|
1960
|
+
* @since 2.0.0
|
|
1961
|
+
*/
|
|
1962
|
+
export const elapsed: Schedule<Duration.Duration> = fromStepWithMetadata(
|
|
1963
|
+
effect.succeed((meta) => effect.succeed([Duration.millis(meta.elapsed), Duration.zero] as const))
|
|
1964
|
+
)
|
|
1965
|
+
|
|
1966
|
+
/**
|
|
1967
|
+
* Schedule that always recurs, but will wait a certain amount between
|
|
1968
|
+
* repetitions, given by `base * factor.pow(n)`, where `n` is the number of
|
|
1969
|
+
* repetitions so far. Returns the current duration between recurrences.
|
|
1970
|
+
*
|
|
1971
|
+
* **Example** (Retrying with exponential backoff)
|
|
1972
|
+
*
|
|
1973
|
+
* ```ts
|
|
1974
|
+
* import { Console, Data, Effect, Schedule } from "effect"
|
|
1975
|
+
*
|
|
1976
|
+
* class RetryFailure extends Data.TaggedError("RetryFailure")<{ readonly message: string }> {}
|
|
1977
|
+
*
|
|
1978
|
+
* // Basic exponential backoff with default factor of 2
|
|
1979
|
+
* const basicExponential = Schedule.exponential("100 millis")
|
|
1980
|
+
* // Delays: 100ms, 200ms, 400ms, 800ms, 1600ms, ...
|
|
1981
|
+
*
|
|
1982
|
+
* // Custom exponential backoff with factor 1.5
|
|
1983
|
+
* const gentleExponential = Schedule.exponential("200 millis", 1.5)
|
|
1984
|
+
* // Delays: 200ms, 300ms, 450ms, 675ms, 1012ms, ...
|
|
1985
|
+
*
|
|
1986
|
+
* // Retry with exponential backoff (limited to 5 attempts)
|
|
1987
|
+
* const retryPolicy = Schedule.exponential("50 millis").pipe(
|
|
1988
|
+
* Schedule.both(Schedule.recurs(5))
|
|
1989
|
+
* )
|
|
1990
|
+
*
|
|
1991
|
+
* const program = Effect.gen(function*() {
|
|
1992
|
+
* let attempt = 0
|
|
1993
|
+
*
|
|
1994
|
+
* const result = yield* Effect.retry(
|
|
1995
|
+
* Effect.gen(function*() {
|
|
1996
|
+
* attempt++
|
|
1997
|
+
* if (attempt < 4) {
|
|
1998
|
+
* yield* Console.log(`Attempt ${attempt} failed, retrying...`)
|
|
1999
|
+
* return yield* Effect.fail(new RetryFailure({ message: `Failure ${attempt}` }))
|
|
2000
|
+
* }
|
|
2001
|
+
* return `Success on attempt ${attempt}`
|
|
2002
|
+
* }),
|
|
2003
|
+
* retryPolicy
|
|
2004
|
+
* )
|
|
2005
|
+
*
|
|
2006
|
+
* yield* Console.log(`Final result: ${result}`)
|
|
2007
|
+
* })
|
|
2008
|
+
*
|
|
2009
|
+
* // Will retry with delays: 50ms, 100ms, 200ms before success
|
|
2010
|
+
* ```
|
|
2011
|
+
*
|
|
2012
|
+
* @category constructors
|
|
2013
|
+
* @since 2.0.0
|
|
2014
|
+
*/
|
|
2015
|
+
export const exponential = (
|
|
2016
|
+
base: Duration.Input,
|
|
2017
|
+
factor: number = 2
|
|
2018
|
+
): Schedule<Duration.Duration> => {
|
|
2019
|
+
const baseMillis = Duration.toMillis(Duration.fromInputUnsafe(base))
|
|
2020
|
+
return fromStepWithMetadata(effect.succeed((meta) => {
|
|
2021
|
+
const duration = Duration.millis(baseMillis * Math.pow(factor, meta.attempt - 1))
|
|
2022
|
+
return effect.succeed([duration, duration])
|
|
2023
|
+
}))
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
/**
|
|
2027
|
+
* Schedule that always recurs, increasing delays by summing the preceding
|
|
2028
|
+
* two delays (similar to the Fibonacci sequence). Returns the current
|
|
2029
|
+
* duration between recurrences.
|
|
2030
|
+
*
|
|
2031
|
+
* **Example** (Retrying with Fibonacci backoff)
|
|
2032
|
+
*
|
|
2033
|
+
* ```ts
|
|
2034
|
+
* import { Console, Data, Effect, Schedule } from "effect"
|
|
2035
|
+
*
|
|
2036
|
+
* class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
|
|
2037
|
+
*
|
|
2038
|
+
* // Basic Fibonacci schedule starting with 100ms
|
|
2039
|
+
* const fibSchedule = Schedule.fibonacci("100 millis")
|
|
2040
|
+
* // Delays: 100ms, 100ms, 200ms, 300ms, 500ms, 800ms, 1300ms, ...
|
|
2041
|
+
*
|
|
2042
|
+
* // Retry with Fibonacci backoff for gradual increase
|
|
2043
|
+
* const retryWithFib = Effect.gen(function*() {
|
|
2044
|
+
* let attempt = 0
|
|
2045
|
+
*
|
|
2046
|
+
* const result = yield* Effect.retry(
|
|
2047
|
+
* Effect.gen(function*() {
|
|
2048
|
+
* attempt++
|
|
2049
|
+
* yield* Console.log(`Attempt ${attempt}`)
|
|
2050
|
+
*
|
|
2051
|
+
* if (attempt < 5) {
|
|
2052
|
+
* return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
|
|
2053
|
+
* }
|
|
2054
|
+
*
|
|
2055
|
+
* return `Success on attempt ${attempt}`
|
|
2056
|
+
* }),
|
|
2057
|
+
* Schedule.fibonacci("50 millis").pipe(
|
|
2058
|
+
* Schedule.both(Schedule.recurs(6)), // Maximum 6 retries
|
|
2059
|
+
* Schedule.tapOutput((delay) => Console.log(`Next retry in ${delay}`))
|
|
2060
|
+
* )
|
|
2061
|
+
* )
|
|
2062
|
+
*
|
|
2063
|
+
* yield* Console.log(`Final result: ${result}`)
|
|
2064
|
+
* })
|
|
2065
|
+
*
|
|
2066
|
+
* // Heartbeat with Fibonacci intervals (starts fast, gets slower)
|
|
2067
|
+
* const adaptiveHeartbeat = Effect.gen(function*() {
|
|
2068
|
+
* yield* Console.log("Heartbeat")
|
|
2069
|
+
* return "pulse"
|
|
2070
|
+
* }).pipe(
|
|
2071
|
+
* Effect.repeat(
|
|
2072
|
+
* Schedule.fibonacci("200 millis").pipe(
|
|
2073
|
+
* Schedule.take(8) // First 8 heartbeats
|
|
2074
|
+
* )
|
|
2075
|
+
* )
|
|
2076
|
+
* )
|
|
2077
|
+
*
|
|
2078
|
+
* // Fibonacci vs exponential comparison
|
|
2079
|
+
* const compareSchedules = Effect.gen(function*() {
|
|
2080
|
+
* yield* Console.log("=== Fibonacci Delays ===")
|
|
2081
|
+
* // 100ms, 100ms, 200ms, 300ms, 500ms, 800ms
|
|
2082
|
+
*
|
|
2083
|
+
* yield* Console.log("=== Exponential Delays ===")
|
|
2084
|
+
* // 100ms, 200ms, 400ms, 800ms, 1600ms, 3200ms
|
|
2085
|
+
*
|
|
2086
|
+
* // Fibonacci grows more slowly than exponential
|
|
2087
|
+
* })
|
|
2088
|
+
* ```
|
|
2089
|
+
*
|
|
2090
|
+
* @category constructors
|
|
2091
|
+
* @since 2.0.0
|
|
2092
|
+
*/
|
|
2093
|
+
export const fibonacci = (one: Duration.Input): Schedule<Duration.Duration> => {
|
|
2094
|
+
const oneMillis = Duration.toMillis(Duration.fromInputUnsafe(one))
|
|
2095
|
+
return fromStep(effect.sync(() => {
|
|
2096
|
+
let a = 0
|
|
2097
|
+
let b = oneMillis
|
|
2098
|
+
return constant(effect.sync(() => {
|
|
2099
|
+
const next = a + b
|
|
2100
|
+
a = b
|
|
2101
|
+
b = next
|
|
2102
|
+
const duration = Duration.millis(next)
|
|
2103
|
+
return [duration, duration]
|
|
2104
|
+
}))
|
|
2105
|
+
}))
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
/**
|
|
2109
|
+
* Returns a `Schedule` that recurs on the specified fixed `interval` and
|
|
2110
|
+
* outputs the number of repetitions of the schedule so far.
|
|
2111
|
+
*
|
|
2112
|
+
* **When to use**
|
|
2113
|
+
*
|
|
2114
|
+
* Use when recurrences should stay aligned to a regular cadence.
|
|
2115
|
+
*
|
|
2116
|
+
* **Gotchas**
|
|
2117
|
+
*
|
|
2118
|
+
* If the action run between recurrences takes longer than the interval, the
|
|
2119
|
+
* next recurrence happens immediately, but missed intervals are not replayed.
|
|
2120
|
+
*
|
|
2121
|
+
* ```text
|
|
2122
|
+
* |-----interval-----|-----interval-----|-----interval-----|
|
|
2123
|
+
* |---------action--------||action|-----|action|-----------|
|
|
2124
|
+
* ```
|
|
2125
|
+
*
|
|
2126
|
+
* **Example** (Repeating on fixed intervals)
|
|
2127
|
+
*
|
|
2128
|
+
* ```ts
|
|
2129
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
2130
|
+
*
|
|
2131
|
+
* // Fixed interval schedule - recurs on a one-second cadence
|
|
2132
|
+
* const everySecond = Schedule.fixed("1 second")
|
|
2133
|
+
*
|
|
2134
|
+
* // Health check that runs at fixed intervals
|
|
2135
|
+
* const healthCheck = Effect.gen(function*() {
|
|
2136
|
+
* yield* Console.log("Health check")
|
|
2137
|
+
* yield* Effect.sleep("200 millis") // simulate health check work
|
|
2138
|
+
* return "healthy"
|
|
2139
|
+
* }).pipe(
|
|
2140
|
+
* Effect.repeat(Schedule.fixed("2 seconds").pipe(Schedule.take(5)))
|
|
2141
|
+
* )
|
|
2142
|
+
*
|
|
2143
|
+
* // Difference between fixed and spaced:
|
|
2144
|
+
* // - fixed: maintains constant rate regardless of action duration
|
|
2145
|
+
* // - spaced: waits for the duration AFTER each action completes
|
|
2146
|
+
*
|
|
2147
|
+
* const longRunningTask = Effect.gen(function*() {
|
|
2148
|
+
* yield* Console.log("Task started")
|
|
2149
|
+
* yield* Effect.sleep("1.5 seconds") // Longer than interval
|
|
2150
|
+
* yield* Console.log("Task completed")
|
|
2151
|
+
* return "done"
|
|
2152
|
+
* })
|
|
2153
|
+
*
|
|
2154
|
+
* // Fixed schedule: if task takes 1.5s but interval is 1s,
|
|
2155
|
+
* // next execution happens immediately (no pile-up)
|
|
2156
|
+
* const fixedSchedule = longRunningTask.pipe(
|
|
2157
|
+
* Effect.repeat(Schedule.fixed("1 second").pipe(Schedule.take(3)))
|
|
2158
|
+
* )
|
|
2159
|
+
*
|
|
2160
|
+
* // Comparing with spaced (waits 1s AFTER each task)
|
|
2161
|
+
* const spacedSchedule = longRunningTask.pipe(
|
|
2162
|
+
* Effect.repeat(Schedule.spaced("1 second").pipe(Schedule.take(3)))
|
|
2163
|
+
* )
|
|
2164
|
+
*
|
|
2165
|
+
* const program = Effect.gen(function*() {
|
|
2166
|
+
* yield* Console.log("=== Fixed Schedule Demo ===")
|
|
2167
|
+
* yield* fixedSchedule
|
|
2168
|
+
*
|
|
2169
|
+
* yield* Console.log("=== Spaced Schedule Demo ===")
|
|
2170
|
+
* yield* spacedSchedule
|
|
2171
|
+
* })
|
|
2172
|
+
* ```
|
|
2173
|
+
*
|
|
2174
|
+
* @see {@link spaced} for delaying after each action completes
|
|
2175
|
+
*
|
|
2176
|
+
* @category constructors
|
|
2177
|
+
* @since 2.0.0
|
|
2178
|
+
*/
|
|
2179
|
+
export const fixed = (interval: Duration.Input): Schedule<number> => {
|
|
2180
|
+
const window = Duration.toMillis(Duration.fromInputUnsafe(interval))
|
|
2181
|
+
return fromStepWithMetadata(effect.sync(() => {
|
|
2182
|
+
let start = 0
|
|
2183
|
+
let lastRun = 0
|
|
2184
|
+
return (meta) =>
|
|
2185
|
+
effect.sync(() => {
|
|
2186
|
+
if (window === 0) {
|
|
2187
|
+
return [meta.attempt - 1, Duration.zero] as const
|
|
2188
|
+
}
|
|
2189
|
+
if (meta.attempt === 1) {
|
|
2190
|
+
start = meta.now
|
|
2191
|
+
lastRun = meta.now + window
|
|
2192
|
+
return [0, Duration.millis(window)] as const
|
|
2193
|
+
}
|
|
2194
|
+
const runningBehind = meta.now > (lastRun + window)
|
|
2195
|
+
const boundary = window - ((meta.now - start) % window)
|
|
2196
|
+
const delay = runningBehind ? 0 : boundary === 0 ? window : boundary
|
|
2197
|
+
lastRun = runningBehind ? meta.now : meta.now + delay
|
|
2198
|
+
return [meta.attempt - 1, Duration.millis(delay)] as const
|
|
2199
|
+
})
|
|
2200
|
+
}))
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
/**
|
|
2204
|
+
* Returns a new `Schedule` that maps the output of this schedule using the
|
|
2205
|
+
* specified function.
|
|
2206
|
+
*
|
|
2207
|
+
* **Example** (Mapping schedule outputs)
|
|
2208
|
+
*
|
|
2209
|
+
* ```ts
|
|
2210
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
2211
|
+
*
|
|
2212
|
+
* // Transform schedule output from number to string
|
|
2213
|
+
* const countSchedule = Schedule.recurs(5).pipe(
|
|
2214
|
+
* Schedule.map((count) => Effect.succeed(`Execution #${count + 1}`))
|
|
2215
|
+
* )
|
|
2216
|
+
*
|
|
2217
|
+
* // Map schedule delays to human-readable format
|
|
2218
|
+
* const readableDelays = Schedule.exponential("100 millis").pipe(
|
|
2219
|
+
* Schedule.map((duration) => Effect.succeed(`Next retry in ${duration}`))
|
|
2220
|
+
* )
|
|
2221
|
+
*
|
|
2222
|
+
* // Transform numeric output to structured data
|
|
2223
|
+
* const structuredSchedule = Schedule.spaced("1 second").pipe(
|
|
2224
|
+
* Schedule.map((recurrence) => Effect.succeed({
|
|
2225
|
+
* iteration: recurrence + 1,
|
|
2226
|
+
* phase: recurrence < 5 ? "warmup" as const : "steady" as const
|
|
2227
|
+
* }))
|
|
2228
|
+
* )
|
|
2229
|
+
*
|
|
2230
|
+
* const program = Effect.gen(function*() {
|
|
2231
|
+
* const results = yield* Effect.repeat(
|
|
2232
|
+
* Effect.succeed("task completed"),
|
|
2233
|
+
* structuredSchedule.pipe(
|
|
2234
|
+
* Schedule.take(8),
|
|
2235
|
+
* Schedule.tapOutput((info) =>
|
|
2236
|
+
* Console.log(
|
|
2237
|
+
* `${info.phase} phase - iteration ${info.iteration}`
|
|
2238
|
+
* )
|
|
2239
|
+
* )
|
|
2240
|
+
* )
|
|
2241
|
+
* )
|
|
2242
|
+
*
|
|
2243
|
+
* yield* Console.log(`Completed iterations`)
|
|
2244
|
+
* })
|
|
2245
|
+
*
|
|
2246
|
+
* // Map with effectful transformation
|
|
2247
|
+
* const effectfulMap = Schedule.fixed("2 seconds").pipe(
|
|
2248
|
+
* Schedule.map((count) =>
|
|
2249
|
+
* Effect.gen(function*() {
|
|
2250
|
+
* yield* Console.log(`Processing count: ${count}`)
|
|
2251
|
+
* return count * 10
|
|
2252
|
+
* })
|
|
2253
|
+
* )
|
|
2254
|
+
* )
|
|
2255
|
+
*
|
|
2256
|
+
* // Combine mapping with other schedule operations
|
|
2257
|
+
* const complexSchedule = Schedule.fibonacci("100 millis").pipe(
|
|
2258
|
+
* Schedule.map((delay) => Effect.succeed(`Delay: ${delay}`))
|
|
2259
|
+
* )
|
|
2260
|
+
* ```
|
|
2261
|
+
*
|
|
2262
|
+
* @category mapping
|
|
2263
|
+
* @since 2.0.0
|
|
2264
|
+
*/
|
|
2265
|
+
export const map: {
|
|
2266
|
+
<Output, Output2, Error2 = never, Env2 = never>(
|
|
2267
|
+
f: (output: Output) => Output2 | Effect<Output2, Error2, Env2>
|
|
2268
|
+
): <Input, Error, Env>(
|
|
2269
|
+
self: Schedule<Output, Input, Error, Env>
|
|
2270
|
+
) => Schedule<Output2, Input, Error | Error2, Env | Env2>
|
|
2271
|
+
<Output, Input, Error, Env, Output2, Error2 = never, Env2 = never>(
|
|
2272
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
2273
|
+
f: (output: Output) => Output2 | Effect<Output2, Error2, Env2>
|
|
2274
|
+
): Schedule<Output2, Input, Error | Error2, Env | Env2>
|
|
2275
|
+
} = dual(2, <Output, Input, Error, Env, Output2, Error2 = never, Env2 = never>(
|
|
2276
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
2277
|
+
f: (output: Output) => Output2 | Effect<Output2, Error2, Env2>
|
|
2278
|
+
): Schedule<Output2, Input, Error | Error2, Env | Env2> => {
|
|
2279
|
+
const handle = Pull.matchEffect({
|
|
2280
|
+
onSuccess: ([output, duration]: [Output, Duration.Duration]) => {
|
|
2281
|
+
const result = f(output)
|
|
2282
|
+
if (!isEffect(result)) return effect.succeed([result, duration] as [Output2, Duration.Duration])
|
|
2283
|
+
return effect.map(result, (output) => [output, duration] as [Output2, Duration.Duration])
|
|
2284
|
+
},
|
|
2285
|
+
onFailure: effect.failCause<Error>,
|
|
2286
|
+
onDone: (output: Output) => {
|
|
2287
|
+
const result = f(output)
|
|
2288
|
+
if (!isEffect(result)) return Cause.done(result as Output2)
|
|
2289
|
+
return effect.flatMap(result, Cause.done)
|
|
2290
|
+
}
|
|
2291
|
+
})
|
|
2292
|
+
return fromStep(effect.map(toStep(self), (step) => (now, input) => handle(step(now, input))))
|
|
2293
|
+
})
|
|
2294
|
+
|
|
2295
|
+
/**
|
|
2296
|
+
* Returns a new `Schedule` that modifies the delay of the next recurrence
|
|
2297
|
+
* of the schedule using the specified effectful function.
|
|
2298
|
+
*
|
|
2299
|
+
* **Example** (Modifying delays from schedule output)
|
|
2300
|
+
*
|
|
2301
|
+
* ```ts
|
|
2302
|
+
* import { Console, Duration, Effect, Schedule } from "effect"
|
|
2303
|
+
*
|
|
2304
|
+
* // Modify delays based on output - increase delay on high iteration counts
|
|
2305
|
+
* const adaptiveDelay = Schedule.recurs(10).pipe(
|
|
2306
|
+
* Schedule.modifyDelay((output, delay) => {
|
|
2307
|
+
* // Double the delay if we're seeing high iteration counts
|
|
2308
|
+
* return Effect.succeed(output > 5 ? Duration.times(delay, 2) : delay)
|
|
2309
|
+
* })
|
|
2310
|
+
* )
|
|
2311
|
+
*
|
|
2312
|
+
* const program = Effect.gen(function*() {
|
|
2313
|
+
* let counter = 0
|
|
2314
|
+
* yield* Effect.repeat(
|
|
2315
|
+
* Effect.gen(function*() {
|
|
2316
|
+
* counter++
|
|
2317
|
+
* yield* Console.log(`Attempt ${counter}`)
|
|
2318
|
+
* return counter
|
|
2319
|
+
* }),
|
|
2320
|
+
* adaptiveDelay.pipe(Schedule.take(8))
|
|
2321
|
+
* )
|
|
2322
|
+
* })
|
|
2323
|
+
* ```
|
|
2324
|
+
*
|
|
2325
|
+
* @category delays & timeouts
|
|
2326
|
+
* @since 2.0.0
|
|
2327
|
+
*/
|
|
2328
|
+
export const modifyDelay: {
|
|
2329
|
+
<Output, Error2 = never, Env2 = never>(
|
|
2330
|
+
f: (
|
|
2331
|
+
output: Output,
|
|
2332
|
+
delay: Duration.Duration
|
|
2333
|
+
) => Effect<Duration.Input, Error2, Env2>
|
|
2334
|
+
): <Input, Error, Env>(
|
|
2335
|
+
self: Schedule<Output, Input, Error, Env>
|
|
2336
|
+
) => Schedule<Output, Input, Error | Error2, Env | Env2>
|
|
2337
|
+
<Output, Input, Error, Env, Error2 = never, Env2 = never>(
|
|
2338
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
2339
|
+
f: (
|
|
2340
|
+
output: Output,
|
|
2341
|
+
delay: Duration.Input
|
|
2342
|
+
) => Effect<Duration.Input, Error2, Env2>
|
|
2343
|
+
): Schedule<Output, Input, Error | Error2, Env | Env2>
|
|
2344
|
+
} = dual(2, <Output, Input, Error, Env, Error2 = never, Env2 = never>(
|
|
2345
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
2346
|
+
f: (
|
|
2347
|
+
output: Output,
|
|
2348
|
+
delay: Duration.Input
|
|
2349
|
+
) => Effect<Duration.Input, Error2, Env2>
|
|
2350
|
+
): Schedule<Output, Input, Error | Error2, Env | Env2> =>
|
|
2351
|
+
fromStep(effect.map(toStep(self), (step) => (now, input) =>
|
|
2352
|
+
effect.flatMap(
|
|
2353
|
+
step(now, input),
|
|
2354
|
+
([output, delay]) => effect.map(f(output, delay), (delay) => [output, Duration.fromInputUnsafe(delay)])
|
|
2355
|
+
))))
|
|
2356
|
+
|
|
2357
|
+
/**
|
|
2358
|
+
* Returns a new `Schedule` that randomly adjusts each recurrence delay.
|
|
2359
|
+
*
|
|
2360
|
+
* **When to use**
|
|
2361
|
+
*
|
|
2362
|
+
* Use to add random variation to an existing schedule's recurrence delays while
|
|
2363
|
+
* preserving its output and completion behavior.
|
|
2364
|
+
*
|
|
2365
|
+
* **Details**
|
|
2366
|
+
*
|
|
2367
|
+
* Each recurrence delay is scaled by a random factor between `0.8` and `1.2`.
|
|
2368
|
+
*
|
|
2369
|
+
* @see {@link modifyDelay} for replacing recurrence delays with a custom effectful transformation
|
|
2370
|
+
*
|
|
2371
|
+
* @category delays & timeouts
|
|
2372
|
+
* @since 2.0.0
|
|
2373
|
+
*/
|
|
2374
|
+
export const jittered = <Output, Input, Error, Env>(
|
|
2375
|
+
self: Schedule<Output, Input, Error, Env>
|
|
2376
|
+
): Schedule<Output, Input, Error, Env> =>
|
|
2377
|
+
modifyDelay(self, (_, delay) =>
|
|
2378
|
+
effect.map(randomNext, (random) => {
|
|
2379
|
+
const millis = Duration.toMillis(Duration.fromInputUnsafe(delay))
|
|
2380
|
+
return Duration.millis(millis * 0.8 * (1 - random) + millis * 1.2 * random)
|
|
2381
|
+
}))
|
|
2382
|
+
|
|
2383
|
+
/**
|
|
2384
|
+
* Returns a new `Schedule` that outputs the inputs of the specified schedule.
|
|
2385
|
+
*
|
|
2386
|
+
* **Example** (Passing inputs through as outputs)
|
|
2387
|
+
*
|
|
2388
|
+
* ```ts
|
|
2389
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
2390
|
+
*
|
|
2391
|
+
* // Create a schedule that outputs the inputs instead of original outputs
|
|
2392
|
+
* const inputSchedule = Schedule.passthrough(
|
|
2393
|
+
* Schedule.exponential("100 millis").pipe(Schedule.take(3))
|
|
2394
|
+
* )
|
|
2395
|
+
*
|
|
2396
|
+
* const program = Effect.gen(function*() {
|
|
2397
|
+
* let counter = 0
|
|
2398
|
+
* yield* Effect.repeat(
|
|
2399
|
+
* Effect.gen(function*() {
|
|
2400
|
+
* counter++
|
|
2401
|
+
* yield* Console.log(`Task ${counter} executed`)
|
|
2402
|
+
* return `result-${counter}`
|
|
2403
|
+
* }),
|
|
2404
|
+
* inputSchedule
|
|
2405
|
+
* )
|
|
2406
|
+
* })
|
|
2407
|
+
* ```
|
|
2408
|
+
*
|
|
2409
|
+
* @category mapping
|
|
2410
|
+
* @since 2.0.0
|
|
2411
|
+
*/
|
|
2412
|
+
export const passthrough = <Output, Input, Error, Env>(
|
|
2413
|
+
self: Schedule<Output, Input, Error, Env>
|
|
2414
|
+
): Schedule<Input, Input, Error, Env> =>
|
|
2415
|
+
fromStep(effect.map(toStep(self), (step) => (now, input) =>
|
|
2416
|
+
Pull.matchEffect(step(now, input), {
|
|
2417
|
+
onSuccess: (result) => effect.succeed([input, result[1]]),
|
|
2418
|
+
onFailure: effect.failCause,
|
|
2419
|
+
onDone: () => Cause.done(input)
|
|
2420
|
+
})))
|
|
2421
|
+
|
|
2422
|
+
/**
|
|
2423
|
+
* Returns a `Schedule` which can only be stepped the specified number of
|
|
2424
|
+
* `times` before it terminates.
|
|
2425
|
+
*
|
|
2426
|
+
* **When to use**
|
|
2427
|
+
*
|
|
2428
|
+
* Use when you need a counter schedule with no additional delay.
|
|
2429
|
+
*
|
|
2430
|
+
* **Gotchas**
|
|
2431
|
+
*
|
|
2432
|
+
* `recurs(n)` counts schedule recurrences, not the first evaluation of the
|
|
2433
|
+
* effect being repeated or retried. For retrying, this means one initial
|
|
2434
|
+
* attempt plus at most `n` retries.
|
|
2435
|
+
*
|
|
2436
|
+
* **Example** (Limiting recurrences)
|
|
2437
|
+
*
|
|
2438
|
+
* ```ts
|
|
2439
|
+
* import { Console, Data, Effect, Schedule } from "effect"
|
|
2440
|
+
*
|
|
2441
|
+
* class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
|
|
2442
|
+
*
|
|
2443
|
+
* // Basic recurs - retry at most 3 times
|
|
2444
|
+
* const maxThreeAttempts = Schedule.recurs(3)
|
|
2445
|
+
*
|
|
2446
|
+
* // Retry a failing operation at most 5 times
|
|
2447
|
+
* const program = Effect.gen(function*() {
|
|
2448
|
+
* let attempt = 0
|
|
2449
|
+
*
|
|
2450
|
+
* const result = yield* Effect.retry(
|
|
2451
|
+
* Effect.gen(function*() {
|
|
2452
|
+
* attempt++
|
|
2453
|
+
* yield* Console.log(`Attempt ${attempt}`)
|
|
2454
|
+
*
|
|
2455
|
+
* if (attempt < 4) {
|
|
2456
|
+
* return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
|
|
2457
|
+
* }
|
|
2458
|
+
*
|
|
2459
|
+
* return `Success on attempt ${attempt}`
|
|
2460
|
+
* }),
|
|
2461
|
+
* Schedule.recurs(5) // Will retry up to 5 times
|
|
2462
|
+
* )
|
|
2463
|
+
*
|
|
2464
|
+
* yield* Console.log(`Final result: ${result}`)
|
|
2465
|
+
* })
|
|
2466
|
+
*
|
|
2467
|
+
* // Combining recurs with other schedules for sophisticated retry logic
|
|
2468
|
+
* const complexRetry = Schedule.exponential("100 millis").pipe(
|
|
2469
|
+
* Schedule.both(Schedule.recurs(3)) // At most 3 retries
|
|
2470
|
+
* )
|
|
2471
|
+
*
|
|
2472
|
+
* // Allow ten recurrences after the initial run
|
|
2473
|
+
* const tenRecurrences = Effect.gen(function*() {
|
|
2474
|
+
* yield* Console.log("Executing task...")
|
|
2475
|
+
* return "completed"
|
|
2476
|
+
* }).pipe(
|
|
2477
|
+
* Effect.repeat(Schedule.recurs(10))
|
|
2478
|
+
* )
|
|
2479
|
+
*
|
|
2480
|
+
* // The schedule outputs the current recurrence count (0-based)
|
|
2481
|
+
* const countingSchedule = Schedule.recurs(3).pipe(
|
|
2482
|
+
* Schedule.tapOutput((count) => Console.log(`Execution #${count + 1}`))
|
|
2483
|
+
* )
|
|
2484
|
+
* ```
|
|
2485
|
+
*
|
|
2486
|
+
* @see {@link take} for limiting an existing schedule
|
|
2487
|
+
*
|
|
2488
|
+
* @category constructors
|
|
2489
|
+
* @since 2.0.0
|
|
2490
|
+
*/
|
|
2491
|
+
export const recurs = (times: number): Schedule<number> =>
|
|
2492
|
+
while_(forever, ({ attempt }) => effect.succeed(attempt <= times))
|
|
2493
|
+
|
|
2494
|
+
/**
|
|
2495
|
+
* Returns a new `Schedule` that combines the outputs of the provided schedule
|
|
2496
|
+
* using the specified effectful `combine` function and starting from the
|
|
2497
|
+
* specified `initial` state.
|
|
2498
|
+
*
|
|
2499
|
+
* **Example** (Reducing schedule outputs)
|
|
2500
|
+
*
|
|
2501
|
+
* ```ts
|
|
2502
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
2503
|
+
*
|
|
2504
|
+
* // Sum up execution counts from a counter schedule
|
|
2505
|
+
* const sumSchedule = Schedule.reduce(
|
|
2506
|
+
* Schedule.recurs(5),
|
|
2507
|
+
* () => 0, // Initial sum
|
|
2508
|
+
* (sum, count) => Effect.succeed(sum + count) // Add each count to the sum
|
|
2509
|
+
* )
|
|
2510
|
+
*
|
|
2511
|
+
* const sumProgram = Effect.gen(function*() {
|
|
2512
|
+
* const finalSum = yield* Effect.repeat(
|
|
2513
|
+
* Effect.gen(function*() {
|
|
2514
|
+
* yield* Console.log("Task executed")
|
|
2515
|
+
* return "task"
|
|
2516
|
+
* }),
|
|
2517
|
+
* sumSchedule.pipe(
|
|
2518
|
+
* Schedule.tapOutput((sum) => Console.log(`Running sum: ${sum}`))
|
|
2519
|
+
* )
|
|
2520
|
+
* )
|
|
2521
|
+
*
|
|
2522
|
+
* yield* Console.log(`Final sum: ${finalSum}`)
|
|
2523
|
+
* })
|
|
2524
|
+
*
|
|
2525
|
+
* // Build a history of execution counts
|
|
2526
|
+
* const historySchedule = Schedule.reduce(
|
|
2527
|
+
* Schedule.spaced("1 second").pipe(Schedule.take(4)),
|
|
2528
|
+
* () => [] as Array<number>, // Initial empty array
|
|
2529
|
+
* (history, executionNumber) => Effect.succeed([...history, executionNumber])
|
|
2530
|
+
* )
|
|
2531
|
+
*
|
|
2532
|
+
* const historyProgram = Effect.gen(function*() {
|
|
2533
|
+
* const timeline = yield* Effect.repeat(
|
|
2534
|
+
* Effect.gen(function*() {
|
|
2535
|
+
* yield* Console.log("Recording execution...")
|
|
2536
|
+
* return "recorded"
|
|
2537
|
+
* }),
|
|
2538
|
+
* historySchedule
|
|
2539
|
+
* )
|
|
2540
|
+
*
|
|
2541
|
+
* yield* Console.log(
|
|
2542
|
+
* `Execution timeline: ${timeline.join(", ")}`
|
|
2543
|
+
* )
|
|
2544
|
+
* })
|
|
2545
|
+
*
|
|
2546
|
+
* // Accumulate metrics with effectful combination
|
|
2547
|
+
* const metricsAccumulator = Schedule.reduce(
|
|
2548
|
+
* Schedule.recurs(6),
|
|
2549
|
+
* () => ({ total: 0, count: 0, max: 0 }),
|
|
2550
|
+
* (metrics, executionCount) => Effect.succeed({
|
|
2551
|
+
* total: metrics.total + executionCount + 1,
|
|
2552
|
+
* count: metrics.count + 1,
|
|
2553
|
+
* max: Math.max(metrics.max, executionCount + 1)
|
|
2554
|
+
* })
|
|
2555
|
+
* )
|
|
2556
|
+
*
|
|
2557
|
+
* const metricsProgram = Effect.gen(function*() {
|
|
2558
|
+
* const finalMetrics = yield* Effect.repeat(
|
|
2559
|
+
* Effect.gen(function*() {
|
|
2560
|
+
* yield* Console.log("Processing...")
|
|
2561
|
+
* return "processed"
|
|
2562
|
+
* }),
|
|
2563
|
+
* metricsAccumulator
|
|
2564
|
+
* )
|
|
2565
|
+
*
|
|
2566
|
+
* const average = finalMetrics.total / finalMetrics.count
|
|
2567
|
+
* yield* Console.log(`Final metrics: ${finalMetrics.count} executions`)
|
|
2568
|
+
* yield* Console.log(
|
|
2569
|
+
* `Average delay: ${average.toFixed(1)}ms, Max delay: ${finalMetrics.max}ms`
|
|
2570
|
+
* )
|
|
2571
|
+
* })
|
|
2572
|
+
*
|
|
2573
|
+
* // Build configuration state over time
|
|
2574
|
+
* const configBuilder = Schedule.reduce(
|
|
2575
|
+
* Schedule.fixed("500 millis").pipe(Schedule.take(3)),
|
|
2576
|
+
* () => ({ retries: 1, timeout: 1000, backoff: 100 }),
|
|
2577
|
+
* (config, executionNumber) => Effect.succeed({
|
|
2578
|
+
* retries: config.retries + 1,
|
|
2579
|
+
* timeout: config.timeout * 1.5,
|
|
2580
|
+
* backoff: Math.min(config.backoff * 2, 5000)
|
|
2581
|
+
* })
|
|
2582
|
+
* )
|
|
2583
|
+
*
|
|
2584
|
+
* const configProgram = Effect.gen(function*() {
|
|
2585
|
+
* const finalConfig = yield* Effect.repeat(
|
|
2586
|
+
* Effect.gen(function*() {
|
|
2587
|
+
* yield* Console.log("Updating configuration...")
|
|
2588
|
+
* return "updated"
|
|
2589
|
+
* }),
|
|
2590
|
+
* configBuilder.pipe(
|
|
2591
|
+
* Schedule.tapOutput((config) =>
|
|
2592
|
+
* Console.log(
|
|
2593
|
+
* `Config: retries=${config.retries}, timeout=${config.timeout}ms`
|
|
2594
|
+
* )
|
|
2595
|
+
* )
|
|
2596
|
+
* )
|
|
2597
|
+
* )
|
|
2598
|
+
*
|
|
2599
|
+
* yield* Console.log(`Final config: ${JSON.stringify(finalConfig)}`)
|
|
2600
|
+
* })
|
|
2601
|
+
* ```
|
|
2602
|
+
*
|
|
2603
|
+
* @category folding
|
|
2604
|
+
* @since 2.0.0
|
|
2605
|
+
*/
|
|
2606
|
+
export const reduce: {
|
|
2607
|
+
<State, Output, Error2 = never, Env2 = never>(
|
|
2608
|
+
initial: LazyArg<State>,
|
|
2609
|
+
combine: (state: State, output: Output) => State | Effect<State, Error2, Env2>
|
|
2610
|
+
): <Input, Error, Env>(
|
|
2611
|
+
self: Schedule<Output, Input, Error, Env>
|
|
2612
|
+
) => Schedule<State, Input, Error | Error2, Env | Env2>
|
|
2613
|
+
<Output, Input, Error, Env, State, Error2 = never, Env2 = never>(
|
|
2614
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
2615
|
+
initial: LazyArg<State>,
|
|
2616
|
+
combine: (state: State, output: Output) => State | Effect<State, Error2, Env2>
|
|
2617
|
+
): Schedule<State, Input, Error | Error2, Env | Env2>
|
|
2618
|
+
} = dual(3, <Output, Input, Error, Env, State, Error2 = never, Env2 = never>(
|
|
2619
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
2620
|
+
initial: LazyArg<State>,
|
|
2621
|
+
combine: (state: State, output: Output) => State | Effect<State, Error2, Env2>
|
|
2622
|
+
): Schedule<State, Input, Error | Error2, Env | Env2> =>
|
|
2623
|
+
fromStep(effect.map(toStep(self), (step) => {
|
|
2624
|
+
let state = initial()
|
|
2625
|
+
return (now, input) =>
|
|
2626
|
+
Pull.matchEffect(step(now, input), {
|
|
2627
|
+
onSuccess([output, delay]) {
|
|
2628
|
+
const next = combine(state, output)
|
|
2629
|
+
if (!isEffect(next)) {
|
|
2630
|
+
state = next
|
|
2631
|
+
return effect.succeed([next, delay] as [State, Duration.Duration])
|
|
2632
|
+
}
|
|
2633
|
+
return effect.map(next, (nextState) => {
|
|
2634
|
+
state = nextState
|
|
2635
|
+
return [nextState, delay]
|
|
2636
|
+
})
|
|
2637
|
+
},
|
|
2638
|
+
onFailure: effect.failCause,
|
|
2639
|
+
onDone(output) {
|
|
2640
|
+
const next = combine(state, output)
|
|
2641
|
+
return isEffect(next) ? effect.flatMap(next, Cause.done) : Cause.done(next)
|
|
2642
|
+
}
|
|
2643
|
+
})
|
|
2644
|
+
})))
|
|
2645
|
+
|
|
2646
|
+
/**
|
|
2647
|
+
* Returns a schedule that recurs continuously, each repetition spaced the
|
|
2648
|
+
* specified duration from the last run.
|
|
2649
|
+
*
|
|
2650
|
+
* **When to use**
|
|
2651
|
+
*
|
|
2652
|
+
* Use when each delay should start after the previous action completes.
|
|
2653
|
+
*
|
|
2654
|
+
* **Example** (Repeating with fixed spacing)
|
|
2655
|
+
*
|
|
2656
|
+
* ```ts
|
|
2657
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
2658
|
+
*
|
|
2659
|
+
* // Basic spaced schedule - runs every 2 seconds
|
|
2660
|
+
* const everyTwoSeconds = Schedule.spaced("2 seconds")
|
|
2661
|
+
*
|
|
2662
|
+
* // Heartbeat that runs indefinitely with fixed spacing
|
|
2663
|
+
* const heartbeat = Effect.gen(function*() {
|
|
2664
|
+
* yield* Console.log("Heartbeat")
|
|
2665
|
+
* }).pipe(
|
|
2666
|
+
* Effect.repeat(everyTwoSeconds)
|
|
2667
|
+
* )
|
|
2668
|
+
*
|
|
2669
|
+
* // Limited repeat - run only 5 times with 1-second spacing
|
|
2670
|
+
* const limitedTask = Effect.gen(function*() {
|
|
2671
|
+
* yield* Console.log("Executing scheduled task...")
|
|
2672
|
+
* yield* Effect.sleep("500 millis") // simulate work
|
|
2673
|
+
* return "Task completed"
|
|
2674
|
+
* }).pipe(
|
|
2675
|
+
* Effect.repeat(
|
|
2676
|
+
* Schedule.spaced("1 second").pipe(Schedule.take(5))
|
|
2677
|
+
* )
|
|
2678
|
+
* )
|
|
2679
|
+
*
|
|
2680
|
+
* // Simple spaced schedule with limited repetitions
|
|
2681
|
+
* const limitedSpaced = Schedule.spaced("100 millis").pipe(
|
|
2682
|
+
* Schedule.both(Schedule.recurs(5)) // at most 5 times
|
|
2683
|
+
* )
|
|
2684
|
+
*
|
|
2685
|
+
* const program = Effect.gen(function*() {
|
|
2686
|
+
* yield* Console.log("Starting spaced execution...")
|
|
2687
|
+
*
|
|
2688
|
+
* yield* Effect.repeat(
|
|
2689
|
+
* Effect.succeed("work item"),
|
|
2690
|
+
* limitedSpaced
|
|
2691
|
+
* )
|
|
2692
|
+
*
|
|
2693
|
+
* yield* Console.log("Completed executions")
|
|
2694
|
+
* })
|
|
2695
|
+
* ```
|
|
2696
|
+
*
|
|
2697
|
+
* @see {@link fixed} for recurrence aligned to a regular cadence
|
|
2698
|
+
*
|
|
2699
|
+
* @category constructors
|
|
2700
|
+
* @since 2.0.0
|
|
2701
|
+
*/
|
|
2702
|
+
export const spaced = (duration: Duration.Input): Schedule<number> => {
|
|
2703
|
+
const decoded = Duration.fromInputUnsafe(duration)
|
|
2704
|
+
return fromStepWithMetadata(effect.succeed((meta) => effect.succeed([meta.attempt - 1, decoded])))
|
|
2705
|
+
}
|
|
2706
|
+
|
|
2707
|
+
/**
|
|
2708
|
+
* Returns a new `Schedule` that allows execution of an effectful function for
|
|
2709
|
+
* every decision of the schedule, but does not alter the inputs and outputs of
|
|
2710
|
+
* the schedule.
|
|
2711
|
+
*
|
|
2712
|
+
* **Details**
|
|
2713
|
+
*
|
|
2714
|
+
* The callback receives the full schedule metadata, including the input, output,
|
|
2715
|
+
* computed delay duration, current attempt, and elapsed timing information.
|
|
2716
|
+
*
|
|
2717
|
+
* **Example** (Tapping schedule metadata)
|
|
2718
|
+
*
|
|
2719
|
+
* ```ts
|
|
2720
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
2721
|
+
*
|
|
2722
|
+
* const monitoredSchedule = Schedule.exponential("100 millis").pipe(
|
|
2723
|
+
* Schedule.take(5),
|
|
2724
|
+
* Schedule.tap((metadata) =>
|
|
2725
|
+
* Console.log(
|
|
2726
|
+
* `Attempt ${metadata.attempt} produced ${metadata.output} ` +
|
|
2727
|
+
* `after ${metadata.elapsed}ms; next delay is ${metadata.duration}`
|
|
2728
|
+
* )
|
|
2729
|
+
* )
|
|
2730
|
+
* )
|
|
2731
|
+
*
|
|
2732
|
+
* const program = Effect.retry(
|
|
2733
|
+
* Effect.fail("transient error"),
|
|
2734
|
+
* monitoredSchedule
|
|
2735
|
+
* )
|
|
2736
|
+
* ```
|
|
2737
|
+
*
|
|
2738
|
+
* @category sequencing
|
|
2739
|
+
* @since 4.0.0
|
|
2740
|
+
*/
|
|
2741
|
+
export const tap: {
|
|
2742
|
+
<Output, Input, X, Error2, Env2>(
|
|
2743
|
+
f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>
|
|
2744
|
+
): <Error, Env>(
|
|
2745
|
+
self: Schedule<Output, Input, Error, Env>
|
|
2746
|
+
) => Schedule<Output, Input, Error | Error2, Env | Env2>
|
|
2747
|
+
<Output, Input, Error, Env, X, Error2, Env2>(
|
|
2748
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
2749
|
+
f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>
|
|
2750
|
+
): Schedule<Output, Input, Error | Error2, Env | Env2>
|
|
2751
|
+
} = dual(2, <Output, Input, Error, Env, X, Error2, Env2>(
|
|
2752
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
2753
|
+
f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>
|
|
2754
|
+
): Schedule<Output, Input, Error | Error2, Env | Env2> =>
|
|
2755
|
+
fromStep(effect.map(toStep(self), (step) => {
|
|
2756
|
+
const meta = metadataFn()
|
|
2757
|
+
return (now, input) =>
|
|
2758
|
+
effect.tap(step(now, input), ([output, duration]) => f({ ...meta(now, input), output, duration }))
|
|
2759
|
+
})))
|
|
2760
|
+
|
|
2761
|
+
/**
|
|
2762
|
+
* Returns a new `Schedule` that allows execution of an effectful function for
|
|
2763
|
+
* every input to the schedule, but does not alter the inputs and outputs of
|
|
2764
|
+
* the schedule.
|
|
2765
|
+
*
|
|
2766
|
+
* **Example** (Tapping retry inputs)
|
|
2767
|
+
*
|
|
2768
|
+
* ```ts
|
|
2769
|
+
* import { Console, Data, Effect, Schedule } from "effect"
|
|
2770
|
+
*
|
|
2771
|
+
* class RetryError extends Data.TaggedError("RetryError")<{ readonly message: string }> {}
|
|
2772
|
+
*
|
|
2773
|
+
* // Log retry errors for debugging
|
|
2774
|
+
* const errorLoggingSchedule = Schedule.exponential("100 millis").pipe(
|
|
2775
|
+
* Schedule.take(3),
|
|
2776
|
+
* Schedule.tapInput((error: RetryError) =>
|
|
2777
|
+
* Console.log(`Retry triggered by error: ${String(error)}`)
|
|
2778
|
+
* )
|
|
2779
|
+
* )
|
|
2780
|
+
*
|
|
2781
|
+
* const retryProgram = Effect.gen(function*() {
|
|
2782
|
+
* let attempt = 0
|
|
2783
|
+
*
|
|
2784
|
+
* const result = yield* Effect.retry(
|
|
2785
|
+
* Effect.gen(function*() {
|
|
2786
|
+
* attempt++
|
|
2787
|
+
* if (attempt < 4) {
|
|
2788
|
+
* return yield* Effect.fail(new RetryError({ message: `Network timeout on attempt ${attempt}` }))
|
|
2789
|
+
* }
|
|
2790
|
+
* return `Success on attempt ${attempt}`
|
|
2791
|
+
* }),
|
|
2792
|
+
* errorLoggingSchedule
|
|
2793
|
+
* )
|
|
2794
|
+
*
|
|
2795
|
+
* yield* Console.log(`Final result: ${result}`)
|
|
2796
|
+
* })
|
|
2797
|
+
*
|
|
2798
|
+
* // Monitor input frequency for metrics
|
|
2799
|
+
* const inputMonitoringSchedule = Schedule.spaced("1 second").pipe(
|
|
2800
|
+
* Schedule.take(5),
|
|
2801
|
+
* Schedule.tapInput((input: unknown) =>
|
|
2802
|
+
* Effect.gen(function*() {
|
|
2803
|
+
* yield* Console.log(`Input type: ${typeof input}`)
|
|
2804
|
+
* // In real applications, might send metrics to monitoring system
|
|
2805
|
+
* })
|
|
2806
|
+
* )
|
|
2807
|
+
* )
|
|
2808
|
+
*
|
|
2809
|
+
* // Input validation with side effects
|
|
2810
|
+
* const validatingSchedule = Schedule.fixed("500 millis").pipe(
|
|
2811
|
+
* Schedule.take(4),
|
|
2812
|
+
* Schedule.tapInput((input: any) =>
|
|
2813
|
+
* Effect.gen(function*() {
|
|
2814
|
+
* if (typeof input === "object" && input !== null) {
|
|
2815
|
+
* yield* Console.log(`Valid object input: ${JSON.stringify(input)}`)
|
|
2816
|
+
* } else {
|
|
2817
|
+
* yield* Console.log(`Warning: Non-object input received: ${input}`)
|
|
2818
|
+
* }
|
|
2819
|
+
* })
|
|
2820
|
+
* )
|
|
2821
|
+
* )
|
|
2822
|
+
*
|
|
2823
|
+
* const validationProgram = Effect.gen(function*() {
|
|
2824
|
+
* let count = 0
|
|
2825
|
+
*
|
|
2826
|
+
* yield* Effect.repeat(
|
|
2827
|
+
* Effect.gen(function*() {
|
|
2828
|
+
* count++
|
|
2829
|
+
* yield* Console.log("Task with validation")
|
|
2830
|
+
* return { data: `sample-${count}` }
|
|
2831
|
+
* }),
|
|
2832
|
+
* validatingSchedule
|
|
2833
|
+
* )
|
|
2834
|
+
* })
|
|
2835
|
+
*
|
|
2836
|
+
* // Conditional alerting based on input
|
|
2837
|
+
* const alertingSchedule = Schedule.exponential("200 millis").pipe(
|
|
2838
|
+
* Schedule.take(6),
|
|
2839
|
+
* Schedule.tapInput((error: RetryError) =>
|
|
2840
|
+
* Effect.gen(function*() {
|
|
2841
|
+
* if (String(error).includes("critical")) {
|
|
2842
|
+
* yield* Console.log(`Critical error: ${String(error)}`)
|
|
2843
|
+
* // In real applications, might trigger alerts or notifications
|
|
2844
|
+
* } else {
|
|
2845
|
+
* yield* Console.log(`Regular error: ${String(error)}`)
|
|
2846
|
+
* }
|
|
2847
|
+
* })
|
|
2848
|
+
* )
|
|
2849
|
+
* )
|
|
2850
|
+
*
|
|
2851
|
+
* const alertProgram = Effect.gen(function*() {
|
|
2852
|
+
* let attempt = 0
|
|
2853
|
+
*
|
|
2854
|
+
* yield* Effect.retry(
|
|
2855
|
+
* Effect.gen(function*() {
|
|
2856
|
+
* attempt++
|
|
2857
|
+
* const isCritical = attempt === 3
|
|
2858
|
+
* const errorType = isCritical
|
|
2859
|
+
* ? "critical database failure"
|
|
2860
|
+
* : "temporary network issue"
|
|
2861
|
+
* return yield* Effect.fail(new RetryError({ message: errorType }))
|
|
2862
|
+
* }),
|
|
2863
|
+
* alertingSchedule
|
|
2864
|
+
* ).pipe(
|
|
2865
|
+
* Effect.catch((error: unknown) =>
|
|
2866
|
+
* Console.log(`All retries exhausted: ${String(error)}`)
|
|
2867
|
+
* )
|
|
2868
|
+
* )
|
|
2869
|
+
* })
|
|
2870
|
+
*
|
|
2871
|
+
* // Chain multiple input taps for different purposes
|
|
2872
|
+
* const comprehensiveSchedule = Schedule.fibonacci("100 millis").pipe(
|
|
2873
|
+
* Schedule.take(5),
|
|
2874
|
+
* Schedule.tapInput((error: RetryError) =>
|
|
2875
|
+
* Console.log(`Error occurred: ${error._tag}`)
|
|
2876
|
+
* ),
|
|
2877
|
+
* Schedule.tapInput((error: RetryError) =>
|
|
2878
|
+
* String(error).length > 20
|
|
2879
|
+
* ? Console.log("Long error message detected")
|
|
2880
|
+
* : Effect.void
|
|
2881
|
+
* )
|
|
2882
|
+
* )
|
|
2883
|
+
* ```
|
|
2884
|
+
*
|
|
2885
|
+
* @category sequencing
|
|
2886
|
+
* @since 2.0.0
|
|
2887
|
+
*/
|
|
2888
|
+
export const tapInput: {
|
|
2889
|
+
<Input, X, Error2, Env2>(
|
|
2890
|
+
f: (input: Input) => Effect<X, Error2, Env2>
|
|
2891
|
+
): <Output, Error, Env>(
|
|
2892
|
+
self: Schedule<Output, Input, Error, Env>
|
|
2893
|
+
) => Schedule<Output, Input, Error | Error2, Env | Env2>
|
|
2894
|
+
<Output, Input, Error, Env, X, Error2, Env2>(
|
|
2895
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
2896
|
+
f: (input: Input) => Effect<X, Error2, Env2>
|
|
2897
|
+
): Schedule<Output, Input, Error | Error2, Env | Env2>
|
|
2898
|
+
} = dual(2, <Output, Input, Error, Env, X, Error2, Env2>(
|
|
2899
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
2900
|
+
f: (input: Input) => Effect<X, Error2, Env2>
|
|
2901
|
+
): Schedule<Output, Input, Error | Error2, Env | Env2> =>
|
|
2902
|
+
fromStep(effect.map(
|
|
2903
|
+
toStep(self),
|
|
2904
|
+
(step) => (now, input) => effect.andThen(f(input), step(now, input))
|
|
2905
|
+
)))
|
|
2906
|
+
|
|
2907
|
+
/**
|
|
2908
|
+
* Returns a new `Schedule` that allows execution of an effectful function for
|
|
2909
|
+
* every output of the schedule, but does not alter the inputs and outputs of
|
|
2910
|
+
* the schedule.
|
|
2911
|
+
*
|
|
2912
|
+
* **Example** (Tapping schedule outputs)
|
|
2913
|
+
*
|
|
2914
|
+
* ```ts
|
|
2915
|
+
* import { Console, Data, Effect, Schedule } from "effect"
|
|
2916
|
+
*
|
|
2917
|
+
* class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
|
|
2918
|
+
*
|
|
2919
|
+
* // Log schedule outputs for debugging/monitoring
|
|
2920
|
+
* const monitoredSchedule = Schedule.exponential("100 millis").pipe(
|
|
2921
|
+
* Schedule.take(5),
|
|
2922
|
+
* Schedule.tapOutput((delay) => Console.log(`Next delay will be: ${delay}`))
|
|
2923
|
+
* )
|
|
2924
|
+
*
|
|
2925
|
+
* const retryProgram = Effect.gen(function*() {
|
|
2926
|
+
* let attempt = 0
|
|
2927
|
+
*
|
|
2928
|
+
* const result = yield* Effect.retry(
|
|
2929
|
+
* Effect.gen(function*() {
|
|
2930
|
+
* attempt++
|
|
2931
|
+
* if (attempt < 4) {
|
|
2932
|
+
* return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
|
|
2933
|
+
* }
|
|
2934
|
+
* return `Success on attempt ${attempt}`
|
|
2935
|
+
* }),
|
|
2936
|
+
* monitoredSchedule
|
|
2937
|
+
* )
|
|
2938
|
+
*
|
|
2939
|
+
* yield* Console.log(`Final result: ${result}`)
|
|
2940
|
+
* })
|
|
2941
|
+
*
|
|
2942
|
+
* // Tap output for metrics collection
|
|
2943
|
+
* const metricsSchedule = Schedule.spaced("1 second").pipe(
|
|
2944
|
+
* Schedule.take(10),
|
|
2945
|
+
* Schedule.tapOutput((executionCount) =>
|
|
2946
|
+
* Effect.gen(function*() {
|
|
2947
|
+
* // Simulate metrics collection
|
|
2948
|
+
* yield* Console.log(`Recording metric: execution_count=${executionCount}`)
|
|
2949
|
+
* // In real code, this might send to monitoring system
|
|
2950
|
+
* })
|
|
2951
|
+
* )
|
|
2952
|
+
* )
|
|
2953
|
+
*
|
|
2954
|
+
* // Tap output with conditional side effects
|
|
2955
|
+
* const alertingSchedule = Schedule.fibonacci("200 millis").pipe(
|
|
2956
|
+
* Schedule.take(8),
|
|
2957
|
+
* Schedule.tapOutput((delay) =>
|
|
2958
|
+
* Effect.gen(function*() {
|
|
2959
|
+
* const delayMs = delay.toString()
|
|
2960
|
+
* if (delayMs.includes("1000")) { // Alert on delays >= 1 second
|
|
2961
|
+
* yield* Console.log(`High delay detected: ${delay}`)
|
|
2962
|
+
* }
|
|
2963
|
+
* })
|
|
2964
|
+
* )
|
|
2965
|
+
* )
|
|
2966
|
+
*
|
|
2967
|
+
* const healthCheckProgram = Effect.gen(function*() {
|
|
2968
|
+
* yield* Effect.repeat(
|
|
2969
|
+
* Effect.gen(function*() {
|
|
2970
|
+
* yield* Console.log("Performing health check...")
|
|
2971
|
+
* return "healthy"
|
|
2972
|
+
* }),
|
|
2973
|
+
* alertingSchedule
|
|
2974
|
+
* )
|
|
2975
|
+
* })
|
|
2976
|
+
*
|
|
2977
|
+
* // Chain multiple taps for different purposes
|
|
2978
|
+
* const comprehensiveSchedule = Schedule.fixed("500 millis").pipe(
|
|
2979
|
+
* Schedule.take(6),
|
|
2980
|
+
* Schedule.tapOutput((count) => Console.log(`Execution ${count + 1}`)),
|
|
2981
|
+
* Schedule.tapOutput((count) =>
|
|
2982
|
+
* count % 3 === 0
|
|
2983
|
+
* ? Console.log("Checkpoint reached")
|
|
2984
|
+
* : Effect.void
|
|
2985
|
+
* )
|
|
2986
|
+
* )
|
|
2987
|
+
* ```
|
|
2988
|
+
*
|
|
2989
|
+
* @category sequencing
|
|
2990
|
+
* @since 2.0.0
|
|
2991
|
+
*/
|
|
2992
|
+
export const tapOutput: {
|
|
2993
|
+
<Output, X, Error2, Env2>(
|
|
2994
|
+
f: (output: Output) => Effect<X, Error2, Env2>
|
|
2995
|
+
): <Input, Error, Env>(
|
|
2996
|
+
self: Schedule<Output, Input, Error, Env>
|
|
2997
|
+
) => Schedule<Output, Input, Error | Error2, Env | Env2>
|
|
2998
|
+
<Output, Input, Error, Env, X, Error2, Env2>(
|
|
2999
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
3000
|
+
f: (output: Output) => Effect<X, Error2, Env2>
|
|
3001
|
+
): Schedule<Output, Input, Error | Error2, Env | Env2>
|
|
3002
|
+
} = dual(2, <Output, Input, Error, Env, X, Error2, Env2>(
|
|
3003
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
3004
|
+
f: (output: Output) => Effect<X, Error2, Env2>
|
|
3005
|
+
): Schedule<Output, Input, Error | Error2, Env | Env2> =>
|
|
3006
|
+
fromStep(effect.map(
|
|
3007
|
+
toStep(self),
|
|
3008
|
+
(step) => (now, input) => effect.tap(step(now, input), ([output]) => f(output))
|
|
3009
|
+
)))
|
|
3010
|
+
|
|
3011
|
+
/**
|
|
3012
|
+
* Returns a new `Schedule` that takes at most the specified number of outputs
|
|
3013
|
+
* from the schedule. Once the specified number of outputs is reached, the
|
|
3014
|
+
* schedule will stop.
|
|
3015
|
+
*
|
|
3016
|
+
* **When to use**
|
|
3017
|
+
*
|
|
3018
|
+
* Use to limit an existing schedule while preserving its output and delay behavior.
|
|
3019
|
+
*
|
|
3020
|
+
* **Gotchas**
|
|
3021
|
+
*
|
|
3022
|
+
* `take(n)` limits schedule outputs. When used with repeat or retry, the
|
|
3023
|
+
* effect is evaluated once before the schedule is stepped, so the total number
|
|
3024
|
+
* of evaluations can be one greater than the number of outputs taken.
|
|
3025
|
+
*
|
|
3026
|
+
* **Example** (Taking a limited number of recurrences)
|
|
3027
|
+
*
|
|
3028
|
+
* ```ts
|
|
3029
|
+
* import { Console, Data, Effect, Schedule } from "effect"
|
|
3030
|
+
*
|
|
3031
|
+
* class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
|
|
3032
|
+
*
|
|
3033
|
+
* // Limit an infinite schedule to five recurrences
|
|
3034
|
+
* const limitedHeartbeat = Schedule.spaced("1 second").pipe(
|
|
3035
|
+
* Schedule.take(5) // Will stop after 5 schedule outputs
|
|
3036
|
+
* )
|
|
3037
|
+
*
|
|
3038
|
+
* const heartbeatProgram = Effect.gen(function*() {
|
|
3039
|
+
* yield* Effect.repeat(
|
|
3040
|
+
* Effect.gen(function*() {
|
|
3041
|
+
* yield* Console.log("Heartbeat")
|
|
3042
|
+
* return "pulse"
|
|
3043
|
+
* }),
|
|
3044
|
+
* limitedHeartbeat
|
|
3045
|
+
* )
|
|
3046
|
+
*
|
|
3047
|
+
* yield* Console.log("Heartbeat sequence completed")
|
|
3048
|
+
* })
|
|
3049
|
+
*
|
|
3050
|
+
* // Limit retry attempts to a specific number
|
|
3051
|
+
* const limitedRetry = Schedule.exponential("100 millis").pipe(
|
|
3052
|
+
* Schedule.take(3) // At most 3 retry attempts
|
|
3053
|
+
* )
|
|
3054
|
+
*
|
|
3055
|
+
* const retryProgram = Effect.gen(function*() {
|
|
3056
|
+
* let attempt = 0
|
|
3057
|
+
*
|
|
3058
|
+
* const result = yield* Effect.retry(
|
|
3059
|
+
* Effect.gen(function*() {
|
|
3060
|
+
* attempt++
|
|
3061
|
+
* yield* Console.log(`Attempt ${attempt}`)
|
|
3062
|
+
*
|
|
3063
|
+
* if (attempt < 5) { // Will fail more than 3 times
|
|
3064
|
+
* return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
|
|
3065
|
+
* }
|
|
3066
|
+
*
|
|
3067
|
+
* return `Success on attempt ${attempt}`
|
|
3068
|
+
* }),
|
|
3069
|
+
* limitedRetry
|
|
3070
|
+
* )
|
|
3071
|
+
*
|
|
3072
|
+
* yield* Console.log(`Result: ${result}`)
|
|
3073
|
+
* }).pipe(
|
|
3074
|
+
* Effect.catch((error: unknown) =>
|
|
3075
|
+
* Console.log(`Failed after limited retries: ${String(error)}`)
|
|
3076
|
+
* )
|
|
3077
|
+
* )
|
|
3078
|
+
*
|
|
3079
|
+
* // Combine take with other schedule operations
|
|
3080
|
+
* const samplingSchedule = Schedule.fixed("500 millis").pipe(
|
|
3081
|
+
* Schedule.take(10), // Take at most 10 schedule outputs
|
|
3082
|
+
* Schedule.map((count) => Effect.succeed(`Sample #${count + 1}`))
|
|
3083
|
+
* )
|
|
3084
|
+
*
|
|
3085
|
+
* const samplingProgram = Effect.gen(function*() {
|
|
3086
|
+
* yield* Effect.repeat(
|
|
3087
|
+
* Effect.gen(function*() {
|
|
3088
|
+
* const value = "sample"
|
|
3089
|
+
* yield* Console.log(`Sampled value: ${value}`)
|
|
3090
|
+
* return value
|
|
3091
|
+
* }),
|
|
3092
|
+
* samplingSchedule.pipe(
|
|
3093
|
+
* Schedule.tapOutput((label) => Console.log(`Completed: ${label}`))
|
|
3094
|
+
* )
|
|
3095
|
+
* )
|
|
3096
|
+
* })
|
|
3097
|
+
* ```
|
|
3098
|
+
*
|
|
3099
|
+
* @see {@link recurs} for creating a count-limited schedule
|
|
3100
|
+
*
|
|
3101
|
+
* @category taking
|
|
3102
|
+
* @since 4.0.0
|
|
3103
|
+
*/
|
|
3104
|
+
export const take: {
|
|
3105
|
+
(n: number): <Output, Input, Error, Env>(
|
|
3106
|
+
self: Schedule<Output, Input, Error, Env>
|
|
3107
|
+
) => Schedule<Output, Input, Error, Env>
|
|
3108
|
+
<Output, Input, Error, Env>(
|
|
3109
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
3110
|
+
n: number
|
|
3111
|
+
): Schedule<Output, Input, Error, Env>
|
|
3112
|
+
} = dual(2, <Output, Input, Error, Env>(
|
|
3113
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
3114
|
+
n: number
|
|
3115
|
+
): Schedule<Output, Input, Error, Env> => while_(self, ({ attempt }) => effect.succeed(attempt <= n)))
|
|
3116
|
+
|
|
3117
|
+
/**
|
|
3118
|
+
* Creates a schedule that unfolds a state by repeatedly applying a function,
|
|
3119
|
+
* outputting the current state and computing the next state.
|
|
3120
|
+
*
|
|
3121
|
+
* **Example** (Unfolding schedule state)
|
|
3122
|
+
*
|
|
3123
|
+
* ```ts
|
|
3124
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
3125
|
+
*
|
|
3126
|
+
* // Counter schedule that increments by 1 each time
|
|
3127
|
+
* const counterSchedule = Schedule.unfold(0, (n) => Effect.succeed(n + 1))
|
|
3128
|
+
* // Outputs: 0, 1, 2, 3, 4, 5, ...
|
|
3129
|
+
*
|
|
3130
|
+
* const countingProgram = Effect.gen(function*() {
|
|
3131
|
+
* yield* Effect.repeat(
|
|
3132
|
+
* Effect.gen(function*() {
|
|
3133
|
+
* yield* Console.log("Task executed")
|
|
3134
|
+
* return "done"
|
|
3135
|
+
* }),
|
|
3136
|
+
* counterSchedule.pipe(
|
|
3137
|
+
* Schedule.take(5),
|
|
3138
|
+
* Schedule.tapOutput((count) => Console.log(`Count: ${count}`))
|
|
3139
|
+
* )
|
|
3140
|
+
* )
|
|
3141
|
+
* })
|
|
3142
|
+
*
|
|
3143
|
+
* // Fibonacci sequence schedule
|
|
3144
|
+
* const fibonacciSchedule = Schedule.unfold(
|
|
3145
|
+
* [0, 1] as [number, number],
|
|
3146
|
+
* ([a, b]) => Effect.succeed([b, a + b] as [number, number])
|
|
3147
|
+
* )
|
|
3148
|
+
* // Outputs: [0,1], [1,1], [1,2], [2,3], [3,5], [5,8], ...
|
|
3149
|
+
*
|
|
3150
|
+
* const fibProgram = Effect.gen(function*() {
|
|
3151
|
+
* yield* Effect.repeat(
|
|
3152
|
+
* Console.log("Fibonacci step"),
|
|
3153
|
+
* fibonacciSchedule.pipe(
|
|
3154
|
+
* Schedule.take(8),
|
|
3155
|
+
* Schedule.tapOutput(([a, b]) => Console.log(`Fib: ${a}, next: ${b}`))
|
|
3156
|
+
* )
|
|
3157
|
+
* )
|
|
3158
|
+
* })
|
|
3159
|
+
*
|
|
3160
|
+
* // Effectful unfold - exponential backoff with state
|
|
3161
|
+
* const exponentialState = Schedule.unfold(
|
|
3162
|
+
* 100,
|
|
3163
|
+
* (delayMs) =>
|
|
3164
|
+
* Effect.gen(function*() {
|
|
3165
|
+
* yield* Console.log(`Current delay: ${delayMs}ms`)
|
|
3166
|
+
* return Math.min(delayMs * 2, 5000) // Cap at 5 seconds
|
|
3167
|
+
* })
|
|
3168
|
+
* )
|
|
3169
|
+
*
|
|
3170
|
+
* // Deterministic delay adjustment schedule
|
|
3171
|
+
* const adjustedDelaySchedule = Schedule.unfold(
|
|
3172
|
+
* { delay: 1000, adjustment: 100 },
|
|
3173
|
+
* ({ delay, adjustment }) =>
|
|
3174
|
+
* Effect.gen(function*() {
|
|
3175
|
+
* const nextDelay = Math.max(100, delay + adjustment)
|
|
3176
|
+
* yield* Console.log(`Adjusted delay: ${nextDelay}ms`)
|
|
3177
|
+
* return { delay: nextDelay, adjustment: adjustment * -1 }
|
|
3178
|
+
* })
|
|
3179
|
+
* )
|
|
3180
|
+
*
|
|
3181
|
+
* // State machine schedule
|
|
3182
|
+
* type State = "init" | "warming" | "active" | "cooling"
|
|
3183
|
+
* const stateMachineSchedule = Schedule.unfold("init" as State, (state) => {
|
|
3184
|
+
* switch (state) {
|
|
3185
|
+
* case "init":
|
|
3186
|
+
* return Effect.succeed("warming" as State)
|
|
3187
|
+
* case "warming":
|
|
3188
|
+
* return Effect.succeed("active" as State)
|
|
3189
|
+
* case "active":
|
|
3190
|
+
* return Effect.succeed("cooling" as State)
|
|
3191
|
+
* case "cooling":
|
|
3192
|
+
* return Effect.succeed("active" as State)
|
|
3193
|
+
* }
|
|
3194
|
+
* })
|
|
3195
|
+
*
|
|
3196
|
+
* const stateMachineProgram = Effect.gen(function*() {
|
|
3197
|
+
* yield* Effect.repeat(
|
|
3198
|
+
* Effect.gen(function*() {
|
|
3199
|
+
* yield* Console.log("State machine step")
|
|
3200
|
+
* return "step"
|
|
3201
|
+
* }),
|
|
3202
|
+
* stateMachineSchedule.pipe(
|
|
3203
|
+
* Schedule.take(10),
|
|
3204
|
+
* Schedule.tapOutput((state) => Console.log(`State: ${state}`))
|
|
3205
|
+
* )
|
|
3206
|
+
* )
|
|
3207
|
+
* })
|
|
3208
|
+
* ```
|
|
3209
|
+
*
|
|
3210
|
+
* @category constructors
|
|
3211
|
+
* @since 2.0.0
|
|
3212
|
+
*/
|
|
3213
|
+
export const unfold = <State, Error = never, Env = never>(
|
|
3214
|
+
initial: State,
|
|
3215
|
+
next: (state: State) => Effect<State, Error, Env>
|
|
3216
|
+
): Schedule<State, unknown, Error, Env> =>
|
|
3217
|
+
fromStep(effect.sync(() => {
|
|
3218
|
+
let state = initial
|
|
3219
|
+
return constant(effect.map(
|
|
3220
|
+
effect.suspend(() => next(state)),
|
|
3221
|
+
(nextState) => {
|
|
3222
|
+
const prev = state
|
|
3223
|
+
state = nextState
|
|
3224
|
+
return [prev, Duration.zero] as const
|
|
3225
|
+
}
|
|
3226
|
+
))
|
|
3227
|
+
}))
|
|
3228
|
+
|
|
3229
|
+
const while_: {
|
|
3230
|
+
<Input, Output, Error2 = never, Env2 = never>(
|
|
3231
|
+
predicate: (
|
|
3232
|
+
metadata: Metadata<Output, Input>
|
|
3233
|
+
) => boolean | Effect<boolean, Error2, Env2>
|
|
3234
|
+
): <Error, Env>(
|
|
3235
|
+
self: Schedule<Output, Input, Error, Env>
|
|
3236
|
+
) => Schedule<Output, Input, Error | Error2, Env | Env2>
|
|
3237
|
+
<Output, Input, Error, Env, Error2 = never, Env2 = never>(
|
|
3238
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
3239
|
+
predicate: (
|
|
3240
|
+
metadata: Metadata<Output, Input>
|
|
3241
|
+
) => boolean | Effect<boolean, Error2, Env2>
|
|
3242
|
+
): Schedule<Output, Input, Error | Error2, Env | Env2>
|
|
3243
|
+
} = dual(2, <Output, Input, Error, Env, Error2 = never, Env2 = never>(
|
|
3244
|
+
self: Schedule<Output, Input, Error, Env>,
|
|
3245
|
+
predicate: (
|
|
3246
|
+
metadata: Metadata<Output, Input>
|
|
3247
|
+
) => boolean | Effect<boolean, Error2, Env2>
|
|
3248
|
+
): Schedule<Output, Input, Error | Error2, Env | Env2> =>
|
|
3249
|
+
fromStep(effect.map(toStep(self), (step) => {
|
|
3250
|
+
const meta = metadataFn()
|
|
3251
|
+
return (now, input) =>
|
|
3252
|
+
effect.flatMap(step(now, input), (result) => {
|
|
3253
|
+
const [output, duration] = result
|
|
3254
|
+
const eff = predicate({ ...meta(now, input), output, duration })
|
|
3255
|
+
return effect.flatMap(
|
|
3256
|
+
isEffect(eff) ? eff : effect.succeed(eff),
|
|
3257
|
+
(check) => (check ? effect.succeed(result) : Cause.done(output))
|
|
3258
|
+
)
|
|
3259
|
+
})
|
|
3260
|
+
})))
|
|
3261
|
+
|
|
3262
|
+
export {
|
|
3263
|
+
/**
|
|
3264
|
+
* Returns a new schedule that continues while the predicate returns `true`.
|
|
3265
|
+
*
|
|
3266
|
+
* **When to use**
|
|
3267
|
+
*
|
|
3268
|
+
* Use to stop an existing schedule based on its full metadata, such as the
|
|
3269
|
+
* current input, output, attempt, delay, or elapsed time.
|
|
3270
|
+
*
|
|
3271
|
+
* **Details**
|
|
3272
|
+
*
|
|
3273
|
+
* The predicate receives `Metadata`, may return `boolean` or an
|
|
3274
|
+
* `Effect<boolean, ...>`, preserves the output and delay when it returns
|
|
3275
|
+
* `true`, and stops the schedule when it returns `false`.
|
|
3276
|
+
*
|
|
3277
|
+
* @see {@link collectWhile} for collecting outputs while using the same predicate
|
|
3278
|
+
* @see {@link take} for stopping after a fixed number of schedule outputs
|
|
3279
|
+
*
|
|
3280
|
+
* @category filtering
|
|
3281
|
+
* @since 4.0.0
|
|
3282
|
+
*/
|
|
3283
|
+
while_ as while
|
|
3284
|
+
}
|
|
3285
|
+
|
|
3286
|
+
/**
|
|
3287
|
+
* Schedule that divides the timeline to `interval`-long windows, and sleeps
|
|
3288
|
+
* until the nearest window boundary every time it recurs.
|
|
3289
|
+
*
|
|
3290
|
+
* **Details**
|
|
3291
|
+
*
|
|
3292
|
+
* For example, `Schedule.windowed("10 seconds")` would produce a schedule as
|
|
3293
|
+
* follows:
|
|
3294
|
+
*
|
|
3295
|
+
* ```text
|
|
3296
|
+
* 10s 10s 10s 10s
|
|
3297
|
+
* |----------|----------|----------|----------|
|
|
3298
|
+
* |action------|sleep---|act|-sleep|action----|
|
|
3299
|
+
* ```
|
|
3300
|
+
*
|
|
3301
|
+
* **Example** (Repeating on aligned windows)
|
|
3302
|
+
*
|
|
3303
|
+
* ```ts
|
|
3304
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
3305
|
+
*
|
|
3306
|
+
* // Execute tasks at regular intervals aligned to window boundaries
|
|
3307
|
+
* const windowSchedule = Schedule.windowed("5 seconds")
|
|
3308
|
+
*
|
|
3309
|
+
* const program = Effect.gen(function*() {
|
|
3310
|
+
* yield* Effect.repeat(
|
|
3311
|
+
* Effect.gen(function*() {
|
|
3312
|
+
* yield* Console.log("Window task executed")
|
|
3313
|
+
* return "window-task"
|
|
3314
|
+
* }),
|
|
3315
|
+
* windowSchedule.pipe(Schedule.take(4))
|
|
3316
|
+
* )
|
|
3317
|
+
* })
|
|
3318
|
+
* ```
|
|
3319
|
+
*
|
|
3320
|
+
* @category constructors
|
|
3321
|
+
* @since 2.0.0
|
|
3322
|
+
*/
|
|
3323
|
+
export const windowed = (interval: Duration.Input): Schedule<number> => {
|
|
3324
|
+
const window = Duration.toMillis(Duration.fromInputUnsafe(interval))
|
|
3325
|
+
return fromStepWithMetadata(effect.succeed((meta) =>
|
|
3326
|
+
effect.sync(() => [
|
|
3327
|
+
meta.attempt - 1,
|
|
3328
|
+
window === 0 ? Duration.zero : Duration.millis(window - (meta.elapsed % window))
|
|
3329
|
+
])
|
|
3330
|
+
))
|
|
3331
|
+
}
|
|
3332
|
+
|
|
3333
|
+
/**
|
|
3334
|
+
* Returns a new `Schedule` that will recur forever.
|
|
3335
|
+
*
|
|
3336
|
+
* **Details**
|
|
3337
|
+
*
|
|
3338
|
+
* The output of the schedule is the current count of its repetitions thus far
|
|
3339
|
+
* (i.e. `0, 1, 2, ...`).
|
|
3340
|
+
*
|
|
3341
|
+
* **Example** (Repeating forever)
|
|
3342
|
+
*
|
|
3343
|
+
* ```ts
|
|
3344
|
+
* import { Console, Effect, Schedule } from "effect"
|
|
3345
|
+
*
|
|
3346
|
+
* // A schedule that runs forever with no delay
|
|
3347
|
+
* const infiniteSchedule = Schedule.forever
|
|
3348
|
+
*
|
|
3349
|
+
* const program = Effect.gen(function*() {
|
|
3350
|
+
* yield* Effect.repeat(
|
|
3351
|
+
* Effect.gen(function*() {
|
|
3352
|
+
* yield* Console.log("Running forever...")
|
|
3353
|
+
* return "continuous-task"
|
|
3354
|
+
* }),
|
|
3355
|
+
* infiniteSchedule.pipe(Schedule.take(5)) // Limit for demo
|
|
3356
|
+
* )
|
|
3357
|
+
* })
|
|
3358
|
+
* ```
|
|
3359
|
+
*
|
|
3360
|
+
* @category constructors
|
|
3361
|
+
* @since 2.0.0
|
|
3362
|
+
*/
|
|
3363
|
+
export const forever: Schedule<number> = spaced(Duration.zero)
|
|
3364
|
+
|
|
3365
|
+
const constIdentity = fromStep(
|
|
3366
|
+
effect.succeed((_now, input: unknown) => effect.succeed([input, Duration.zero] as [unknown, Duration.Duration]))
|
|
3367
|
+
)
|
|
3368
|
+
|
|
3369
|
+
const identity_ = <A>(): Schedule<A, A> => constIdentity as Schedule<A, A>
|
|
3370
|
+
|
|
3371
|
+
export {
|
|
3372
|
+
/**
|
|
3373
|
+
* Creates a schedule that always recurs, passing inputs directly as outputs.
|
|
3374
|
+
*
|
|
3375
|
+
* **When to use**
|
|
3376
|
+
*
|
|
3377
|
+
* Use when you need an infinite schedule that preserves input values as
|
|
3378
|
+
* outputs.
|
|
3379
|
+
*
|
|
3380
|
+
* **Details**
|
|
3381
|
+
*
|
|
3382
|
+
* This schedule runs indefinitely, returning each input value as its output
|
|
3383
|
+
* without modification. It effectively acts as a pass-through that simply
|
|
3384
|
+
* echoes its input values at each step.
|
|
3385
|
+
*
|
|
3386
|
+
* @see {@link forever} for an infinite schedule that returns incrementing step counts
|
|
3387
|
+
* @category constructors
|
|
3388
|
+
* @since 2.0.0
|
|
3389
|
+
*/
|
|
3390
|
+
identity_ as identity
|
|
3391
|
+
}
|
|
3392
|
+
|
|
3393
|
+
/**
|
|
3394
|
+
* Ensures that a schedule's input type extends a given type `T`.
|
|
3395
|
+
*
|
|
3396
|
+
* **When to use**
|
|
3397
|
+
*
|
|
3398
|
+
* Use when you need a generic helper to prove that an existing schedule can
|
|
3399
|
+
* consume a required input type without changing runtime behavior.
|
|
3400
|
+
*
|
|
3401
|
+
* **Example** (Constraining schedule input types)
|
|
3402
|
+
*
|
|
3403
|
+
* ```ts
|
|
3404
|
+
* import { Schedule } from "effect"
|
|
3405
|
+
*
|
|
3406
|
+
* declare const StringInputSchedule: Schedule.Schedule<number, string>
|
|
3407
|
+
* declare const NumberInputSchedule: Schedule.Schedule<number, number>
|
|
3408
|
+
*
|
|
3409
|
+
* const satisfiesStringInput = Schedule.satisfiesInputType<string>()
|
|
3410
|
+
*
|
|
3411
|
+
* // This works because the schedule input type is string.
|
|
3412
|
+
* const validSchedule = satisfiesStringInput(StringInputSchedule)
|
|
3413
|
+
*
|
|
3414
|
+
* // This would cause a TypeScript compilation error:
|
|
3415
|
+
* // const invalidSchedule = satisfiesStringInput(NumberInputSchedule)
|
|
3416
|
+
* ```
|
|
3417
|
+
*
|
|
3418
|
+
* @see {@link setInputType} for adapting an input-agnostic schedule
|
|
3419
|
+
*
|
|
3420
|
+
* @category utility types
|
|
3421
|
+
* @since 4.0.0
|
|
3422
|
+
*/
|
|
3423
|
+
export const satisfiesInputType = <T>() =>
|
|
3424
|
+
<Input extends T, Output = never, Error = never, Env = never>(
|
|
3425
|
+
self: Schedule<Output, Input, Error, Env>
|
|
3426
|
+
): Schedule<Output, Input, Error, Env> => self
|
|
3427
|
+
|
|
3428
|
+
/**
|
|
3429
|
+
* Sets the input type of the provided schedule without altering its behavior.
|
|
3430
|
+
*
|
|
3431
|
+
* **When to use**
|
|
3432
|
+
*
|
|
3433
|
+
* Use to adapt a schedule that does not depend on its input values.
|
|
3434
|
+
*
|
|
3435
|
+
* **Details**
|
|
3436
|
+
*
|
|
3437
|
+
* This helper is checked at compile time and does not change the schedule's
|
|
3438
|
+
* runtime behavior.
|
|
3439
|
+
*
|
|
3440
|
+
* **Example** (Setting a schedule input type)
|
|
3441
|
+
*
|
|
3442
|
+
* ```ts
|
|
3443
|
+
* import { Schedule } from "effect"
|
|
3444
|
+
*
|
|
3445
|
+
* const schedule = Schedule.recurs(3).pipe(
|
|
3446
|
+
* Schedule.setInputType<string>()
|
|
3447
|
+
* )
|
|
3448
|
+
* ```
|
|
3449
|
+
*
|
|
3450
|
+
* @see {@link satisfiesInputType} for checking an existing input type
|
|
3451
|
+
*
|
|
3452
|
+
* @category utility types
|
|
3453
|
+
* @since 4.0.0
|
|
3454
|
+
*/
|
|
3455
|
+
export const setInputType =
|
|
3456
|
+
<T>() => <Output, Error, Env>(self: Schedule<Output, T, Error, Env>): Schedule<Output, T, Error, Env> => self
|
|
3457
|
+
|
|
3458
|
+
/**
|
|
3459
|
+
* Ensures that a schedule's output type extends a given type `T`.
|
|
3460
|
+
*
|
|
3461
|
+
* **Details**
|
|
3462
|
+
*
|
|
3463
|
+
* This helper is checked at compile time and does not change the schedule's
|
|
3464
|
+
* runtime behavior.
|
|
3465
|
+
*
|
|
3466
|
+
* **Example** (Constraining schedule output types)
|
|
3467
|
+
*
|
|
3468
|
+
* ```ts
|
|
3469
|
+
* import { Schedule } from "effect"
|
|
3470
|
+
*
|
|
3471
|
+
* declare const StringOutputSchedule: Schedule.Schedule<string>
|
|
3472
|
+
* declare const NumberOutputSchedule: Schedule.Schedule<number>
|
|
3473
|
+
*
|
|
3474
|
+
* const satisfiesStringOutput = Schedule.satisfiesOutputType<string>()
|
|
3475
|
+
*
|
|
3476
|
+
* // This works because the schedule output type is string.
|
|
3477
|
+
* const validSchedule = satisfiesStringOutput(StringOutputSchedule)
|
|
3478
|
+
*
|
|
3479
|
+
* // This would cause a TypeScript compilation error:
|
|
3480
|
+
* // const invalidSchedule = satisfiesStringOutput(NumberOutputSchedule)
|
|
3481
|
+
* ```
|
|
3482
|
+
*
|
|
3483
|
+
* @category utility types
|
|
3484
|
+
* @since 4.0.0
|
|
3485
|
+
*/
|
|
3486
|
+
export const satisfiesOutputType = <T>() =>
|
|
3487
|
+
<Output extends T, Error = never, Input = unknown, Env = never>(
|
|
3488
|
+
self: Schedule<Output, Input, Error, Env>
|
|
3489
|
+
): Schedule<Output, Input, Error, Env> => self
|
|
3490
|
+
|
|
3491
|
+
/**
|
|
3492
|
+
* Ensures that a schedule's error type extends a given type `T`.
|
|
3493
|
+
*
|
|
3494
|
+
* **Details**
|
|
3495
|
+
*
|
|
3496
|
+
* This helper is checked at compile time and does not change the schedule's
|
|
3497
|
+
* runtime behavior.
|
|
3498
|
+
*
|
|
3499
|
+
* **Example** (Constraining schedule error types)
|
|
3500
|
+
*
|
|
3501
|
+
* ```ts
|
|
3502
|
+
* import { Data, Schedule } from "effect"
|
|
3503
|
+
*
|
|
3504
|
+
* // Create a custom error using Data.TaggedError
|
|
3505
|
+
* class CustomError extends Data.TaggedError("CustomError")<{
|
|
3506
|
+
* message: string
|
|
3507
|
+
* }> {}
|
|
3508
|
+
*
|
|
3509
|
+
* declare const CustomErrorSchedule: Schedule.Schedule<number, unknown, CustomError>
|
|
3510
|
+
* declare const StringErrorSchedule: Schedule.Schedule<number, unknown, string>
|
|
3511
|
+
*
|
|
3512
|
+
* const satisfiesCustomError = Schedule.satisfiesErrorType<CustomError>()
|
|
3513
|
+
*
|
|
3514
|
+
* // This works because the schedule error type is CustomError.
|
|
3515
|
+
* const validSchedule = satisfiesCustomError(CustomErrorSchedule)
|
|
3516
|
+
*
|
|
3517
|
+
* // This would cause a TypeScript compilation error:
|
|
3518
|
+
* // const invalidSchedule = satisfiesCustomError(StringErrorSchedule)
|
|
3519
|
+
* ```
|
|
3520
|
+
*
|
|
3521
|
+
* @category utility types
|
|
3522
|
+
* @since 4.0.0
|
|
3523
|
+
*/
|
|
3524
|
+
export const satisfiesErrorType = <T>() =>
|
|
3525
|
+
<Error extends T, Output = never, Input = unknown, Env = never>(
|
|
3526
|
+
self: Schedule<Output, Input, Error, Env>
|
|
3527
|
+
): Schedule<Output, Input, Error, Env> => self
|
|
3528
|
+
|
|
3529
|
+
/**
|
|
3530
|
+
* Ensures that a schedule's context type extends a given type `T`.
|
|
3531
|
+
*
|
|
3532
|
+
* **Details**
|
|
3533
|
+
*
|
|
3534
|
+
* This helper is checked at compile time and does not change the schedule's
|
|
3535
|
+
* runtime behavior.
|
|
3536
|
+
*
|
|
3537
|
+
* **Example** (Constraining schedule service types)
|
|
3538
|
+
*
|
|
3539
|
+
* ```ts
|
|
3540
|
+
* import { Schedule } from "effect"
|
|
3541
|
+
*
|
|
3542
|
+
* interface Logger {
|
|
3543
|
+
* readonly log: (message: string) => void
|
|
3544
|
+
* }
|
|
3545
|
+
*
|
|
3546
|
+
* declare const LoggerSchedule: Schedule.Schedule<number, unknown, never, Logger>
|
|
3547
|
+
* declare const NumberSchedule: Schedule.Schedule<number, unknown, never, number>
|
|
3548
|
+
*
|
|
3549
|
+
* const satisfiesLogger = Schedule.satisfiesServicesType<Logger>()
|
|
3550
|
+
*
|
|
3551
|
+
* // This works because the schedule context type is Logger.
|
|
3552
|
+
* const validSchedule = satisfiesLogger(LoggerSchedule)
|
|
3553
|
+
*
|
|
3554
|
+
* // This would cause a TypeScript compilation error:
|
|
3555
|
+
* // const invalidSchedule = satisfiesLogger(NumberSchedule)
|
|
3556
|
+
* ```
|
|
3557
|
+
*
|
|
3558
|
+
* @category utility types
|
|
3559
|
+
* @since 4.0.0
|
|
3560
|
+
*/
|
|
3561
|
+
export const satisfiesServicesType = <T>() =>
|
|
3562
|
+
<Env extends T, Output = never, Input = unknown, Error = never>(
|
|
3563
|
+
self: Schedule<Output, Input, Error, Env>
|
|
3564
|
+
): Schedule<Output, Input, Error, Env> => self
|