@clayroach/effect 3.19.14-source-capture.8 → 3.19.14-source-trace.2

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.
Files changed (452) hide show
  1. package/SourceLocation/package.json +6 -0
  2. package/dist/cjs/Effect.js +2 -28
  3. package/dist/cjs/Effect.js.map +1 -1
  4. package/dist/cjs/FiberRef.js +12 -1
  5. package/dist/cjs/FiberRef.js.map +1 -1
  6. package/dist/cjs/Layer.js +2 -24
  7. package/dist/cjs/Layer.js.map +1 -1
  8. package/dist/cjs/RuntimeFlags.js +1 -29
  9. package/dist/cjs/RuntimeFlags.js.map +1 -1
  10. package/dist/cjs/SourceLocation.js +60 -0
  11. package/dist/cjs/SourceLocation.js.map +1 -0
  12. package/dist/cjs/Tracer.js +1 -15
  13. package/dist/cjs/Tracer.js.map +1 -1
  14. package/dist/cjs/Utils.js +1 -1
  15. package/dist/cjs/Utils.js.map +1 -1
  16. package/dist/cjs/index.js +3 -1
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/internal/clock.js +1 -1
  19. package/dist/cjs/internal/clock.js.map +1 -1
  20. package/dist/cjs/internal/core.js +17 -50
  21. package/dist/cjs/internal/core.js.map +1 -1
  22. package/dist/cjs/internal/effect/circular.js +18 -30
  23. package/dist/cjs/internal/effect/circular.js.map +1 -1
  24. package/dist/cjs/internal/fiberRuntime.js +16 -65
  25. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  26. package/dist/cjs/internal/layer/circular.js +1 -5
  27. package/dist/cjs/internal/layer/circular.js.map +1 -1
  28. package/dist/cjs/internal/layer.js +1 -3
  29. package/dist/cjs/internal/layer.js.map +1 -1
  30. package/dist/cjs/internal/logger.js +25 -2
  31. package/dist/cjs/internal/logger.js.map +1 -1
  32. package/dist/cjs/internal/runtimeFlags.js +2 -11
  33. package/dist/cjs/internal/runtimeFlags.js.map +1 -1
  34. package/dist/cjs/internal/tracer.js +1 -114
  35. package/dist/cjs/internal/tracer.js.map +1 -1
  36. package/dist/dts/Config.d.ts +2 -2
  37. package/dist/dts/Config.d.ts.map +1 -1
  38. package/dist/dts/Effect.d.ts +8 -29
  39. package/dist/dts/Effect.d.ts.map +1 -1
  40. package/dist/dts/FiberRef.d.ts +12 -0
  41. package/dist/dts/FiberRef.d.ts.map +1 -1
  42. package/dist/dts/Layer.d.ts +0 -22
  43. package/dist/dts/Layer.d.ts.map +1 -1
  44. package/dist/dts/RuntimeFlags.d.ts +0 -28
  45. package/dist/dts/RuntimeFlags.d.ts.map +1 -1
  46. package/dist/dts/SourceLocation.d.ts +88 -0
  47. package/dist/dts/SourceLocation.d.ts.map +1 -0
  48. package/dist/dts/Tracer.d.ts +0 -15
  49. package/dist/dts/Tracer.d.ts.map +1 -1
  50. package/dist/dts/index.d.ts +6 -0
  51. package/dist/dts/index.d.ts.map +1 -1
  52. package/dist/dts/internal/core.d.ts.map +1 -1
  53. package/dist/dts/internal/layer.d.ts.map +1 -1
  54. package/dist/dts/internal/runtimeFlags.d.ts.map +1 -1
  55. package/dist/esm/Effect.js +0 -26
  56. package/dist/esm/Effect.js.map +1 -1
  57. package/dist/esm/FiberRef.js +11 -0
  58. package/dist/esm/FiberRef.js.map +1 -1
  59. package/dist/esm/Layer.js +0 -22
  60. package/dist/esm/Layer.js.map +1 -1
  61. package/dist/esm/RuntimeFlags.js +0 -28
  62. package/dist/esm/RuntimeFlags.js.map +1 -1
  63. package/dist/esm/SourceLocation.js +51 -0
  64. package/dist/esm/SourceLocation.js.map +1 -0
  65. package/dist/esm/Tracer.js +0 -14
  66. package/dist/esm/Tracer.js.map +1 -1
  67. package/dist/esm/Utils.js +1 -1
  68. package/dist/esm/Utils.js.map +1 -1
  69. package/dist/esm/index.js +6 -0
  70. package/dist/esm/index.js.map +1 -1
  71. package/dist/esm/internal/clock.js +1 -1
  72. package/dist/esm/internal/clock.js.map +1 -1
  73. package/dist/esm/internal/core.js +12 -45
  74. package/dist/esm/internal/core.js.map +1 -1
  75. package/dist/esm/internal/effect/circular.js +18 -30
  76. package/dist/esm/internal/effect/circular.js.map +1 -1
  77. package/dist/esm/internal/fiberRuntime.js +13 -60
  78. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  79. package/dist/esm/internal/layer/circular.js +0 -4
  80. package/dist/esm/internal/layer/circular.js.map +1 -1
  81. package/dist/esm/internal/layer.js +0 -2
  82. package/dist/esm/internal/layer.js.map +1 -1
  83. package/dist/esm/internal/logger.js +25 -2
  84. package/dist/esm/internal/logger.js.map +1 -1
  85. package/dist/esm/internal/runtimeFlags.js +1 -9
  86. package/dist/esm/internal/runtimeFlags.js.map +1 -1
  87. package/dist/esm/internal/tracer.js +0 -111
  88. package/dist/esm/internal/tracer.js.map +1 -1
  89. package/package.json +12 -1
  90. package/src/Arbitrary.ts +1101 -0
  91. package/src/Array.ts +3589 -0
  92. package/src/BigDecimal.ts +1349 -0
  93. package/src/BigInt.ts +643 -0
  94. package/src/Boolean.ts +287 -0
  95. package/src/Brand.ts +360 -0
  96. package/src/Cache.ts +281 -0
  97. package/src/Cause.ts +1555 -0
  98. package/src/Channel.ts +2355 -0
  99. package/src/ChildExecutorDecision.ts +146 -0
  100. package/src/Chunk.ts +1495 -0
  101. package/src/Clock.ts +111 -0
  102. package/src/Config.ts +542 -0
  103. package/src/ConfigError.ts +270 -0
  104. package/src/ConfigProvider.ts +333 -0
  105. package/src/ConfigProviderPathPatch.ts +100 -0
  106. package/src/Console.ts +226 -0
  107. package/src/Context.ts +585 -0
  108. package/src/Cron.ts +706 -0
  109. package/src/Data.ts +596 -0
  110. package/src/DateTime.ts +1686 -0
  111. package/src/DefaultServices.ts +34 -0
  112. package/src/Deferred.ts +301 -0
  113. package/src/Differ.ts +450 -0
  114. package/src/Duration.ts +1000 -0
  115. package/src/Effect.ts +14817 -0
  116. package/src/Effectable.ts +107 -0
  117. package/src/Either.ts +1040 -0
  118. package/src/Encoding.ts +195 -0
  119. package/src/Equal.ts +98 -0
  120. package/src/Equivalence.ts +235 -0
  121. package/src/ExecutionPlan.ts +308 -0
  122. package/src/ExecutionStrategy.ts +119 -0
  123. package/src/Exit.ts +467 -0
  124. package/src/FastCheck.ts +9 -0
  125. package/src/Fiber.ts +744 -0
  126. package/src/FiberHandle.ts +540 -0
  127. package/src/FiberId.ts +195 -0
  128. package/src/FiberMap.ts +656 -0
  129. package/src/FiberRef.ts +444 -0
  130. package/src/FiberRefs.ts +204 -0
  131. package/src/FiberRefsPatch.ts +105 -0
  132. package/src/FiberSet.ts +491 -0
  133. package/src/FiberStatus.ts +108 -0
  134. package/src/Function.ts +1222 -0
  135. package/src/GlobalValue.ts +53 -0
  136. package/src/Graph.ts +3732 -0
  137. package/src/GroupBy.ts +103 -0
  138. package/src/HKT.ts +45 -0
  139. package/src/Hash.ts +195 -0
  140. package/src/HashMap.ts +519 -0
  141. package/src/HashRing.ts +317 -0
  142. package/src/HashSet.ts +2346 -0
  143. package/src/Inspectable.ts +287 -0
  144. package/src/Iterable.ts +1119 -0
  145. package/src/JSONSchema.ts +1044 -0
  146. package/src/KeyedPool.ts +167 -0
  147. package/src/Layer.ts +1228 -0
  148. package/src/LayerMap.ts +436 -0
  149. package/src/List.ts +977 -0
  150. package/src/LogLevel.ts +285 -0
  151. package/src/LogSpan.ts +25 -0
  152. package/src/Logger.ts +702 -0
  153. package/src/Mailbox.ts +268 -0
  154. package/src/ManagedRuntime.ts +180 -0
  155. package/src/Match.ts +1477 -0
  156. package/src/MergeDecision.ts +95 -0
  157. package/src/MergeState.ts +172 -0
  158. package/src/MergeStrategy.ts +107 -0
  159. package/src/Metric.ts +780 -0
  160. package/src/MetricBoundaries.ts +69 -0
  161. package/src/MetricHook.ts +151 -0
  162. package/src/MetricKey.ts +224 -0
  163. package/src/MetricKeyType.ts +262 -0
  164. package/src/MetricLabel.ts +47 -0
  165. package/src/MetricPair.ts +71 -0
  166. package/src/MetricPolling.ts +148 -0
  167. package/src/MetricRegistry.ts +48 -0
  168. package/src/MetricState.ts +257 -0
  169. package/src/Micro.ts +4405 -0
  170. package/src/ModuleVersion.ts +18 -0
  171. package/src/MutableHashMap.ts +411 -0
  172. package/src/MutableHashSet.ts +706 -0
  173. package/src/MutableList.ts +297 -0
  174. package/src/MutableQueue.ts +227 -0
  175. package/src/MutableRef.ts +202 -0
  176. package/src/NonEmptyIterable.ts +32 -0
  177. package/src/Number.ts +1071 -0
  178. package/src/Option.ts +2170 -0
  179. package/src/Order.ts +373 -0
  180. package/src/Ordering.ts +111 -0
  181. package/src/ParseResult.ts +2031 -0
  182. package/src/PartitionedSemaphore.ts +200 -0
  183. package/src/Pipeable.ts +566 -0
  184. package/src/Pool.ts +204 -0
  185. package/src/Predicate.ts +1405 -0
  186. package/src/Pretty.ts +205 -0
  187. package/src/PrimaryKey.ts +23 -0
  188. package/src/PubSub.ts +182 -0
  189. package/src/Queue.ts +644 -0
  190. package/src/Random.ts +204 -0
  191. package/src/RateLimiter.ts +138 -0
  192. package/src/RcMap.ts +141 -0
  193. package/src/RcRef.ts +122 -0
  194. package/src/Readable.ts +93 -0
  195. package/src/Record.ts +1274 -0
  196. package/src/RedBlackTree.ts +421 -0
  197. package/src/Redacted.ts +144 -0
  198. package/src/Ref.ts +180 -0
  199. package/src/RegExp.ts +38 -0
  200. package/src/Reloadable.ts +127 -0
  201. package/src/Request.ts +347 -0
  202. package/src/RequestBlock.ts +118 -0
  203. package/src/RequestResolver.ts +366 -0
  204. package/src/Resource.ts +119 -0
  205. package/src/Runtime.ts +383 -0
  206. package/src/RuntimeFlags.ts +336 -0
  207. package/src/RuntimeFlagsPatch.ts +183 -0
  208. package/src/STM.ts +2045 -0
  209. package/src/Schedule.ts +2219 -0
  210. package/src/ScheduleDecision.ts +62 -0
  211. package/src/ScheduleInterval.ts +151 -0
  212. package/src/ScheduleIntervals.ts +122 -0
  213. package/src/Scheduler.ts +353 -0
  214. package/src/Schema.ts +10914 -0
  215. package/src/SchemaAST.ts +3043 -0
  216. package/src/Scope.ts +204 -0
  217. package/src/ScopedCache.ts +151 -0
  218. package/src/ScopedRef.ts +117 -0
  219. package/src/Secret.ts +88 -0
  220. package/src/SingleProducerAsyncInput.ts +67 -0
  221. package/src/Sink.ts +1461 -0
  222. package/src/SortedMap.ts +287 -0
  223. package/src/SortedSet.ts +390 -0
  224. package/src/SourceLocation.ts +108 -0
  225. package/src/Stream.ts +6468 -0
  226. package/src/StreamEmit.ts +136 -0
  227. package/src/StreamHaltStrategy.ts +123 -0
  228. package/src/Streamable.ts +45 -0
  229. package/src/String.ts +778 -0
  230. package/src/Struct.ts +243 -0
  231. package/src/Subscribable.ts +100 -0
  232. package/src/SubscriptionRef.ts +298 -0
  233. package/src/Supervisor.ts +240 -0
  234. package/src/Symbol.ts +29 -0
  235. package/src/SynchronizedRef.ts +270 -0
  236. package/src/TArray.ts +495 -0
  237. package/src/TDeferred.ts +100 -0
  238. package/src/TMap.ts +515 -0
  239. package/src/TPriorityQueue.ts +223 -0
  240. package/src/TPubSub.ts +200 -0
  241. package/src/TQueue.ts +432 -0
  242. package/src/TRandom.ts +129 -0
  243. package/src/TReentrantLock.ts +224 -0
  244. package/src/TRef.ts +178 -0
  245. package/src/TSemaphore.ts +129 -0
  246. package/src/TSet.ts +365 -0
  247. package/src/TSubscriptionRef.ts +192 -0
  248. package/src/Take.ts +258 -0
  249. package/src/TestAnnotation.ts +158 -0
  250. package/src/TestAnnotationMap.ts +119 -0
  251. package/src/TestAnnotations.ts +117 -0
  252. package/src/TestClock.ts +556 -0
  253. package/src/TestConfig.ts +47 -0
  254. package/src/TestContext.ts +36 -0
  255. package/src/TestLive.ts +53 -0
  256. package/src/TestServices.ts +390 -0
  257. package/src/TestSized.ts +55 -0
  258. package/src/Tracer.ts +182 -0
  259. package/src/Trie.ts +840 -0
  260. package/src/Tuple.ts +305 -0
  261. package/src/Types.ts +353 -0
  262. package/src/Unify.ts +113 -0
  263. package/src/UpstreamPullRequest.ts +117 -0
  264. package/src/UpstreamPullStrategy.ts +121 -0
  265. package/src/Utils.ts +809 -0
  266. package/src/index.ts +1568 -0
  267. package/src/internal/array.ts +8 -0
  268. package/src/internal/blockedRequests.ts +520 -0
  269. package/src/internal/cache.ts +733 -0
  270. package/src/internal/cause.ts +1050 -0
  271. package/src/internal/channel/channelExecutor.ts +1200 -0
  272. package/src/internal/channel/channelState.ts +134 -0
  273. package/src/internal/channel/childExecutorDecision.ts +96 -0
  274. package/src/internal/channel/continuation.ts +200 -0
  275. package/src/internal/channel/mergeDecision.ts +113 -0
  276. package/src/internal/channel/mergeState.ts +120 -0
  277. package/src/internal/channel/mergeStrategy.ts +72 -0
  278. package/src/internal/channel/singleProducerAsyncInput.ts +259 -0
  279. package/src/internal/channel/subexecutor.ts +229 -0
  280. package/src/internal/channel/upstreamPullRequest.ts +84 -0
  281. package/src/internal/channel/upstreamPullStrategy.ts +87 -0
  282. package/src/internal/channel.ts +2603 -0
  283. package/src/internal/clock.ts +95 -0
  284. package/src/internal/completedRequestMap.ts +9 -0
  285. package/src/internal/concurrency.ts +54 -0
  286. package/src/internal/config.ts +716 -0
  287. package/src/internal/configError.ts +304 -0
  288. package/src/internal/configProvider/pathPatch.ts +97 -0
  289. package/src/internal/configProvider.ts +799 -0
  290. package/src/internal/console.ts +153 -0
  291. package/src/internal/context.ts +337 -0
  292. package/src/internal/core-effect.ts +2293 -0
  293. package/src/internal/core-stream.ts +998 -0
  294. package/src/internal/core.ts +3189 -0
  295. package/src/internal/data.ts +36 -0
  296. package/src/internal/dataSource.ts +327 -0
  297. package/src/internal/dateTime.ts +1277 -0
  298. package/src/internal/defaultServices/console.ts +100 -0
  299. package/src/internal/defaultServices.ts +163 -0
  300. package/src/internal/deferred.ts +46 -0
  301. package/src/internal/differ/chunkPatch.ts +211 -0
  302. package/src/internal/differ/contextPatch.ts +232 -0
  303. package/src/internal/differ/hashMapPatch.ts +220 -0
  304. package/src/internal/differ/hashSetPatch.ts +176 -0
  305. package/src/internal/differ/orPatch.ts +311 -0
  306. package/src/internal/differ/readonlyArrayPatch.ts +210 -0
  307. package/src/internal/differ.ts +200 -0
  308. package/src/internal/doNotation.ts +80 -0
  309. package/src/internal/effect/circular.ts +895 -0
  310. package/src/internal/effectable.ts +131 -0
  311. package/src/internal/either.ts +110 -0
  312. package/src/internal/encoding/base64.ts +286 -0
  313. package/src/internal/encoding/base64Url.ts +29 -0
  314. package/src/internal/encoding/common.ts +51 -0
  315. package/src/internal/encoding/hex.ts +315 -0
  316. package/src/internal/errors.ts +7 -0
  317. package/src/internal/executionPlan.ts +114 -0
  318. package/src/internal/executionStrategy.ts +74 -0
  319. package/src/internal/fiber.ts +388 -0
  320. package/src/internal/fiberId.ts +267 -0
  321. package/src/internal/fiberMessage.ts +82 -0
  322. package/src/internal/fiberRefs/patch.ts +144 -0
  323. package/src/internal/fiberRefs.ts +297 -0
  324. package/src/internal/fiberRuntime.ts +3842 -0
  325. package/src/internal/fiberScope.ts +71 -0
  326. package/src/internal/fiberStatus.ts +119 -0
  327. package/src/internal/groupBy.ts +530 -0
  328. package/src/internal/hashMap/array.ts +49 -0
  329. package/src/internal/hashMap/bitwise.ts +32 -0
  330. package/src/internal/hashMap/config.ts +14 -0
  331. package/src/internal/hashMap/keySet.ts +8 -0
  332. package/src/internal/hashMap/node.ts +391 -0
  333. package/src/internal/hashMap.ts +586 -0
  334. package/src/internal/hashSet.ts +323 -0
  335. package/src/internal/keyedPool.ts +244 -0
  336. package/src/internal/layer/circular.ts +214 -0
  337. package/src/internal/layer.ts +1483 -0
  338. package/src/internal/logSpan.ts +20 -0
  339. package/src/internal/logger-circular.ts +24 -0
  340. package/src/internal/logger.ts +522 -0
  341. package/src/internal/mailbox.ts +561 -0
  342. package/src/internal/managedRuntime/circular.ts +6 -0
  343. package/src/internal/managedRuntime.ts +134 -0
  344. package/src/internal/matcher.ts +652 -0
  345. package/src/internal/metric/boundaries.ts +75 -0
  346. package/src/internal/metric/hook.ts +483 -0
  347. package/src/internal/metric/key.ts +167 -0
  348. package/src/internal/metric/keyType.ts +238 -0
  349. package/src/internal/metric/label.ts +41 -0
  350. package/src/internal/metric/pair.ts +48 -0
  351. package/src/internal/metric/polling.ts +149 -0
  352. package/src/internal/metric/registry.ts +187 -0
  353. package/src/internal/metric/state.ts +290 -0
  354. package/src/internal/metric.ts +577 -0
  355. package/src/internal/opCodes/cause.ts +35 -0
  356. package/src/internal/opCodes/channel.ts +83 -0
  357. package/src/internal/opCodes/channelChildExecutorDecision.ts +17 -0
  358. package/src/internal/opCodes/channelMergeDecision.ts +11 -0
  359. package/src/internal/opCodes/channelMergeState.ts +17 -0
  360. package/src/internal/opCodes/channelMergeStrategy.ts +11 -0
  361. package/src/internal/opCodes/channelState.ts +23 -0
  362. package/src/internal/opCodes/channelUpstreamPullRequest.ts +11 -0
  363. package/src/internal/opCodes/channelUpstreamPullStrategy.ts +11 -0
  364. package/src/internal/opCodes/config.ts +65 -0
  365. package/src/internal/opCodes/configError.ts +35 -0
  366. package/src/internal/opCodes/continuation.ts +11 -0
  367. package/src/internal/opCodes/deferred.ts +11 -0
  368. package/src/internal/opCodes/effect.ts +89 -0
  369. package/src/internal/opCodes/layer.ts +59 -0
  370. package/src/internal/opCodes/streamHaltStrategy.ts +23 -0
  371. package/src/internal/option.ts +80 -0
  372. package/src/internal/pool.ts +432 -0
  373. package/src/internal/pubsub.ts +1762 -0
  374. package/src/internal/query.ts +204 -0
  375. package/src/internal/queue.ts +766 -0
  376. package/src/internal/random.ts +161 -0
  377. package/src/internal/rateLimiter.ts +93 -0
  378. package/src/internal/rcMap.ts +285 -0
  379. package/src/internal/rcRef.ts +192 -0
  380. package/src/internal/redBlackTree/iterator.ts +200 -0
  381. package/src/internal/redBlackTree/node.ts +68 -0
  382. package/src/internal/redBlackTree.ts +1245 -0
  383. package/src/internal/redacted.ts +73 -0
  384. package/src/internal/ref.ts +171 -0
  385. package/src/internal/reloadable.ts +140 -0
  386. package/src/internal/request.ts +177 -0
  387. package/src/internal/resource.ts +76 -0
  388. package/src/internal/ringBuffer.ts +68 -0
  389. package/src/internal/runtime.ts +558 -0
  390. package/src/internal/runtimeFlags.ts +178 -0
  391. package/src/internal/runtimeFlagsPatch.ts +103 -0
  392. package/src/internal/schedule/decision.ts +47 -0
  393. package/src/internal/schedule/interval.ts +101 -0
  394. package/src/internal/schedule/intervals.ts +180 -0
  395. package/src/internal/schedule.ts +2199 -0
  396. package/src/internal/schema/errors.ts +191 -0
  397. package/src/internal/schema/schemaId.ts +106 -0
  398. package/src/internal/schema/util.ts +50 -0
  399. package/src/internal/scopedCache.ts +644 -0
  400. package/src/internal/scopedRef.ts +118 -0
  401. package/src/internal/secret.ts +89 -0
  402. package/src/internal/singleShotGen.ts +35 -0
  403. package/src/internal/sink.ts +2120 -0
  404. package/src/internal/stack.ts +10 -0
  405. package/src/internal/stm/core.ts +817 -0
  406. package/src/internal/stm/entry.ts +59 -0
  407. package/src/internal/stm/journal.ts +123 -0
  408. package/src/internal/stm/opCodes/stm.ts +71 -0
  409. package/src/internal/stm/opCodes/stmState.ts +17 -0
  410. package/src/internal/stm/opCodes/strategy.ts +17 -0
  411. package/src/internal/stm/opCodes/tExit.ts +29 -0
  412. package/src/internal/stm/opCodes/tryCommit.ts +11 -0
  413. package/src/internal/stm/stm.ts +1453 -0
  414. package/src/internal/stm/stmState.ts +136 -0
  415. package/src/internal/stm/tArray.ts +550 -0
  416. package/src/internal/stm/tDeferred.ts +81 -0
  417. package/src/internal/stm/tExit.ts +190 -0
  418. package/src/internal/stm/tMap.ts +824 -0
  419. package/src/internal/stm/tPriorityQueue.ts +267 -0
  420. package/src/internal/stm/tPubSub.ts +551 -0
  421. package/src/internal/stm/tQueue.ts +393 -0
  422. package/src/internal/stm/tRandom.ts +140 -0
  423. package/src/internal/stm/tReentrantLock.ts +352 -0
  424. package/src/internal/stm/tRef.ts +195 -0
  425. package/src/internal/stm/tSemaphore.ts +113 -0
  426. package/src/internal/stm/tSet.ts +259 -0
  427. package/src/internal/stm/tSubscriptionRef.ts +286 -0
  428. package/src/internal/stm/tryCommit.ts +34 -0
  429. package/src/internal/stm/txnId.ts +14 -0
  430. package/src/internal/stm/versioned.ts +4 -0
  431. package/src/internal/stream/debounceState.ts +57 -0
  432. package/src/internal/stream/emit.ts +123 -0
  433. package/src/internal/stream/haltStrategy.ts +94 -0
  434. package/src/internal/stream/handoff.ts +187 -0
  435. package/src/internal/stream/handoffSignal.ts +59 -0
  436. package/src/internal/stream/pull.ts +34 -0
  437. package/src/internal/stream/sinkEndReason.ts +30 -0
  438. package/src/internal/stream/zipAllState.ts +88 -0
  439. package/src/internal/stream/zipChunksState.ts +56 -0
  440. package/src/internal/stream.ts +8801 -0
  441. package/src/internal/string-utils.ts +107 -0
  442. package/src/internal/subscriptionRef.ts +138 -0
  443. package/src/internal/supervisor/patch.ts +190 -0
  444. package/src/internal/supervisor.ts +303 -0
  445. package/src/internal/synchronizedRef.ts +114 -0
  446. package/src/internal/take.ts +199 -0
  447. package/src/internal/testing/sleep.ts +27 -0
  448. package/src/internal/testing/suspendedWarningData.ts +85 -0
  449. package/src/internal/testing/warningData.ts +94 -0
  450. package/src/internal/tracer.ts +150 -0
  451. package/src/internal/trie.ts +722 -0
  452. package/src/internal/version.ts +7 -0
@@ -0,0 +1,1405 @@
1
+ /**
2
+ * This module provides a collection of functions for working with predicates and refinements.
3
+ *
4
+ * A `Predicate<A>` is a function that takes a value of type `A` and returns a boolean.
5
+ * It is used to check if a value satisfies a certain condition.
6
+ *
7
+ * A `Refinement<A, B>` is a special type of predicate that not only checks a condition
8
+ * but also provides a type guard, allowing TypeScript to narrow the type of the input
9
+ * value from `A` to a more specific type `B` within a conditional block.
10
+ *
11
+ * The module includes:
12
+ * - Basic predicates and refinements for common types (e.g., `isString`, `isNumber`).
13
+ * - Combinators to create new predicates from existing ones (e.g., `and`, `or`, `not`).
14
+ * - Advanced combinators for working with data structures (e.g., `tuple`, `struct`).
15
+ * - Type-level utilities for inspecting predicate and refinement types.
16
+ *
17
+ * @since 2.0.0
18
+ */
19
+ import { dual, isFunction as isFunction_ } from "./Function.js"
20
+ import type { TypeLambda } from "./HKT.js"
21
+ import type { TupleOf, TupleOfAtLeast } from "./Types.js"
22
+
23
+ /**
24
+ * Represents a function that takes a value of type `A` and returns `true` if the value
25
+ * satisfies some condition, `false` otherwise.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * import { Predicate } from "effect"
30
+ * import * as assert from "node:assert"
31
+ *
32
+ * const isEven: Predicate.Predicate<number> = (n) => n % 2 === 0
33
+ *
34
+ * assert.strictEqual(isEven(2), true)
35
+ * assert.strictEqual(isEven(3), false)
36
+ * ```
37
+ *
38
+ * @category models
39
+ * @since 2.0.0
40
+ */
41
+ export interface Predicate<in A> {
42
+ (a: A): boolean
43
+ }
44
+
45
+ /**
46
+ * A `TypeLambda` for `Predicate`. This is used to support higher-kinded types
47
+ * and allows `Predicate` to be used in generic contexts within the `effect` ecosystem.
48
+ *
49
+ * @category type lambdas
50
+ * @since 2.0.0
51
+ */
52
+ export interface PredicateTypeLambda extends TypeLambda {
53
+ readonly type: Predicate<this["Target"]>
54
+ }
55
+
56
+ /**
57
+ * Represents a function that serves as a type guard.
58
+ *
59
+ * A `Refinement<A, B>` is a function that takes a value of type `A` and returns a
60
+ * type predicate `a is B`, where `B` is a subtype of `A`. If the function returns
61
+ * `true`, TypeScript will narrow the type of the input variable to `B`.
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * import { Predicate } from "effect"
66
+ * import * as assert from "node:assert"
67
+ *
68
+ * const isString: Predicate.Refinement<unknown, string> = (u): u is string => typeof u === "string"
69
+ *
70
+ * const value: unknown = "hello"
71
+ *
72
+ * if (isString(value)) {
73
+ * // value is now known to be a string
74
+ * assert.strictEqual(value.toUpperCase(), "HELLO")
75
+ * }
76
+ * ```
77
+ *
78
+ * @category models
79
+ * @since 2.0.0
80
+ */
81
+ export interface Refinement<in A, out B extends A> {
82
+ (a: A): a is B
83
+ }
84
+
85
+ /**
86
+ * A namespace for type-level utilities for `Predicate`.
87
+ *
88
+ * @since 3.6.0
89
+ * @category type-level
90
+ */
91
+ export declare namespace Predicate {
92
+ /**
93
+ * Extracts the input type `A` from a `Predicate<A>`.
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * import { type Predicate } from "effect"
98
+ *
99
+ * type T = Predicate.Predicate.In<Predicate.Predicate<string>> // T is string
100
+ * ```
101
+ *
102
+ * @since 3.6.0
103
+ * @category type-level
104
+ */
105
+ export type In<T extends Any> = [T] extends [Predicate<infer _A>] ? _A : never
106
+ /**
107
+ * A type representing any `Predicate`.
108
+ *
109
+ * @since 3.6.0
110
+ * @category type-level
111
+ */
112
+ export type Any = Predicate<never>
113
+ }
114
+
115
+ /**
116
+ * A namespace for type-level utilities for `Refinement`.
117
+ *
118
+ * @since 3.6.0
119
+ * @category type-level
120
+ */
121
+ export declare namespace Refinement {
122
+ /**
123
+ * Extracts the input type `A` from a `Refinement<A, B>`.
124
+ *
125
+ * @example
126
+ * ```ts
127
+ * import { type Predicate } from "effect"
128
+ *
129
+ * type IsString = Predicate.Refinement<unknown, string>
130
+ * type T = Predicate.Refinement.In<IsString> // T is unknown
131
+ * ```
132
+ *
133
+ * @since 3.6.0
134
+ * @category type-level
135
+ */
136
+ export type In<T extends Any> = [T] extends [Refinement<infer _A, infer _>] ? _A : never
137
+ /**
138
+ * Extracts the output (refined) type `B` from a `Refinement<A, B>`.
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * import { type Predicate } from "effect"
143
+ *
144
+ * type IsString = Predicate.Refinement<unknown, string>
145
+ * type T = Predicate.Refinement.Out<IsString> // T is string
146
+ * ```
147
+ *
148
+ * @since 3.6.0
149
+ * @category type-level
150
+ */
151
+ export type Out<T extends Any> = [T] extends [Refinement<infer _, infer _B>] ? _B : never
152
+ /**
153
+ * A type representing any `Refinement`.
154
+ *
155
+ * @since 3.6.0
156
+ * @category type-level
157
+ */
158
+ export type Any = Refinement<any, any>
159
+ }
160
+
161
+ /**
162
+ * Transforms a `Predicate<A>` into a `Predicate<B>` by applying a function `(b: B) => A`
163
+ * to the input before passing it to the predicate. This is also known as "contramap" or
164
+ * "pre-composition".
165
+ *
166
+ * @example
167
+ * ```ts
168
+ * import { Predicate, Number } from "effect"
169
+ * import * as assert from "node:assert"
170
+ *
171
+ * // A predicate on numbers
172
+ * const isPositive: Predicate.Predicate<number> = Number.greaterThan(0)
173
+ *
174
+ * // A function from `string` to `number`
175
+ * const stringLength = (s: string): number => s.length
176
+ *
177
+ * // Create a new predicate on strings by mapping the input
178
+ * const hasPositiveLength = Predicate.mapInput(isPositive, stringLength)
179
+ *
180
+ * assert.strictEqual(hasPositiveLength("hello"), true)
181
+ * assert.strictEqual(hasPositiveLength(""), false)
182
+ * ```
183
+ *
184
+ * @category combinators
185
+ * @since 2.0.0
186
+ */
187
+ export const mapInput: {
188
+ <B, A>(f: (b: B) => A): (self: Predicate<A>) => Predicate<B>
189
+ <A, B>(self: Predicate<A>, f: (b: B) => A): Predicate<B>
190
+ } = dual(2, <A, B>(self: Predicate<A>, f: (b: B) => A): Predicate<B> => (b) => self(f(b)))
191
+
192
+ /**
193
+ * A refinement that checks if a `ReadonlyArray<T>` is a tuple with exactly `N` elements.
194
+ * If the check is successful, the type is narrowed to `TupleOf<N, T>`.
195
+ *
196
+ * @example
197
+ * ```ts
198
+ * import * as assert from "node:assert"
199
+ * import { isTupleOf } from "effect/Predicate"
200
+ *
201
+ * const isTupleOf3 = isTupleOf(3)
202
+ *
203
+ * assert.strictEqual(isTupleOf3([1, 2, 3]), true);
204
+ * assert.strictEqual(isTupleOf3([1, 2]), false);
205
+ *
206
+ * const arr: number[] = [1, 2, 3];
207
+ * if (isTupleOf(arr, 3)) {
208
+ * // The type of arr is now [number, number, number]
209
+ * const [a, b, c] = arr;
210
+ * assert.deepStrictEqual([a, b, c], [1, 2, 3])
211
+ * }
212
+ * ```
213
+ *
214
+ * @category guards
215
+ * @since 3.3.0
216
+ */
217
+ export const isTupleOf: {
218
+ <N extends number>(n: N): <T>(self: ReadonlyArray<T>) => self is TupleOf<N, T>
219
+ <T, N extends number>(self: ReadonlyArray<T>, n: N): self is TupleOf<N, T>
220
+ } = dual(2, <T, N extends number>(self: ReadonlyArray<T>, n: N): self is TupleOf<N, T> => self.length === n)
221
+
222
+ /**
223
+ * A refinement that checks if a `ReadonlyArray<T>` is a tuple with at least `N` elements.
224
+ * If the check is successful, the type is narrowed to `TupleOfAtLeast<N, T>`.
225
+ *
226
+ * @example
227
+ * ```ts
228
+ * import * as assert from "node:assert"
229
+ * import { isTupleOfAtLeast } from "effect/Predicate"
230
+ *
231
+ * const isTupleOfAtLeast3 = isTupleOfAtLeast(3)
232
+ *
233
+ * assert.strictEqual(isTupleOfAtLeast3([1, 2, 3]), true);
234
+ * assert.strictEqual(isTupleOfAtLeast3([1, 2, 3, 4]), true);
235
+ * assert.strictEqual(isTupleOfAtLeast3([1, 2]), false);
236
+ *
237
+ * const arr: number[] = [1, 2, 3, 4];
238
+ * if (isTupleOfAtLeast(arr, 3)) {
239
+ * // The type of arr is now [number, number, number, ...number[]]
240
+ * const [a, b, c] = arr;
241
+ * assert.deepStrictEqual([a, b, c], [1, 2, 3])
242
+ * }
243
+ * ```
244
+ *
245
+ * @category guards
246
+ * @since 3.3.0
247
+ */
248
+ export const isTupleOfAtLeast: {
249
+ <N extends number>(n: N): <T>(self: ReadonlyArray<T>) => self is TupleOfAtLeast<N, T>
250
+ <T, N extends number>(self: ReadonlyArray<T>, n: N): self is TupleOfAtLeast<N, T>
251
+ } = dual(2, <T, N extends number>(self: ReadonlyArray<T>, n: N): self is TupleOfAtLeast<N, T> => self.length >= n)
252
+
253
+ /**
254
+ * A predicate that checks if a value is "truthy" in JavaScript.
255
+ * Fails for `false`, `0`, `-0`, `0n`, `""`, `null`, `undefined`, and `NaN`.
256
+ *
257
+ * @example
258
+ * ```ts
259
+ * import * as assert from "node:assert"
260
+ * import { isTruthy } from "effect/Predicate"
261
+ *
262
+ * assert.strictEqual(isTruthy(1), true)
263
+ * assert.strictEqual(isTruthy("hello"), true)
264
+ * assert.strictEqual(isTruthy({}), true)
265
+ *
266
+ * assert.strictEqual(isTruthy(0), false)
267
+ * assert.strictEqual(isTruthy(""), false)
268
+ * assert.strictEqual(isTruthy(null), false)
269
+ * assert.strictEqual(isTruthy(undefined), false)
270
+ * ```
271
+ *
272
+ * @category guards
273
+ * @since 2.0.0
274
+ */
275
+ export const isTruthy = (input: unknown) => !!input
276
+
277
+ /**
278
+ * A refinement that checks if a value is a `Set`.
279
+ *
280
+ * @example
281
+ * ```ts
282
+ * import * as assert from "node:assert"
283
+ * import { isSet } from "effect/Predicate"
284
+ *
285
+ * assert.strictEqual(isSet(new Set([1, 2])), true)
286
+ * assert.strictEqual(isSet(new Set()), true)
287
+ *
288
+ * assert.strictEqual(isSet({}), false)
289
+ * assert.strictEqual(isSet([1, 2]), false)
290
+ * ```
291
+ *
292
+ * @category guards
293
+ * @since 2.0.0
294
+ */
295
+ export const isSet = (input: unknown): input is Set<unknown> => input instanceof Set
296
+
297
+ /**
298
+ * A refinement that checks if a value is a `Map`.
299
+ *
300
+ * @example
301
+ * ```ts
302
+ * import * as assert from "node:assert"
303
+ * import { isMap } from "effect/Predicate"
304
+ *
305
+ * assert.strictEqual(isMap(new Map()), true)
306
+ *
307
+ * assert.strictEqual(isMap({}), false)
308
+ * assert.strictEqual(isMap(new Set()), false)
309
+ * ```
310
+ *
311
+ * @category guards
312
+ * @since 2.0.0
313
+ */
314
+ export const isMap = (input: unknown): input is Map<unknown, unknown> => input instanceof Map
315
+
316
+ /**
317
+ * A refinement that checks if a value is a `string`.
318
+ *
319
+ * @example
320
+ * ```ts
321
+ * import * as assert from "node:assert"
322
+ * import { isString } from "effect/Predicate"
323
+ *
324
+ * assert.strictEqual(isString("hello"), true)
325
+ * assert.strictEqual(isString(""), true)
326
+ *
327
+ * assert.strictEqual(isString(123), false)
328
+ * assert.strictEqual(isString(null), false)
329
+ * ```
330
+ *
331
+ * @category guards
332
+ * @since 2.0.0
333
+ */
334
+ export const isString = (input: unknown): input is string => typeof input === "string"
335
+
336
+ /**
337
+ * A refinement that checks if a value is a `number`.
338
+ *
339
+ * @example
340
+ * ```ts
341
+ * import * as assert from "node:assert"
342
+ * import { isNumber } from "effect/Predicate"
343
+ *
344
+ * assert.strictEqual(isNumber(123), true)
345
+ * assert.strictEqual(isNumber(0), true)
346
+ * assert.strictEqual(isNumber(-1.5), true)
347
+ * assert.strictEqual(isNumber(NaN), true)
348
+ *
349
+ * assert.strictEqual(isNumber("123"), false)
350
+ * ```
351
+ *
352
+ * @category guards
353
+ * @since 2.0.0
354
+ */
355
+ export const isNumber = (input: unknown): input is number => typeof input === "number"
356
+
357
+ /**
358
+ * A refinement that checks if a value is a `boolean`.
359
+ *
360
+ * @example
361
+ * ```ts
362
+ * import * as assert from "node:assert"
363
+ * import { isBoolean } from "effect/Predicate"
364
+ *
365
+ * assert.strictEqual(isBoolean(true), true)
366
+ * assert.strictEqual(isBoolean(false), true)
367
+ *
368
+ * assert.strictEqual(isBoolean("true"), false)
369
+ * assert.strictEqual(isBoolean(0), false)
370
+ * ```
371
+ *
372
+ * @category guards
373
+ * @since 2.0.0
374
+ */
375
+ export const isBoolean = (input: unknown): input is boolean => typeof input === "boolean"
376
+
377
+ /**
378
+ * A refinement that checks if a value is a `bigint`.
379
+ *
380
+ * @example
381
+ * ```ts
382
+ * import * as assert from "node:assert"
383
+ * import { isBigInt } from "effect/Predicate"
384
+ *
385
+ * assert.strictEqual(isBigInt(1n), true)
386
+ *
387
+ * assert.strictEqual(isBigInt(1), false)
388
+ * assert.strictEqual(isBigInt("1"), false)
389
+ * ```
390
+ *
391
+ * @category guards
392
+ * @since 2.0.0
393
+ */
394
+ export const isBigInt = (input: unknown): input is bigint => typeof input === "bigint"
395
+
396
+ /**
397
+ * A refinement that checks if a value is a `symbol`.
398
+ *
399
+ * @example
400
+ * ```ts
401
+ * import * as assert from "node:assert"
402
+ * import { isSymbol } from "effect/Predicate"
403
+ *
404
+ * assert.strictEqual(isSymbol(Symbol.for("a")), true)
405
+ *
406
+ * assert.strictEqual(isSymbol("a"), false)
407
+ * ```
408
+ *
409
+ * @category guards
410
+ * @since 2.0.0
411
+ */
412
+ export const isSymbol = (input: unknown): input is symbol => typeof input === "symbol"
413
+
414
+ // TODO: make public
415
+ /**
416
+ * A refinement that checks if a value is a valid `PropertyKey` (a `string`, `number`, or `symbol`).
417
+ * @internal
418
+ */
419
+ export const isPropertyKey = (u: unknown): u is PropertyKey => isString(u) || isNumber(u) || isSymbol(u)
420
+
421
+ /**
422
+ * A refinement that checks if a value is a `Function`.
423
+ *
424
+ * @example
425
+ * ```ts
426
+ * import * as assert from "node:assert"
427
+ * import { isFunction } from "effect/Predicate"
428
+ *
429
+ * assert.strictEqual(isFunction(() => {}), true)
430
+ * assert.strictEqual(isFunction(isFunction), true)
431
+ *
432
+ * assert.strictEqual(isFunction("function"), false)
433
+ * ```
434
+ *
435
+ * @category guards
436
+ * @since 2.0.0
437
+ */
438
+ export const isFunction: (input: unknown) => input is Function = isFunction_
439
+
440
+ /**
441
+ * A refinement that checks if a value is `undefined`.
442
+ *
443
+ * @example
444
+ * ```ts
445
+ * import * as assert from "node:assert"
446
+ * import { isUndefined } from "effect/Predicate"
447
+ *
448
+ * assert.strictEqual(isUndefined(undefined), true)
449
+ *
450
+ * assert.strictEqual(isUndefined(null), false)
451
+ * assert.strictEqual(isUndefined("undefined"), false)
452
+ * ```
453
+ *
454
+ * @category guards
455
+ * @since 2.0.0
456
+ */
457
+ export const isUndefined = (input: unknown): input is undefined => input === undefined
458
+
459
+ /**
460
+ * A refinement that checks if a value is not `undefined`.
461
+ *
462
+ * @example
463
+ * ```ts
464
+ * import * as assert from "node:assert"
465
+ * import { isNotUndefined } from "effect/Predicate"
466
+ *
467
+ * assert.strictEqual(isNotUndefined(null), true)
468
+ * assert.strictEqual(isNotUndefined("value"), true)
469
+ *
470
+ * assert.strictEqual(isNotUndefined(undefined), false)
471
+ * ```
472
+ *
473
+ * @category guards
474
+ * @since 2.0.0
475
+ */
476
+ export const isNotUndefined = <A>(input: A): input is Exclude<A, undefined> => input !== undefined
477
+
478
+ /**
479
+ * A refinement that checks if a value is `null`.
480
+ *
481
+ * @example
482
+ * ```ts
483
+ * import * as assert from "node:assert"
484
+ * import { isNull } from "effect/Predicate"
485
+ *
486
+ * assert.strictEqual(isNull(null), true)
487
+ *
488
+ * assert.strictEqual(isNull(undefined), false)
489
+ * assert.strictEqual(isNull("null"), false)
490
+ * ```
491
+ *
492
+ * @category guards
493
+ * @since 2.0.0
494
+ */
495
+ export const isNull = (input: unknown): input is null => input === null
496
+
497
+ /**
498
+ * A refinement that checks if a value is not `null`.
499
+ *
500
+ * @example
501
+ * ```ts
502
+ * import * as assert from "node:assert"
503
+ * import { isNotNull } from "effect/Predicate"
504
+ *
505
+ * assert.strictEqual(isNotNull(undefined), true)
506
+ * assert.strictEqual(isNotNull("value"), true)
507
+ *
508
+ * assert.strictEqual(isNotNull(null), false)
509
+ * ```
510
+ *
511
+ * @category guards
512
+ * @since 2.0.0
513
+ */
514
+ export const isNotNull = <A>(input: A): input is Exclude<A, null> => input !== null
515
+
516
+ /**
517
+ * A refinement that always returns `false`. The type is narrowed to `never`.
518
+ *
519
+ * @example
520
+ * ```ts
521
+ * import * as assert from "node:assert"
522
+ * import { isNever } from "effect/Predicate"
523
+ *
524
+ * assert.strictEqual(isNever(1), false)
525
+ * assert.strictEqual(isNever(null), false)
526
+ * assert.strictEqual(isNever({}), false)
527
+ * ```
528
+ *
529
+ * @category guards
530
+ * @since 2.0.0
531
+ */
532
+ export const isNever: (input: unknown) => input is never = (_: unknown): _ is never => false
533
+
534
+ /**
535
+ * A refinement that always returns `true`. The type is narrowed to `unknown`.
536
+ *
537
+ * @example
538
+ * ```ts
539
+ * import * as assert from "node:assert"
540
+ * import { isUnknown } from "effect/Predicate"
541
+ *
542
+ * assert.strictEqual(isUnknown(1), true)
543
+ * assert.strictEqual(isUnknown(null), true)
544
+ * assert.strictEqual(isUnknown({}), true)
545
+ * ```
546
+ *
547
+ * @category guards
548
+ * @since 2.0.0
549
+ */
550
+ export const isUnknown: (input: unknown) => input is unknown = (_): _ is unknown => true
551
+
552
+ /**
553
+ * Checks if the input is an object or an array.
554
+ * @internal
555
+ */
556
+ export const isRecordOrArray = (input: unknown): input is { [x: PropertyKey]: unknown } =>
557
+ typeof input === "object" && input !== null
558
+
559
+ /**
560
+ * A refinement that checks if a value is an `object`. Note that in JavaScript,
561
+ * arrays and functions are also considered objects.
562
+ *
563
+ * @example
564
+ * ```ts
565
+ * import * as assert from "node:assert"
566
+ * import { isObject } from "effect/Predicate"
567
+ *
568
+ * assert.strictEqual(isObject({}), true)
569
+ * assert.strictEqual(isObject([]), true)
570
+ * assert.strictEqual(isObject(() => {}), true)
571
+ *
572
+ * assert.strictEqual(isObject(null), false)
573
+ * assert.strictEqual(isObject("hello"), false)
574
+ * ```
575
+ *
576
+ * @category guards
577
+ * @since 2.0.0
578
+ * @see isRecord to check for plain objects (excluding arrays and functions).
579
+ */
580
+ export const isObject = (input: unknown): input is object => isRecordOrArray(input) || isFunction(input)
581
+
582
+ /**
583
+ * A refinement that checks if a value is an object-like value and has a specific property key.
584
+ *
585
+ * @example
586
+ * ```ts
587
+ * import * as assert from "node:assert"
588
+ * import { hasProperty } from "effect/Predicate"
589
+ *
590
+ * assert.strictEqual(hasProperty({ a: 1 }, "a"), true)
591
+ * assert.strictEqual(hasProperty({ a: 1 }, "b"), false)
592
+ *
593
+ * const value: unknown = { name: "Alice" };
594
+ * if (hasProperty(value, "name")) {
595
+ * // The type of `value` is narrowed to `{ name: unknown }`
596
+ * // and we can safely access `value.name`
597
+ * console.log(value.name)
598
+ * }
599
+ * ```
600
+ *
601
+ * @category guards
602
+ * @since 2.0.0
603
+ */
604
+ export const hasProperty: {
605
+ <P extends PropertyKey>(property: P): (self: unknown) => self is { [K in P]: unknown }
606
+ <P extends PropertyKey>(self: unknown, property: P): self is { [K in P]: unknown }
607
+ } = dual(
608
+ 2,
609
+ <P extends PropertyKey>(self: unknown, property: P): self is { [K in P]: unknown } =>
610
+ isObject(self) && (property in self)
611
+ )
612
+
613
+ /**
614
+ * A refinement that checks if a value is an object with a `_tag` property
615
+ * that matches the given tag. This is a powerful tool for working with
616
+ * discriminated union types.
617
+ *
618
+ * @example
619
+ * ```ts
620
+ * import * as assert from "node:assert"
621
+ * import { isTagged } from "effect/Predicate"
622
+ *
623
+ * type Shape = { _tag: "circle"; radius: number } | { _tag: "square"; side: number }
624
+ *
625
+ * const isCircle = isTagged("circle")
626
+ *
627
+ * const shape1: Shape = { _tag: "circle", radius: 10 }
628
+ * const shape2: Shape = { _tag: "square", side: 5 }
629
+ *
630
+ * assert.strictEqual(isCircle(shape1), true)
631
+ * assert.strictEqual(isCircle(shape2), false)
632
+ *
633
+ * if (isCircle(shape1)) {
634
+ * // shape1 is now narrowed to { _tag: "circle"; radius: number }
635
+ * assert.strictEqual(shape1.radius, 10)
636
+ * }
637
+ * ```
638
+ *
639
+ * @category guards
640
+ * @since 2.0.0
641
+ */
642
+ export const isTagged: {
643
+ <K extends string>(tag: K): (self: unknown) => self is { _tag: K }
644
+ <K extends string>(self: unknown, tag: K): self is { _tag: K }
645
+ } = dual(
646
+ 2,
647
+ <K extends string>(self: unknown, tag: K): self is { _tag: K } => hasProperty(self, "_tag") && self["_tag"] === tag
648
+ )
649
+
650
+ /**
651
+ * A refinement that checks if a value is either `null` or `undefined`.
652
+ *
653
+ * @example
654
+ * ```ts
655
+ * import * as assert from "node:assert"
656
+ * import { isNullable } from "effect/Predicate"
657
+ *
658
+ * assert.strictEqual(isNullable(null), true)
659
+ * assert.strictEqual(isNullable(undefined), true)
660
+ *
661
+ * assert.strictEqual(isNullable(0), false)
662
+ * assert.strictEqual(isNullable(""), false)
663
+ * ```
664
+ *
665
+ * @category guards
666
+ * @since 2.0.0
667
+ * @see isNotNullable
668
+ */
669
+ export const isNullable = <A>(input: A): input is Extract<A, null | undefined> => input === null || input === undefined
670
+
671
+ /**
672
+ * A refinement that checks if a value is neither `null` nor `undefined`.
673
+ * The type is narrowed to `NonNullable<A>`.
674
+ *
675
+ * @example
676
+ * ```ts
677
+ * import * as assert from "node:assert"
678
+ * import { isNotNullable } from "effect/Predicate"
679
+ *
680
+ * assert.strictEqual(isNotNullable(0), true)
681
+ * assert.strictEqual(isNotNullable("hello"), true)
682
+ *
683
+ * assert.strictEqual(isNotNullable(null), false)
684
+ * assert.strictEqual(isNotNullable(undefined), false)
685
+ * ```
686
+ *
687
+ * @category guards
688
+ * @since 2.0.0
689
+ * @see isNullable
690
+ */
691
+ export const isNotNullable = <A>(input: A): input is NonNullable<A> => input !== null && input !== undefined
692
+
693
+ /**
694
+ * A refinement that checks if a value is an instance of `Error`.
695
+ *
696
+ * @example
697
+ * ```ts
698
+ * import * as assert from "node:assert"
699
+ * import { isError } from "effect/Predicate"
700
+ *
701
+ * assert.strictEqual(isError(new Error("boom")), true)
702
+ * assert.strictEqual(isError(new TypeError("boom")), true)
703
+ *
704
+ * assert.strictEqual(isError({ message: "boom" }), false)
705
+ * assert.strictEqual(isError("boom"), false)
706
+ * ```
707
+ *
708
+ * @category guards
709
+ * @since 2.0.0
710
+ */
711
+ export const isError = (input: unknown): input is Error => input instanceof Error
712
+
713
+ /**
714
+ * A refinement that checks if a value is a `Uint8Array`.
715
+ *
716
+ * @example
717
+ * ```ts
718
+ * import * as assert from "node:assert"
719
+ * import { isUint8Array } from "effect/Predicate"
720
+ *
721
+ * assert.strictEqual(isUint8Array(new Uint8Array()), true)
722
+ *
723
+ * assert.strictEqual(isUint8Array(new Uint16Array()), false)
724
+ * assert.strictEqual(isUint8Array([1, 2, 3]), false)
725
+ * ```
726
+ *
727
+ * @category guards
728
+ * @since 2.0.0
729
+ */
730
+ export const isUint8Array = (input: unknown): input is Uint8Array => input instanceof Uint8Array
731
+
732
+ /**
733
+ * A refinement that checks if a value is a `Date` object.
734
+ *
735
+ * @example
736
+ * ```ts
737
+ * import * as assert from "node:assert"
738
+ * import { isDate } from "effect/Predicate"
739
+ *
740
+ * assert.strictEqual(isDate(new Date()), true)
741
+ *
742
+ * assert.strictEqual(isDate(Date.now()), false) // `Date.now()` returns a number
743
+ * assert.strictEqual(isDate("2023-01-01"), false)
744
+ * ```
745
+ *
746
+ * @category guards
747
+ * @since 2.0.0
748
+ */
749
+ export const isDate = (input: unknown): input is Date => input instanceof Date
750
+
751
+ /**
752
+ * A refinement that checks if a value is an `Iterable`.
753
+ * Many built-in types are iterable, such as `Array`, `string`, `Map`, and `Set`.
754
+ *
755
+ * @example
756
+ * ```ts
757
+ * import * as assert from "node:assert"
758
+ * import { isIterable } from "effect/Predicate"
759
+ *
760
+ * assert.strictEqual(isIterable([]), true)
761
+ * assert.strictEqual(isIterable("hello"), true)
762
+ * assert.strictEqual(isIterable(new Set()), true)
763
+ *
764
+ * assert.strictEqual(isIterable({}), false)
765
+ * assert.strictEqual(isIterable(123), false)
766
+ * ```
767
+ *
768
+ * @category guards
769
+ * @since 2.0.0
770
+ */
771
+ export const isIterable = (input: unknown): input is Iterable<unknown> =>
772
+ typeof input === "string" || hasProperty(input, Symbol.iterator)
773
+
774
+ /**
775
+ * A refinement that checks if a value is a record (i.e., a plain object).
776
+ * This check returns `false` for arrays, `null`, and functions.
777
+ *
778
+ * @example
779
+ * ```ts
780
+ * import * as assert from "node:assert"
781
+ * import { isRecord } from "effect/Predicate"
782
+ *
783
+ * assert.strictEqual(isRecord({}), true)
784
+ * assert.strictEqual(isRecord({ a: 1 }), true)
785
+ *
786
+ * assert.strictEqual(isRecord([]), false)
787
+ * assert.strictEqual(isRecord(new Date()), false)
788
+ * assert.strictEqual(isRecord(null), false)
789
+ * assert.strictEqual(isRecord(() => null), false)
790
+ * ```
791
+ *
792
+ * @category guards
793
+ * @since 2.0.0
794
+ * @see isObject
795
+ */
796
+ export const isRecord = (input: unknown): input is { [x: string | symbol]: unknown } =>
797
+ isRecordOrArray(input) && !Array.isArray(input)
798
+
799
+ /**
800
+ * A refinement that checks if a value is a readonly record (i.e., a plain object).
801
+ * This check returns `false` for arrays, `null`, and functions.
802
+ *
803
+ * This is an alias for `isRecord`.
804
+ *
805
+ * @example
806
+ * ```ts
807
+ * import * as assert from "node:assert"
808
+ * import { isReadonlyRecord } from "effect/Predicate"
809
+ *
810
+ * assert.strictEqual(isReadonlyRecord({}), true)
811
+ * assert.strictEqual(isReadonlyRecord({ a: 1 }), true)
812
+ *
813
+ * assert.strictEqual(isReadonlyRecord([]), false)
814
+ * assert.strictEqual(isReadonlyRecord(null), false)
815
+ * ```
816
+ *
817
+ * @category guards
818
+ * @since 2.0.0
819
+ */
820
+ export const isReadonlyRecord: (
821
+ input: unknown
822
+ ) => input is { readonly [x: string | symbol]: unknown } = isRecord
823
+
824
+ /**
825
+ * A refinement that checks if a value is a `Promise`. It performs a duck-typing check
826
+ * for `.then` and `.catch` methods.
827
+ *
828
+ * @example
829
+ * ```ts
830
+ * import * as assert from "node:assert"
831
+ * import { isPromise } from "effect/Predicate"
832
+ *
833
+ * assert.strictEqual(isPromise(Promise.resolve(1)), true)
834
+ * assert.strictEqual(isPromise(new Promise(() => {})), true)
835
+ *
836
+ * assert.strictEqual(isPromise({ then() {} }), false) // Missing .catch
837
+ * assert.strictEqual(isPromise({}), false)
838
+ * ```
839
+ *
840
+ * @category guards
841
+ * @since 2.0.0
842
+ * @see isPromiseLike
843
+ */
844
+ export const isPromise = (
845
+ input: unknown
846
+ ): input is Promise<unknown> =>
847
+ hasProperty(input, "then") && "catch" in input && isFunction(input.then) && isFunction(input.catch)
848
+
849
+ /**
850
+ * A refinement that checks if a value is `PromiseLike`. It performs a duck-typing
851
+ * check for a `.then` method.
852
+ *
853
+ * @example
854
+ * ```ts
855
+ * import * as assert from "node:assert"
856
+ * import { isPromiseLike } from "effect/Predicate"
857
+ *
858
+ * assert.strictEqual(isPromiseLike(Promise.resolve(1)), true)
859
+ * assert.strictEqual(isPromiseLike({ then: () => {} }), true)
860
+ *
861
+ * assert.strictEqual(isPromiseLike({}), false)
862
+ * ```
863
+ *
864
+ * @category guards
865
+ * @since 2.0.0
866
+ * @see isPromise
867
+ */
868
+ export const isPromiseLike = (
869
+ input: unknown
870
+ ): input is PromiseLike<unknown> => hasProperty(input, "then") && isFunction(input.then)
871
+
872
+ /**
873
+ * A refinement that checks if a value is a `RegExp`.
874
+ *
875
+ * @example
876
+ * ```ts
877
+ * import * as assert from "node:assert"
878
+ * import { Predicate } from "effect"
879
+ *
880
+ * assert.strictEqual(Predicate.isRegExp(/a/), true)
881
+ * assert.strictEqual(Predicate.isRegExp(new RegExp("a")), true)
882
+ *
883
+ * assert.strictEqual(Predicate.isRegExp("/a/"), false)
884
+ * ```
885
+ *
886
+ * @category guards
887
+ * @since 3.9.0
888
+ */
889
+ export const isRegExp = (input: unknown): input is RegExp => input instanceof RegExp
890
+
891
+ /**
892
+ * Composes a `Refinement` with another `Refinement` or `Predicate`.
893
+ *
894
+ * This can be used to chain checks. The first refinement is applied, and if it
895
+ * passes, the second check is applied to the same value, potentially refining
896
+ * the type further.
897
+ *
898
+ * @example
899
+ * ```ts
900
+ * import { Predicate } from "effect"
901
+ * import * as assert from "node:assert"
902
+ *
903
+ * const isString = (u: unknown): u is string => typeof u === "string"
904
+ * const minLength = (n: number) => (s: string): boolean => s.length >= n
905
+ *
906
+ * // Create a refinement that checks for a string with a minimum length of 3
907
+ * const isLongString = Predicate.compose(isString, minLength(3))
908
+ *
909
+ * let value: unknown = "hello"
910
+ *
911
+ * assert.strictEqual(isLongString(value), true)
912
+ * if (isLongString(value)) {
913
+ * // value is narrowed to string
914
+ * assert.strictEqual(value.toUpperCase(), "HELLO")
915
+ * }
916
+ * assert.strictEqual(isLongString("hi"), false)
917
+ * ```
918
+ *
919
+ * @since 2.0.0
920
+ */
921
+ export const compose: {
922
+ <A, B extends A, C extends B, D extends C>(bc: Refinement<C, D>): (ab: Refinement<A, B>) => Refinement<A, D>
923
+ <A, B extends A>(bc: Predicate<NoInfer<B>>): (ab: Refinement<A, B>) => Refinement<A, B>
924
+ <A, B extends A, C extends B, D extends C>(ab: Refinement<A, B>, bc: Refinement<C, D>): Refinement<A, D>
925
+ <A, B extends A>(ab: Refinement<A, B>, bc: Predicate<NoInfer<B>>): Refinement<A, B>
926
+ } = dual(
927
+ 2,
928
+ <A, B extends A, C extends B, D extends C>(ab: Refinement<A, B>, bc: Refinement<C, D>): Refinement<A, D> =>
929
+ (a): a is D => ab(a) && bc(a as C)
930
+ )
931
+
932
+ /**
933
+ * Combines two predicates to test a tuple of two values. The first predicate tests the
934
+ * first element of the tuple, and the second predicate tests the second element.
935
+ *
936
+ * @category combining
937
+ * @since 2.0.0
938
+ */
939
+ export const product =
940
+ <A, B>(self: Predicate<A>, that: Predicate<B>): Predicate<readonly [A, B]> /* readonly because contravariant */ =>
941
+ ([a, b]) => self(a) && that(b)
942
+
943
+ /**
944
+ * Takes an iterable of predicates and returns a new predicate that tests an array of values.
945
+ * The new predicate returns `true` if each predicate at a given index is satisfied by the
946
+ * value at the same index in the array. The check stops at the length of the shorter of
947
+ * the two iterables (predicates or values).
948
+ *
949
+ * @category combining
950
+ * @since 2.0.0
951
+ * @see tuple for a more powerful, variadic version.
952
+ */
953
+ export const all = <A>(
954
+ collection: Iterable<Predicate<A>>
955
+ ): Predicate<ReadonlyArray<A>> => {
956
+ return (as) => {
957
+ let collectionIndex = 0
958
+ for (const p of collection) {
959
+ if (collectionIndex >= as.length) {
960
+ break
961
+ }
962
+ if (p(as[collectionIndex]) === false) {
963
+ return false
964
+ }
965
+ collectionIndex++
966
+ }
967
+ return true
968
+ }
969
+ }
970
+
971
+ /**
972
+ * Combines a predicate for a single value and an iterable of predicates for the rest of an array.
973
+ * Useful for checking the head and tail of an array separately.
974
+ *
975
+ * @category combining
976
+ * @since 2.0.0
977
+ */
978
+ export const productMany = <A>(
979
+ self: Predicate<A>,
980
+ collection: Iterable<Predicate<A>>
981
+ ): Predicate<readonly [A, ...Array<A>]> /* readonly because contravariant */ => {
982
+ const rest = all(collection)
983
+ return ([head, ...tail]) => self(head) === false ? false : rest(tail)
984
+ }
985
+
986
+ /**
987
+ * Combines an array of predicates into a single predicate that tests an array of values.
988
+ * This function is highly type-aware and will produce a `Refinement` if any of the provided
989
+ * predicates are `Refinement`s, allowing for powerful type-narrowing of tuples.
990
+ *
991
+ * - If all predicates are `Predicate<T>`, the result is `Predicate<[T, T, ...]>`.
992
+ * - If any predicate is a `Refinement<A, B>`, the result is a `Refinement` that narrows
993
+ * the input tuple type to a more specific tuple type.
994
+ *
995
+ * @example
996
+ * ```ts
997
+ * import * as assert from "node:assert"
998
+ * import { Predicate } from "effect"
999
+ *
1000
+ * const isString = (u: unknown): u is string => typeof u === "string"
1001
+ * const isNumber = (u: unknown): u is number => typeof u === "number"
1002
+ *
1003
+ * // Create a refinement for a [string, number] tuple
1004
+ * const isStringNumberTuple = Predicate.tuple(isString, isNumber)
1005
+ *
1006
+ * const value: [unknown, unknown] = ["hello", 123]
1007
+ * if (isStringNumberTuple(value)) {
1008
+ * // value is narrowed to [string, number]
1009
+ * const [s, n] = value
1010
+ * assert.strictEqual(s.toUpperCase(), "HELLO")
1011
+ * assert.strictEqual(n.toFixed(2), "123.00")
1012
+ * }
1013
+ * assert.strictEqual(isStringNumberTuple(["hello", "123"]), false)
1014
+ * ```
1015
+ *
1016
+ * @since 2.0.0
1017
+ */
1018
+ export const tuple: {
1019
+ <T extends ReadonlyArray<Predicate.Any>>(
1020
+ ...elements: T
1021
+ ): [Extract<T[number], Refinement.Any>] extends [never] ? Predicate<{ readonly [I in keyof T]: Predicate.In<T[I]> }>
1022
+ : Refinement<
1023
+ { readonly [I in keyof T]: T[I] extends Refinement.Any ? Refinement.In<T[I]> : Predicate.In<T[I]> },
1024
+ { readonly [I in keyof T]: T[I] extends Refinement.Any ? Refinement.Out<T[I]> : Predicate.In<T[I]> }
1025
+ >
1026
+ } = (...elements: ReadonlyArray<Predicate.Any>) => all(elements) as any
1027
+
1028
+ /**
1029
+ * Combines a record of predicates into a single predicate that tests a record of values.
1030
+ * This function is highly type-aware and will produce a `Refinement` if any of the provided
1031
+ * predicates are `Refinement`s, allowing for powerful type-narrowing of structs.
1032
+ *
1033
+ * - If all predicates are `Predicate<T>`, the result is `Predicate<{ k: T, ... }>`.
1034
+ * - If any predicate is a `Refinement<A, B>`, the result is a `Refinement` that narrows
1035
+ * the input record type to a more specific record type.
1036
+ *
1037
+ * @example
1038
+ * ```ts
1039
+ * import * as assert from "node:assert"
1040
+ * import { Predicate } from "effect"
1041
+ *
1042
+ * const isString = (u: unknown): u is string => typeof u === "string"
1043
+ * const isNumber = (u: unknown): u is number => typeof u === "number"
1044
+ *
1045
+ * const personPredicate = Predicate.struct({
1046
+ * name: isString,
1047
+ * age: isNumber
1048
+ * })
1049
+ *
1050
+ * const value: { name: unknown; age: unknown } = { name: "Alice", age: 30 }
1051
+ * if (personPredicate(value)) {
1052
+ * // value is narrowed to { name: string; age: number }
1053
+ * assert.strictEqual(value.name.toUpperCase(), "ALICE")
1054
+ * assert.strictEqual(value.age.toFixed(0), "30")
1055
+ * }
1056
+ * assert.strictEqual(personPredicate({ name: "Bob", age: "40" }), false)
1057
+ * ```
1058
+ *
1059
+ * @since 2.0.0
1060
+ */
1061
+ export const struct: {
1062
+ <R extends Record<string, Predicate.Any>>(
1063
+ fields: R
1064
+ ): [Extract<R[keyof R], Refinement.Any>] extends [never] ?
1065
+ Predicate<{ readonly [K in keyof R]: Predicate.In<R[K]> }> :
1066
+ Refinement<
1067
+ { readonly [K in keyof R]: R[K] extends Refinement.Any ? Refinement.In<R[K]> : Predicate.In<R[K]> },
1068
+ { readonly [K in keyof R]: R[K] extends Refinement.Any ? Refinement.Out<R[K]> : Predicate.In<R[K]> }
1069
+ >
1070
+ } = (<R extends Record<string, Predicate.Any>>(fields: R) => {
1071
+ const keys = Object.keys(fields)
1072
+ return (a: Record<string, unknown>) => {
1073
+ for (const key of keys) {
1074
+ if (!fields[key](a[key] as never)) {
1075
+ return false
1076
+ }
1077
+ }
1078
+ return true
1079
+ }
1080
+ }) as any
1081
+
1082
+ /**
1083
+ * Returns a new predicate that is the logical negation of the given predicate.
1084
+ *
1085
+ * **Note**: If the input is a `Refinement`, the resulting predicate will be a
1086
+ * simple `Predicate`, as TypeScript cannot infer the negative type.
1087
+ *
1088
+ * @example
1089
+ * ```ts
1090
+ * import * as assert from "node:assert"
1091
+ * import { Predicate, Number } from "effect"
1092
+ *
1093
+ * const isNonPositive = Predicate.not(Number.greaterThan(0))
1094
+ *
1095
+ * assert.strictEqual(isNonPositive(-1), true)
1096
+ * assert.strictEqual(isNonPositive(0), true)
1097
+ * assert.strictEqual(isNonPositive(1), false)
1098
+ * ```
1099
+ *
1100
+ * @category combinators
1101
+ * @since 2.0.0
1102
+ */
1103
+ export const not = <A>(self: Predicate<A>): Predicate<A> => (a) => !self(a)
1104
+
1105
+ /**
1106
+ * Combines two predicates with a logical "OR". The resulting predicate returns `true`
1107
+ * if at least one of the predicates returns `true`.
1108
+ *
1109
+ * If both predicates are `Refinement`s, the resulting predicate is a `Refinement` to the
1110
+ * union of their target types (`B | C`).
1111
+ *
1112
+ * @example
1113
+ * ```ts
1114
+ * import * as assert from "node:assert"
1115
+ * import { Predicate } from "effect"
1116
+ *
1117
+ * const isString = (u: unknown): u is string => typeof u === "string"
1118
+ * const isNumber = (u: unknown): u is number => typeof u === "number"
1119
+ *
1120
+ * const isStringOrNumber = Predicate.or(isString, isNumber)
1121
+ *
1122
+ * assert.strictEqual(isStringOrNumber("hello"), true)
1123
+ * assert.strictEqual(isStringOrNumber(123), true)
1124
+ * assert.strictEqual(isStringOrNumber(null), false)
1125
+ *
1126
+ * const value: unknown = "world"
1127
+ * if (isStringOrNumber(value)) {
1128
+ * // value is narrowed to string | number
1129
+ * console.log(value)
1130
+ * }
1131
+ * ```
1132
+ *
1133
+ * @category combinators
1134
+ * @since 2.0.0
1135
+ */
1136
+ export const or: {
1137
+ <A, C extends A>(that: Refinement<A, C>): <B extends A>(self: Refinement<A, B>) => Refinement<A, B | C>
1138
+ <A, B extends A, C extends A>(self: Refinement<A, B>, that: Refinement<A, C>): Refinement<A, B | C>
1139
+ <A>(that: Predicate<A>): (self: Predicate<A>) => Predicate<A>
1140
+ <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A>
1141
+ } = dual(2, <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A> => (a) => self(a) || that(a))
1142
+
1143
+ /**
1144
+ * Combines two predicates with a logical "AND". The resulting predicate returns `true`
1145
+ * only if both of the predicates return `true`.
1146
+ *
1147
+ * If both predicates are `Refinement`s, the resulting predicate is a `Refinement` to the
1148
+ * intersection of their target types (`B & C`).
1149
+ *
1150
+ * @example
1151
+ * ```ts
1152
+ * import * as assert from "node:assert"
1153
+ * import { Predicate } from "effect"
1154
+ *
1155
+ * type Person = { name: string }
1156
+ * type Employee = { id: number }
1157
+ *
1158
+ * const hasName = (u: unknown): u is Person => Predicate.hasProperty(u, "name") && typeof (u as any).name === "string"
1159
+ * const hasId = (u: unknown): u is Employee => Predicate.hasProperty(u, "id") && typeof (u as any).id === "number"
1160
+ *
1161
+ * const isPersonAndEmployee = Predicate.and(hasName, hasId)
1162
+ *
1163
+ * const val: unknown = { name: "Alice", id: 123 }
1164
+ * if (isPersonAndEmployee(val)) {
1165
+ * // val is narrowed to Person & Employee
1166
+ * assert.strictEqual(val.name, "Alice")
1167
+ * assert.strictEqual(val.id, 123)
1168
+ * }
1169
+ *
1170
+ * assert.strictEqual(isPersonAndEmployee({ name: "Bob" }), false) // Missing id
1171
+ * assert.strictEqual(isPersonAndEmployee({ id: 456 }), false) // Missing name
1172
+ * ```
1173
+ *
1174
+ * @category combinators
1175
+ * @since 2.0.0
1176
+ */
1177
+ export const and: {
1178
+ <A, C extends A>(that: Refinement<A, C>): <B extends A>(self: Refinement<A, B>) => Refinement<A, B & C>
1179
+ <A, B extends A, C extends A>(self: Refinement<A, B>, that: Refinement<A, C>): Refinement<A, B & C>
1180
+ <A>(that: Predicate<A>): (self: Predicate<A>) => Predicate<A>
1181
+ <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A>
1182
+ } = dual(2, <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A> => (a) => self(a) && that(a))
1183
+
1184
+ /**
1185
+ * Combines two predicates with a logical "XOR" (exclusive OR). The resulting predicate
1186
+ * returns `true` if one of the predicates returns `true`, but not both.
1187
+ *
1188
+ * @example
1189
+ * ```ts
1190
+ * import * as assert from "node:assert"
1191
+ * import { Predicate } from "effect"
1192
+ *
1193
+ * const isPositive = (n: number) => n > 0
1194
+ * const isEven = (n: number) => n % 2 === 0
1195
+ *
1196
+ * const isPositiveXorEven = Predicate.xor(isPositive, isEven)
1197
+ *
1198
+ * assert.strictEqual(isPositiveXorEven(4), false) // both true -> false
1199
+ * assert.strictEqual(isPositiveXorEven(3), true) // one true -> true
1200
+ * assert.strictEqual(isPositiveXorEven(-2), true) // one true -> true
1201
+ * assert.strictEqual(isPositiveXorEven(-1), false) // both false -> false
1202
+ * ```
1203
+ *
1204
+ * @category combinators
1205
+ * @since 2.0.0
1206
+ */
1207
+ export const xor: {
1208
+ <A>(that: Predicate<A>): (self: Predicate<A>) => Predicate<A>
1209
+ <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A>
1210
+ } = dual(2, <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A> => (a) => self(a) !== that(a))
1211
+
1212
+ /**
1213
+ * Combines two predicates with a logical "EQV" (equivalence). The resulting predicate
1214
+ * returns `true` if both predicates return the same boolean value (both `true` or both `false`).
1215
+ *
1216
+ * @example
1217
+ * ```ts
1218
+ * import * as assert from "node:assert"
1219
+ * import { Predicate } from "effect"
1220
+ *
1221
+ * const isPositive = (n: number) => n > 0
1222
+ * const isEven = (n: number) => n % 2 === 0
1223
+ *
1224
+ * const isPositiveEqvEven = Predicate.eqv(isPositive, isEven)
1225
+ *
1226
+ * assert.strictEqual(isPositiveEqvEven(4), true) // both true -> true
1227
+ * assert.strictEqual(isPositiveEqvEven(3), false) // different -> false
1228
+ * assert.strictEqual(isPositiveEqvEven(-2), false) // different -> false
1229
+ * assert.strictEqual(isPositiveEqvEven(-1), true) // both false -> true
1230
+ * ```
1231
+ *
1232
+ * @category combinators
1233
+ * @since 2.0.0
1234
+ */
1235
+ export const eqv: {
1236
+ <A>(that: Predicate<A>): (self: Predicate<A>) => Predicate<A>
1237
+ <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A>
1238
+ } = dual(2, <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A> => (a) => self(a) === that(a))
1239
+
1240
+ /**
1241
+ * Creates a predicate that represents a logical "if-then" rule.
1242
+ *
1243
+ * Think of it as a conditional promise: **"If `antecedent` holds true, then I promise `consequent` will also be true."**
1244
+ *
1245
+ * This function is invaluable for defining complex validation logic where one condition dictates another.
1246
+ *
1247
+ * ### How It Works
1248
+ *
1249
+ * The rule only fails (returns `false`) when the "if" part is `true`, but the "then" part is `false`.
1250
+ * In all other cases, the promise is considered kept, and the result is `true`.
1251
+ *
1252
+ * This includes the concept of **"vacuous truth"**: if the "if" part is `false`, the rule doesn't apply,
1253
+ * so the promise isn't broken, and the result is `true`. (e.g., "If it rains, I'll bring an umbrella."
1254
+ * If it doesn't rain, you haven't broken your promise, no matter what).
1255
+ *
1256
+ * ### Key Details
1257
+ *
1258
+ * - **Logical Equivalence**: `implies(p, q)` is the same as `not(p).or(q)`, or simply `!p || q`
1259
+ * in plain JavaScript. This can be a helpful way to reason about its behavior.
1260
+ *
1261
+ * - **Type-Safety Warning**: This function always returns a `Predicate`, never a type-narrowing
1262
+ * `Refinement`. A `true` result doesn't guarantee the `consequent` passed (it could be `true`
1263
+ * simply because the `antecedent` was `false`), so it cannot be used to safely narrow a type.
1264
+ *
1265
+ * @example
1266
+ * ```ts
1267
+ * // Rule: A user can only be an admin if they also belong to the "staff" group.
1268
+ * import * as assert from "node:assert"
1269
+ * import { Predicate } from "effect"
1270
+ *
1271
+ * type User = {
1272
+ * isStaff: boolean
1273
+ * isAdmin: boolean
1274
+ * }
1275
+ *
1276
+ * const isValidUserPermission = Predicate.implies(
1277
+ * // antecedent: "if" the user is an admin...
1278
+ * (user: User) => user.isAdmin,
1279
+ * // consequent: "then" they must be staff.
1280
+ * (user: User) => user.isStaff
1281
+ * )
1282
+ *
1283
+ * // A non-admin who is not staff. Rule doesn't apply (antecedent is false).
1284
+ * assert.strictEqual(isValidUserPermission({ isStaff: false, isAdmin: false }), true)
1285
+ *
1286
+ * // A staff member who is not an admin. Rule doesn't apply (antecedent is false).
1287
+ * assert.strictEqual(isValidUserPermission({ isStaff: true, isAdmin: false }), true)
1288
+ *
1289
+ * // An admin who is also staff. The rule was followed.
1290
+ * assert.strictEqual(isValidUserPermission({ isStaff: true, isAdmin: true }), true)
1291
+ *
1292
+ * // An admin who is NOT staff. The rule was broken!
1293
+ * assert.strictEqual(isValidUserPermission({ isStaff: false, isAdmin: true }), false)
1294
+ * ```
1295
+ *
1296
+ * @category combinators
1297
+ * @since 2.0.0
1298
+ */
1299
+ export const implies: {
1300
+ <A>(consequent: Predicate<A>): (antecedent: Predicate<A>) => Predicate<A>
1301
+ <A>(antecedent: Predicate<A>, consequent: Predicate<A>): Predicate<A>
1302
+ } = dual(
1303
+ 2,
1304
+ <A>(antecedent: Predicate<A>, consequent: Predicate<A>): Predicate<A> => (a) => antecedent(a) ? consequent(a) : true
1305
+ )
1306
+
1307
+ /**
1308
+ * Combines two predicates with a logical "NOR" (negated OR). The resulting predicate
1309
+ * returns `true` only if both predicates return `false`.
1310
+ * This is equivalent to `not(or(p, q))`.
1311
+ *
1312
+ * @category combinators
1313
+ * @since 2.0.0
1314
+ */
1315
+ export const nor: {
1316
+ <A>(that: Predicate<A>): (self: Predicate<A>) => Predicate<A>
1317
+ <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A>
1318
+ } = dual(
1319
+ 2,
1320
+ <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A> => (a) => !(self(a) || that(a))
1321
+ )
1322
+
1323
+ /**
1324
+ * Combines two predicates with a logical "NAND" (negated AND). The resulting predicate
1325
+ * returns `true` if at least one of the predicates returns `false`.
1326
+ * This is equivalent to `not(and(p, q))`.
1327
+ *
1328
+ * @category combinators
1329
+ * @since 2.0.0
1330
+ */
1331
+ export const nand: {
1332
+ <A>(that: Predicate<A>): (self: Predicate<A>) => Predicate<A>
1333
+ <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A>
1334
+ } = dual(
1335
+ 2,
1336
+ <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A> => (a) => !(self(a) && that(a))
1337
+ )
1338
+
1339
+ /**
1340
+ * Takes an iterable of predicates and returns a new predicate. The new predicate
1341
+ * returns `true` if all predicates in the collection return `true` for a given value.
1342
+ *
1343
+ * This is like `Array.prototype.every` but for a collection of predicates.
1344
+ *
1345
+ * @example
1346
+ * ```ts
1347
+ * import * as assert from "node:assert"
1348
+ * import { Predicate } from "effect"
1349
+ *
1350
+ * const isPositive = (n: number) => n > 0
1351
+ * const isEven = (n: number) => n % 2 === 0
1352
+ *
1353
+ * const isPositiveAndEven = Predicate.every([isPositive, isEven])
1354
+ *
1355
+ * assert.strictEqual(isPositiveAndEven(4), true)
1356
+ * assert.strictEqual(isPositiveAndEven(3), false)
1357
+ * assert.strictEqual(isPositiveAndEven(-2), false)
1358
+ * ```
1359
+ *
1360
+ * @category elements
1361
+ * @since 2.0.0
1362
+ * @see some
1363
+ */
1364
+ export const every = <A>(collection: Iterable<Predicate<A>>): Predicate<A> => (a: A) => {
1365
+ for (const p of collection) {
1366
+ if (!p(a)) {
1367
+ return false
1368
+ }
1369
+ }
1370
+ return true
1371
+ }
1372
+
1373
+ /**
1374
+ * Takes an iterable of predicates and returns a new predicate. The new predicate
1375
+ * returns `true` if at least one predicate in the collection returns `true` for a given value.
1376
+ *
1377
+ * This is like `Array.prototype.some` but for a collection of predicates.
1378
+ *
1379
+ * @example
1380
+ * ```ts
1381
+ * import * as assert from "node:assert"
1382
+ * import { Predicate } from "effect"
1383
+ *
1384
+ * const isNegative = (n: number) => n < 0
1385
+ * const isOdd = (n: number) => n % 2 !== 0
1386
+ *
1387
+ * const isNegativeOrOdd = Predicate.some([isNegative, isOdd])
1388
+ *
1389
+ * assert.strictEqual(isNegativeOrOdd(-2), true) // isNegative is true
1390
+ * assert.strictEqual(isNegativeOrOdd(3), true) // isOdd is true
1391
+ * assert.strictEqual(isNegativeOrOdd(4), false) // both are false
1392
+ * ```
1393
+ *
1394
+ * @category elements
1395
+ * @since 2.0.0
1396
+ * @see every
1397
+ */
1398
+ export const some = <A>(collection: Iterable<Predicate<A>>): Predicate<A> => (a) => {
1399
+ for (const p of collection) {
1400
+ if (p(a)) {
1401
+ return true
1402
+ }
1403
+ }
1404
+ return false
1405
+ }