simtap 0.0.0-stage → 0.6.0

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 (179) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +186 -2
  3. package/THIRD_PARTY_LICENSES +61 -0
  4. package/bin/simtap.js +4 -0
  5. package/dist/act/diff.js +67 -0
  6. package/dist/act/resolve.js +49 -0
  7. package/dist/act/steps.js +188 -0
  8. package/dist/cli.js +123 -0
  9. package/dist/engine/apps.js +153 -0
  10. package/dist/engine/axe.js +107 -0
  11. package/dist/engine/exec.js +36 -0
  12. package/dist/engine/jobs.js +95 -0
  13. package/dist/engine/logs.js +115 -0
  14. package/dist/engine/simctl.js +191 -0
  15. package/dist/engine/state.js +30 -0
  16. package/dist/engine/xcode.js +253 -0
  17. package/dist/engine/xcresult.js +95 -0
  18. package/dist/errors.js +11 -0
  19. package/dist/look/read.js +50 -0
  20. package/dist/look/snapshot.js +455 -0
  21. package/dist/mcp.js +108 -0
  22. package/dist/registry.js +65 -0
  23. package/dist/tools/app-control.js +127 -0
  24. package/dist/tools/app-logs.js +128 -0
  25. package/dist/tools/app-run.js +94 -0
  26. package/dist/tools/device-use.js +68 -0
  27. package/dist/tools/devices.js +26 -0
  28. package/dist/tools/jobs.js +55 -0
  29. package/dist/tools/launch-app.js +68 -0
  30. package/dist/tools/screen-record.js +79 -0
  31. package/dist/tools/tests-run.js +81 -0
  32. package/dist/tools/types.js +2 -0
  33. package/dist/tools/ui-act.js +435 -0
  34. package/dist/tools/ui-look.js +40 -0
  35. package/package.json +45 -4
  36. package/skill/SKILL.md +23 -0
  37. package/vendor/axe/.version +1 -0
  38. package/vendor/axe/AXe_AXe.bundle/skills/axe/SKILL.md +87 -0
  39. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/FBControlCore +0 -0
  40. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBAccessibilityTraits.h +23 -0
  41. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBArchitecture.h +20 -0
  42. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBArchiveOperations.h +136 -0
  43. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBBinaryDescriptor.h +73 -0
  44. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBControlCore-Swift.h +3232 -0
  45. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBControlCore-SwiftImport.h +28 -0
  46. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBControlCore.h +47 -0
  47. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBControlCoreFrameworkLoader.h +104 -0
  48. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBControlCoreLogger+OSLog.h +30 -0
  49. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBControlCoreLogger.h +107 -0
  50. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBCrashLog.h +20 -0
  51. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBDataBuffer.h +75 -0
  52. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBDataConsumer.h +173 -0
  53. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBFileContainer.h +46 -0
  54. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBFileReader.h +25 -0
  55. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBFourCharCode.h +30 -0
  56. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBFuture+Sync.h +104 -0
  57. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBFuture.h +580 -0
  58. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBFutureContextManager.h +61 -0
  59. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBInstalledApplication.h +30 -0
  60. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBInstrumentsCommands.h +29 -0
  61. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBInstrumentsOperation.h +83 -0
  62. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBObjCExceptionGuard.h +59 -0
  63. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBProcessBuilder.h +272 -0
  64. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBProcessFetcher.h +128 -0
  65. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBProcessIO.h +126 -0
  66. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBProcessStream.h +175 -0
  67. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBProcessTerminationStrategy.h +25 -0
  68. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBScreenshotCommands.h +15 -0
  69. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBSettingsCommands.h +22 -0
  70. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBSocketServer.h +63 -0
  71. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBSubprocess.h +131 -0
  72. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBVideoStream.h +255 -0
  73. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBVideoStreamConfiguration.h +51 -0
  74. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBXCTraceOperation.h +13 -0
  75. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBiOSTarget.h +69 -0
  76. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBiOSTargetConfiguration.h +322 -0
  77. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBiOSTargetConstants.h +48 -0
  78. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Headers/FBiOSTargetOperation.h +18 -0
  79. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Modules/FBControlCore.swiftmodule/Project/arm64-apple-macos.swiftsourceinfo +0 -0
  80. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Modules/FBControlCore.swiftmodule/Project/x86_64-apple-macos.swiftsourceinfo +0 -0
  81. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Modules/FBControlCore.swiftmodule/arm64-apple-macos.abi.json +51890 -0
  82. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Modules/FBControlCore.swiftmodule/arm64-apple-macos.private.swiftinterface +1341 -0
  83. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Modules/FBControlCore.swiftmodule/arm64-apple-macos.swiftdoc +0 -0
  84. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Modules/FBControlCore.swiftmodule/arm64-apple-macos.swiftinterface +1341 -0
  85. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Modules/FBControlCore.swiftmodule/arm64-apple-macos.swiftmodule +0 -0
  86. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Modules/FBControlCore.swiftmodule/x86_64-apple-macos.abi.json +51890 -0
  87. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Modules/FBControlCore.swiftmodule/x86_64-apple-macos.private.swiftinterface +1341 -0
  88. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Modules/FBControlCore.swiftmodule/x86_64-apple-macos.swiftdoc +0 -0
  89. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Modules/FBControlCore.swiftmodule/x86_64-apple-macos.swiftinterface +1341 -0
  90. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Modules/FBControlCore.swiftmodule/x86_64-apple-macos.swiftmodule +0 -0
  91. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Modules/module.modulemap +10 -0
  92. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/Resources/Info.plist +50 -0
  93. package/vendor/axe/Frameworks/FBControlCore.framework/Versions/A/_CodeSignature/CodeResources +492 -0
  94. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/FBDeviceControl +0 -0
  95. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBAFCConnection.h +135 -0
  96. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBAMDServiceConnection.h +239 -0
  97. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBAMDefines.h +256 -0
  98. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBAMDevice.h +105 -0
  99. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBAMDeviceManager.h +59 -0
  100. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBAMRestorableDevice.h +72 -0
  101. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBAMRestorableDeviceManager.h +32 -0
  102. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBDevice.h +89 -0
  103. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBDeviceCommands.h +147 -0
  104. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBDeviceControl-Swift.h +1500 -0
  105. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBDeviceControl.h +24 -0
  106. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBDeviceControlFrameworkLoader.h +25 -0
  107. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBDeviceDebugSymbolsCommands.h +29 -0
  108. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBDeviceManager.h +118 -0
  109. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Headers/FBInstrumentsClient.h +49 -0
  110. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Modules/FBDeviceControl.swiftmodule/Project/arm64-apple-macos.swiftsourceinfo +0 -0
  111. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Modules/FBDeviceControl.swiftmodule/Project/x86_64-apple-macos.swiftsourceinfo +0 -0
  112. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Modules/FBDeviceControl.swiftmodule/arm64-apple-macos.abi.json +16073 -0
  113. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Modules/FBDeviceControl.swiftmodule/arm64-apple-macos.private.swiftinterface +398 -0
  114. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Modules/FBDeviceControl.swiftmodule/arm64-apple-macos.swiftdoc +0 -0
  115. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Modules/FBDeviceControl.swiftmodule/arm64-apple-macos.swiftinterface +398 -0
  116. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Modules/FBDeviceControl.swiftmodule/arm64-apple-macos.swiftmodule +0 -0
  117. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Modules/FBDeviceControl.swiftmodule/x86_64-apple-macos.abi.json +16073 -0
  118. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Modules/FBDeviceControl.swiftmodule/x86_64-apple-macos.private.swiftinterface +398 -0
  119. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Modules/FBDeviceControl.swiftmodule/x86_64-apple-macos.swiftdoc +0 -0
  120. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Modules/FBDeviceControl.swiftmodule/x86_64-apple-macos.swiftinterface +398 -0
  121. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Modules/FBDeviceControl.swiftmodule/x86_64-apple-macos.swiftmodule +0 -0
  122. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Modules/module.modulemap +10 -0
  123. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/Resources/Info.plist +50 -0
  124. package/vendor/axe/Frameworks/FBDeviceControl.framework/Versions/A/_CodeSignature/CodeResources +324 -0
  125. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/FBSimulatorControl +0 -0
  126. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Headers/FBFramebuffer.h +24 -0
  127. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Headers/FBPeriodicStatsTimer.h +43 -0
  128. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Headers/FBSimDeviceWrapper.h +86 -0
  129. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Headers/FBSimulator.h +160 -0
  130. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Headers/FBSimulatorBootConfiguration.h +18 -0
  131. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Headers/FBSimulatorControl-Swift.h +2270 -0
  132. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Headers/FBSimulatorControl.h +21 -0
  133. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Headers/FBSimulatorControlFrameworkLoader.h +45 -0
  134. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Headers/FBSimulatorVideoStream.h +153 -0
  135. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Modules/FBSimulatorControl.swiftmodule/Project/arm64-apple-macos.swiftsourceinfo +0 -0
  136. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Modules/FBSimulatorControl.swiftmodule/Project/x86_64-apple-macos.swiftsourceinfo +0 -0
  137. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Modules/FBSimulatorControl.swiftmodule/arm64-apple-macos.abi.json +46980 -0
  138. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Modules/FBSimulatorControl.swiftmodule/arm64-apple-macos.private.swiftinterface +1072 -0
  139. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Modules/FBSimulatorControl.swiftmodule/arm64-apple-macos.swiftdoc +0 -0
  140. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Modules/FBSimulatorControl.swiftmodule/arm64-apple-macos.swiftinterface +1072 -0
  141. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Modules/FBSimulatorControl.swiftmodule/arm64-apple-macos.swiftmodule +0 -0
  142. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Modules/FBSimulatorControl.swiftmodule/x86_64-apple-macos.abi.json +46980 -0
  143. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Modules/FBSimulatorControl.swiftmodule/x86_64-apple-macos.private.swiftinterface +1072 -0
  144. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Modules/FBSimulatorControl.swiftmodule/x86_64-apple-macos.swiftdoc +0 -0
  145. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Modules/FBSimulatorControl.swiftmodule/x86_64-apple-macos.swiftinterface +1072 -0
  146. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Modules/FBSimulatorControl.swiftmodule/x86_64-apple-macos.swiftmodule +0 -0
  147. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Modules/module.modulemap +10 -0
  148. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Resources/Info.plist +50 -0
  149. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/Resources/README.md +124 -0
  150. package/vendor/axe/Frameworks/FBSimulatorControl.framework/Versions/A/_CodeSignature/CodeResources +293 -0
  151. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Headers/FBActivityRecord.h +33 -0
  152. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Headers/FBAttachment.h +25 -0
  153. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Headers/FBCodeCoverageConfiguration.h +15 -0
  154. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Headers/FBTestBundleConnection.h +37 -0
  155. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Headers/FBTestConfiguration.h +74 -0
  156. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Headers/FBTestManagerAPIMediator.h +46 -0
  157. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Headers/FBTestManagerResultSummary.h +19 -0
  158. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Headers/FBTestReporterAdapter.h +27 -0
  159. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Headers/FBXCTestConfiguration.h +30 -0
  160. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Headers/XCTestBootstrap-Swift.h +1570 -0
  161. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Headers/XCTestBootstrap.h +22 -0
  162. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Headers/XCTestBootstrapError.h +25 -0
  163. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Modules/XCTestBootstrap.swiftmodule/Project/arm64-apple-macos.swiftsourceinfo +0 -0
  164. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Modules/XCTestBootstrap.swiftmodule/Project/x86_64-apple-macos.swiftsourceinfo +0 -0
  165. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Modules/XCTestBootstrap.swiftmodule/arm64-apple-macos.abi.json +15972 -0
  166. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Modules/XCTestBootstrap.swiftmodule/arm64-apple-macos.private.swiftinterface +397 -0
  167. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Modules/XCTestBootstrap.swiftmodule/arm64-apple-macos.swiftdoc +0 -0
  168. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Modules/XCTestBootstrap.swiftmodule/arm64-apple-macos.swiftinterface +397 -0
  169. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Modules/XCTestBootstrap.swiftmodule/arm64-apple-macos.swiftmodule +0 -0
  170. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Modules/XCTestBootstrap.swiftmodule/x86_64-apple-macos.abi.json +15972 -0
  171. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Modules/XCTestBootstrap.swiftmodule/x86_64-apple-macos.private.swiftinterface +397 -0
  172. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Modules/XCTestBootstrap.swiftmodule/x86_64-apple-macos.swiftdoc +0 -0
  173. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Modules/XCTestBootstrap.swiftmodule/x86_64-apple-macos.swiftinterface +397 -0
  174. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Modules/XCTestBootstrap.swiftmodule/x86_64-apple-macos.swiftmodule +0 -0
  175. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Modules/module.modulemap +13 -0
  176. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/Resources/Info.plist +50 -0
  177. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/XCTestBootstrap +0 -0
  178. package/vendor/axe/Frameworks/XCTestBootstrap.framework/Versions/A/_CodeSignature/CodeResources +303 -0
  179. package/vendor/axe/axe +0 -0
@@ -0,0 +1,104 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #import <Foundation/Foundation.h>
9
+
10
+ #import <FBControlCore/FBFuture.h>
11
+
12
+ /**
13
+ Conveniences to aid synchronous waiting on events, whilst not blocking other event sources.
14
+ */
15
+ @interface NSRunLoop (FBControlCore)
16
+
17
+ /**
18
+ Spins the Run Loop until `untilTrue` returns YES or a timeout is reached.
19
+
20
+ @oaram timeout the Timeout in Seconds.
21
+ @param untilTrue the condition to meet.
22
+ @return YES if the condition was met, NO if the timeout was reached first.
23
+ */
24
+ - (BOOL)spinRunLoopWithTimeout:(NSTimeInterval)timeout untilTrue:(nonnull BOOL (^)(void))untilTrue;
25
+
26
+ /**
27
+ Spins the Run Loop until `untilTrue` returns a value, or a timeout is reached.
28
+
29
+ @oaram timeout the Timeout in Seconds.
30
+ @param untilExists the mapping to a value.
31
+ @return the return value of untilTrue, or nil if a timeout was reached.
32
+ */
33
+ - (nullable id)spinRunLoopWithTimeout:(NSTimeInterval)timeout untilExists:(nonnull id _Nullable (^)(void))untilExists;
34
+
35
+ @end
36
+
37
+ /**
38
+ Helpers for extracting the value from an FBFuture.
39
+ Since FBFuture only exposes callback mounting in it's main interface, this allows callers to wait for a value to appear asynchronously.
40
+ */
41
+ @interface FBFuture <T>(Sync)
42
+
43
+ /**
44
+ Await the Future, with no Timeout.
45
+ This will spin the run loop whilst waiting for the Future to resolve.
46
+ For threads and queues that don't have a Run Loop, one will be created in accordance with +[NSRunLoop currentRunLoop].
47
+
48
+ @param error an error outparam if the Future resolves with an error.
49
+ @return the the Future's result if successful, nil otherwise.
50
+ */
51
+ - (nullable T)await:(NSError * _Nullable * _Nullable)error;
52
+
53
+ /**
54
+ Await the Future with the provided timeout.
55
+ This will spin the run loop whilst waiting for the Future to resolve.
56
+ For threads and queues that don't have a Run Loop, one will be created in accordance with +[NSRunLoop currentRunLoop].
57
+
58
+ @param timeout the timeout in seconds to wait.
59
+ @param error an error outparam if the Future resolves with an error, or the Future is not resolved within the timeout.
60
+ @return the the Future's result if successful, nil otherwise.
61
+ */
62
+ - (nullable T)awaitWithTimeout:(NSTimeInterval)timeout error:(NSError * _Nullable * _Nullable)error;
63
+
64
+ /**
65
+ Block until the Future is completed and return whether is succeeded.
66
+ This will use dispatch internally and should *never* be called from the main thread/queue, or any thread/queue that needs to be serviced for the Future to resolve.
67
+ This is useful if the value returned by the future is not significant for the caller, only that it succeeded.
68
+
69
+ @param error an error outparam if the Future resolves with an error.
70
+ @return YES if the future completes successfully, NO otherwise.
71
+ */
72
+ - (BOOL)succeeds:(NSError * _Nullable * _Nullable)error;
73
+
74
+ /**
75
+ Block until the Future is completed and return whether is succeeded.
76
+ This will use dispatch internally and should *never* be called from the main thread/queue, or any thread/queue that needs to be serviced for the Future to resolve.
77
+ This is useful if the value returned by the future is not significant for the caller, only that it succeeded.
78
+
79
+ @param error an error outparam if the Future resolves with an error or times out.
80
+ @return YES if the future completes successfully, NO otherwise.
81
+ */
82
+ - (BOOL)onQueue:(nonnull dispatch_queue_t)queue timeout:(dispatch_time_t)timeout succeeds:(NSError * _Nullable * _Nullable)error;
83
+
84
+ /**
85
+ Block until the Future is completed and return the result.
86
+ This will use dispatch internally and should *never* be called from the main thread/queue, or any thread/queue that needs to be serviced for the Future to resolve.
87
+
88
+ @param error an error outparam if the Future resolves with an error.
89
+ @return the the Future's result if successful, nil otherwise.
90
+ */
91
+ - (nullable T)block:(NSError * _Nullable * _Nullable)error;
92
+
93
+ /**
94
+ Block until the Future is completed and return the result.
95
+ This will use dispatch internally and should *never* be called from the main thread/queue, or any thread/queue that needs to be serviced for the Future to resolve.
96
+
97
+ @param queue the queue to serialize on.
98
+ @param timeout the timeout in dispatch_time to wait
99
+ @param error an error outparam if the Future resolves with an error or times out.
100
+ @return the the Future's result if successful, nil otherwise.
101
+ */
102
+ - (nullable T)onQueue:(nonnull dispatch_queue_t)queue timeout:(dispatch_time_t)timeout block:(NSError * _Nullable * _Nullable)error;
103
+
104
+ @end
@@ -0,0 +1,580 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #import <Foundation/Foundation.h>
9
+
10
+ @class FBFutureContext<T>;
11
+
12
+ @protocol FBControlCoreLogger;
13
+
14
+ /**
15
+ A State for the Future.
16
+ */
17
+ typedef NS_ENUM(NSUInteger, FBFutureState) {
18
+ FBFutureStateRunning = 1, /* The Future hasn't resolved yet */
19
+ FBFutureStateDone = 2, /* The Future has resolved successfully */
20
+ FBFutureStateFailed = 3, /* The Future has resolved in error */
21
+ FBFutureStateCancelled = 4, /* The Future has been cancelled */
22
+ };
23
+
24
+ /**
25
+ Loop status for onQueue:resolveOrFailWhen:
26
+ */
27
+ typedef NS_ENUM(NSUInteger, FBFutureLoopState) {
28
+ FBFutureLoopContinue = 1, /* FBFuture resolveOrFailWhen will continue */
29
+ FBFutureLoopFinished = 2, /* FBFuture resolveOrFailWhen has finished */
30
+ FBFutureLoopFailed = 3, /* FBFuture resolveOrFailWhen has failed */
31
+ };
32
+
33
+ extern dispatch_time_t FBCreateDispatchTimeFromDuration(NSTimeInterval inDuration);
34
+
35
+ /**
36
+ A Future Operation
37
+ */
38
+ @interface FBFuture <T : id> : NSObject
39
+
40
+ #pragma mark Initializers
41
+
42
+ /**
43
+ Constructs a Future that wraps a result
44
+
45
+ @param result the result.
46
+ @return a new Future.
47
+ */
48
+ + (nonnull FBFuture<T> *)futureWithResult:(nonnull T)result;
49
+
50
+ /**
51
+ Constructs a Future that wraps an error.
52
+
53
+ @param error the error to wrap.
54
+ @return a new Future.
55
+ */
56
+ + (nonnull FBFuture<T> *)futureWithError:(nonnull NSError *)error;
57
+
58
+ /**
59
+ Construct a Future that resolves with a delay.
60
+
61
+ @param delay the delay to resolve the future in.
62
+ @param future the future to resolve
63
+ @return the Future wrapped in a delay.
64
+ */
65
+ + (nonnull FBFuture<T> *)futureWithDelay:(NSTimeInterval)delay future:(nonnull FBFuture<T> *)future;
66
+
67
+ /**
68
+ Constructs a Future that resolves successfully when the resolveWhen block returns YES.
69
+ onQueue:resolveWhen: is a shortcut to onQueue:resolveOrFailWhen:
70
+
71
+ @param queue to resolve on.
72
+ @param resolveWhen a block determining when the future should resolve.
73
+ @return a new Future that resolves when the resolution block returns YES.
74
+ */
75
+ + (nonnull FBFuture<NSNull *> *)onQueue:(nonnull dispatch_queue_t)queue resolveWhen:(nonnull BOOL (^)(void))resolveWhen;
76
+
77
+ /**
78
+ Constructs a Future that resolves when the resolveOrFailWhen block returns FBFutureLoopState.
79
+ resolveOrFailWhen block will be executed every 100ms to determine when the future should be resolved:
80
+
81
+ * If resolveOrFailWhen block returns FBFutureLoopContinue, the future will continue in Running state
82
+ * If resolveOrFailWhen block returns FBFutureLoopFinished and errorOut is not set, the future will resolve successfully
83
+ * If resolveOrFailWhen block returns FBFutureLoopFailed and error out is set, the future will resolve on a failure.
84
+
85
+ @param queue to resolve on.
86
+ @param resolveOrFailWhen a block determining when the future should resolve. Future will resolve into a failure if `errorOut` is not nil.
87
+ @return a new Future that resolves when the resolution block returns FBFutureLoopFinished or FBFutureLoopFailed.
88
+ */
89
+ + (nonnull FBFuture<NSNull *> *)onQueue:(nonnull dispatch_queue_t)queue resolveOrFailWhen:(nonnull FBFutureLoopState (^)(NSError * _Nullable * _Nullable errorOut))resolveOrFailWhen;
90
+
91
+ /**
92
+ Constructs a Future that resolves successfully when the resolveUntil block resolves a Future that resolves a value.
93
+ Each resolution will occur one-after-another.
94
+
95
+ @param queue to resolve on.
96
+ @param resolveUntil a block that returns a future to resolve.
97
+ @return a new Future that resolves when the future returned by the block resolves a value.
98
+ */
99
+ + (nonnull FBFuture<T> *)onQueue:(nonnull dispatch_queue_t)queue resolveUntil:(nonnull FBFuture<T> * _Nonnull (^)(void))resolveUntil;
100
+
101
+ /**
102
+ Resolve a future synchronously, by value.
103
+
104
+ @param resolve the the block to resolve the future.
105
+ @return the receiver, for chaining.
106
+ */
107
+ + (nonnull instancetype)resolveValue:(nonnull T _Nullable (^)(NSError * _Nullable * _Nullable))resolve;
108
+
109
+ /**
110
+ Resolve a future asynchronously, by value.
111
+
112
+ @param queue to resolve on.
113
+ @param resolve the the block to resolve the future.
114
+ @return the receiver, for chaining.
115
+ */
116
+ + (nonnull instancetype)onQueue:(nonnull dispatch_queue_t)queue resolveValue:(nonnull T _Nullable (^)(NSError * _Nullable * _Nullable))resolve;
117
+
118
+ /**
119
+ Resolve a future asynchronously, by returning a future.
120
+
121
+ @param queue to resolve on.
122
+ @param resolve the the block to resolve the future.
123
+ @return the receiver, for chaining.
124
+ */
125
+ + (nonnull instancetype)onQueue:(nonnull dispatch_queue_t)queue resolve:(nonnull FBFuture * _Nonnull (^)(void))resolve;
126
+
127
+ /**
128
+ Constructs a future from an array of futures.
129
+ The future will resolve when all futures in the array have resolved.
130
+ If any future resolves in an error, the first error will be propogated. Any pending futures will not be cancelled.
131
+ If any future resolves in cancellation, the cancellation will be propogated. Any pending futures will not be cancelled.
132
+
133
+ @param futures the futures to compose.
134
+ @return a new future with the resolved results of all the composed futures.
135
+ */
136
+ + (nonnull FBFuture<NSArray<T> *> *)futureWithFutures:(nonnull NSArray<FBFuture<T> *> *)futures NS_SWIFT_NAME(combine(_:));
137
+
138
+ /**
139
+ Constructrs a Future from an Array of Futures.
140
+ The future which resolves the first will be returned.
141
+ All other futures will be cancelled.
142
+
143
+ @param futures the futures to compose.
144
+ @return a new Future with the first future that resolves.
145
+ */
146
+ + (nonnull FBFuture<T> *)race:(nonnull NSArray<FBFuture<T> *> *)futures NS_SWIFT_NAME(init(race:));
147
+
148
+ /**
149
+ A resolved future, with an insignificant value.
150
+ This can be used to communicate "success", where an errored future would indicate failure.
151
+
152
+ @return a new Future that's resolved with an NSNull value.
153
+ */
154
+ + (nonnull FBFuture<NSNull *> *)empty;
155
+
156
+ #pragma mark Cancellation
157
+
158
+ /**
159
+ Cancels the asynchronous operation.
160
+ This will always start the process of cancellation.
161
+ Some cancellation is immediate, the returned future may resolve immediatey.
162
+
163
+ However, other cancellation operations are asynchronous, where the future will not resolve immediately.
164
+ If you wish to wait for the cancellation to have been fully resolved, chain on the future returned.
165
+
166
+ @return a Future that resolves when cancellation of all handlers has been processed.
167
+ */
168
+ - (nonnull FBFuture<NSNull *> *)cancel;
169
+
170
+ /**
171
+ Respond to the cancellation of the receiver.
172
+ Since the cancellation handler can itself return a future, asynchronous cancellation is permitted.
173
+ This can be called multiple times for the same Future if multiple cleanup operations need to occur.
174
+
175
+ Make sure that the future that is returned from this block is itself not the same reference as the receiver.
176
+ Otherwise the `cancel` call will itself resolve as 'cancelled'.
177
+
178
+ @param queue the queue to notify on.
179
+ @param handler the block to invoke if cancelled.
180
+ @return the Receiver, for chaining.
181
+ */
182
+ - (nonnull instancetype)onQueue:(nonnull dispatch_queue_t)queue respondToCancellation:(nonnull FBFuture<NSNull *> * _Nonnull (^)(void))handler;
183
+
184
+ #pragma mark Completion Notification
185
+
186
+ /**
187
+ Notifies of the resolution of the Future.
188
+
189
+ @param queue the queue to notify on.
190
+ @param handler the block to invoke.
191
+ @return the Receiver, for chaining.
192
+ */
193
+ - (nonnull instancetype)onQueue:(nonnull dispatch_queue_t)queue notifyOfCompletion:(nonnull void (^)(FBFuture * _Nonnull))handler;
194
+
195
+ /**
196
+ Notifies of the successful resolution of the Future.
197
+ The handler will resolve before the chained Future.
198
+
199
+ @param queue the queue to notify on.
200
+ @param handler the block to invoke.
201
+ @return the Receiver, for chaining.
202
+ */
203
+ - (nonnull instancetype)onQueue:(nonnull dispatch_queue_t)queue doOnResolved:(nonnull void (^)(T _Nonnull))handler;
204
+
205
+ #pragma mark Deriving new Futures
206
+
207
+ /**
208
+ Chain Futures based on any non-cancellation resolution of the receiver.
209
+ All completion events are called in the chained future block (Done, Error, Cancelled).
210
+
211
+ @param queue the queue to chain on.
212
+ @param chain the chaining handler, called on all completion events.
213
+ @return a chained future
214
+ */
215
+ - (nonnull FBFuture *)onQueue:(nonnull dispatch_queue_t)queue chain:(nonnull FBFuture * _Nonnull (^)(FBFuture * _Nonnull future))chain;
216
+
217
+ /**
218
+ FlatMap a successful resolution of the receiver to a new Future.
219
+
220
+ @param queue the queue to chain on.
221
+ @param fmap the function to re-map the result to a new future, only called on success.
222
+ @return a flatmapped future
223
+ */
224
+ - (nonnull FBFuture *)onQueue:(nonnull dispatch_queue_t)queue fmap:(nonnull FBFuture * _Nonnull (^)(T _Nonnull result))fmap;
225
+
226
+ /**
227
+ Map a future's result to a new value, based on a successful resolution of the receiver.
228
+
229
+ @param queue the queue to map on.
230
+ @param map the mapping block, only called on success.
231
+ @return a mapped future
232
+ */
233
+ - (nonnull FBFuture *)onQueue:(nonnull dispatch_queue_t)queue map:(nonnull id _Nonnull (^)(T _Nonnull result))map;
234
+
235
+ /**
236
+ Returns a copy of this future that'll resolve on a specific queue
237
+
238
+ @param queue the queue to resolve on
239
+ @returns a copy of this future that'll resolve on the specified queue
240
+ */
241
+ - (nonnull FBFuture<T> *)onQueue:(nonnull dispatch_queue_t)queue;
242
+
243
+ /**
244
+ Attempt to handle an error.
245
+
246
+ @param queue the queue to handle on.
247
+ @param handler the block to invoke.
248
+ @return a Future that will attempt to handle the error
249
+ */
250
+ - (nonnull FBFuture *)onQueue:(nonnull dispatch_queue_t)queue handleError:(nonnull FBFuture * _Nonnull (^)(NSError * _Nonnull))handler;
251
+
252
+ /**
253
+ Cancels the receiver if it doesn't resolve within the timeout.
254
+ The chained future is resolved in error, with the provided error message.
255
+
256
+ @param timeout the amount of time to time out the receiver in
257
+ @param description the description of the timeout.
258
+ @return the current future with a timeout applied.
259
+ */
260
+ - (nonnull FBFuture *)timeout:(NSTimeInterval)timeout waitingFor:(nonnull NSString *)description;
261
+
262
+ /**
263
+ Cancels the receiver if it doesn't resolve within the timeout.
264
+ The chained future is resolved based upon the value returned within the handler.
265
+
266
+ @param queue the queue to call the handler on.
267
+ @param timeout the amount of time to time out the receiver in
268
+ @param handler the block that will be fired on timeout.
269
+ @return the current future with a timeout applied.
270
+ */
271
+ - (nonnull FBFuture *)onQueue:(nonnull dispatch_queue_t)queue timeout:(NSTimeInterval)timeout handler:(nonnull FBFuture * _Nonnull (^)(void))handler;
272
+
273
+ /**
274
+ Replaces the value on a successful future.
275
+
276
+ @param replacement the replacement
277
+ @return a future with the replacement.
278
+ */
279
+ - (nonnull FBFuture *)mapReplace:(nonnull id)replacement;
280
+
281
+ /**
282
+ Once the receiver has resolved in any state, chains to another Future.
283
+ This is un-conditional, if the receiver resolves in error the replacement will still be used.
284
+
285
+ @param replacement the replacement
286
+ @return a future with the replacement.
287
+ */
288
+ - (nonnull FBFuture *)chainReplace:(nonnull FBFuture *)replacement;
289
+
290
+ /**
291
+ Shields the future from failure, replacing it with the provided value.
292
+
293
+ @param replacement the replacement
294
+ @return a future with the replacement.
295
+ */
296
+ - (nonnull FBFuture<T> *)fallback:(nonnull T)replacement;
297
+
298
+ /**
299
+ Delays delivery of the completion of the receiver.
300
+ A chaining convenience over -[FBFuture futureWithDelay:future:]
301
+
302
+ @param delay the delay to resolve the future in.
303
+ @return a delayed future.
304
+ */
305
+ - (nonnull FBFuture<T> *)delay:(NSTimeInterval)delay;
306
+
307
+ /**
308
+ Replaces the error message in the event of a failure.
309
+
310
+ @param description the description to re-phrase the failure message.
311
+ @return a future with the replacement.
312
+ */
313
+ - (nonnull FBFuture<T> *)rephraseFailure:(nonnull NSString *)description;
314
+
315
+ #pragma mark Creating Context
316
+
317
+ /**
318
+ Creates an 'context object' that allows for the value contained by a future to be torn-down when the context is done.
319
+ This is useful for resource cleanup, where closing a resource needs to be managed.
320
+ The teardown will always be called, regardless of the terminating condition of any chained future.
321
+ The state passed in the teardown callback is the state of the resolved future from any chaining that may happen.
322
+ The teardown will only be called if the receiver has resolved, as this is how the context value is resolved.
323
+
324
+ @param queue the queue to perform the teardown on.
325
+ @param action the teardown action to invoke. This block will be executed after the context object is done. This also includes the state that the resultant future ended in.
326
+ @return a 'context object' that manages the tear-down of the receiver's value. This teardown can be asynchronous, and is indicated via the return-value of the contextualTeardown block,
327
+ */
328
+ - (nonnull FBFutureContext<T> *)onQueue:(nonnull dispatch_queue_t)queue contextualTeardown:(nonnull FBFuture<NSNull *> * _Nonnull (^)(T _Nonnull, FBFutureState))action;
329
+
330
+ /**
331
+ Creates an 'context object' from a block.
332
+
333
+ @param queue the queue to perform the teardown on.
334
+ @param fmap the 'context object' to add.
335
+ @return a 'contex object' that manages the tear-down of the receiver's value.
336
+ */
337
+ - (nonnull FBFutureContext *)onQueue:(nonnull dispatch_queue_t)queue pushTeardown:(nonnull FBFutureContext * _Nonnull (^)(T _Nonnull))fmap;
338
+
339
+ #pragma mark Metadata
340
+
341
+ /**
342
+ Rename the future.
343
+
344
+ @param name the name of the Future.
345
+ @return the receiver, for chaining.
346
+ */
347
+ - (nonnull FBFuture<T> *)named:(nonnull NSString *)name;
348
+
349
+ /**
350
+ A helper to log completion of the future.
351
+
352
+ @param logger the logger to log to.
353
+ @param purpose a description of the future.
354
+ @return the receiver, for chaining
355
+ */
356
+ - (nonnull FBFuture<T> *)logCompletion:(nonnull id<FBControlCoreLogger>)logger withPurpose:(nonnull NSString *)purpose;
357
+
358
+ #pragma mark Properties
359
+
360
+ /**
361
+ YES if receiver has terminated, NO otherwise.
362
+ */
363
+ @property (atomic, readonly, assign) BOOL hasCompleted;
364
+
365
+ /**
366
+ The Error if one is present.
367
+ */
368
+ @property (nullable, atomic, readonly, copy) NSError *error;
369
+
370
+ /**
371
+ The Result.
372
+ */
373
+ @property (nullable, atomic, readonly, copy) T result;
374
+
375
+ /**
376
+ The State.
377
+ */
378
+ @property (atomic, readonly, assign) FBFutureState state;
379
+
380
+ /**
381
+ The name of the Future.
382
+ This can be used to set contextual information about the work that the Future represents.
383
+ Any name is incorporated into the description.
384
+ */
385
+ @property (nullable, atomic, readonly, copy) NSString *name;
386
+
387
+ @end
388
+
389
+ /**
390
+ A Future that can be modified.
391
+ */
392
+ @interface FBMutableFuture <T : id> : FBFuture
393
+
394
+ #pragma mark Initializers
395
+
396
+ /**
397
+ A Future that can be controlled externally.
398
+ The Future is in a 'running' state until it is resolved with the `resolve` methods.
399
+
400
+ @return a new Mutable Future.
401
+ */
402
+ + (nonnull FBMutableFuture<T> *)future;
403
+
404
+ /**
405
+ A Mutable Future with a Name.
406
+
407
+ @param name the name of the Future
408
+ @return a new Mutable Future.
409
+ */
410
+ + (nonnull FBMutableFuture<T> *)futureWithName:(nullable NSString *)name;
411
+
412
+ #pragma mark Mutation
413
+
414
+ /**
415
+ Make the wrapped future succeeded.
416
+
417
+ @param result The result.
418
+ @return the receiver, for chaining.
419
+ */
420
+ - (nonnull instancetype)resolveWithResult:(nonnull T)result;
421
+
422
+ /**
423
+ Make the wrapped future fail with an error.
424
+
425
+ @param error The error.
426
+ @return the receiver, for chaining.
427
+ */
428
+ - (nonnull instancetype)resolveWithError:(nonnull NSError *)error;
429
+
430
+ /**
431
+ Resolve the receiver upon the completion of another future.
432
+
433
+ @param future the future to resolve from.
434
+ @return the receiver, for chaining.
435
+ */
436
+ - (nonnull instancetype)resolveFromFuture:(nonnull FBFuture *)future;
437
+
438
+ @end
439
+
440
+ /**
441
+ Wraps a Future in such a way that teardown work can be deferred.
442
+ This is useful when the Future wraps some kind of resource that requires cleanup.
443
+ Upon completion of the future that the context wraps, a teardown action associated with the context is then performed.
444
+
445
+ From this class:
446
+ - A Future can be obtained that will completed before the teardown work does.
447
+ - Additional chaining is possible, deferring teardown, or adding to a stack of teardowns.
448
+
449
+ The API intentionally mirrors some of the methods in FBFuture, so that it can used in equivalent places.
450
+ The nominal types of FBFuture and FBFutureContext so that it hard to confuse chaining on between them.
451
+
452
+ Like cancellation on a Future, teardown is also permitted to be asynchronous. This is important where resources are allocated on top of each other.
453
+ For example this can be useful to have set-up and tear-down actions performed in the order they are added to the teardown stack:
454
+ 1) A socket is created.
455
+ 2) A file read operation is made on the socket.
456
+ 3) The file read operation is used, and then finishes.
457
+ 4) The file read operation is stopped.
458
+ 5) The socket is closed.
459
+
460
+ In this case it's important that #4 has finished it's teardown work before #5 completes.
461
+ This is achieved by a teardown action returning a future that completes when the work of #4 is completely done.
462
+ Async teardown is completely optional, if the ordering is not significant, then the action can return an empty future to not defer any teardown work lower in the stack.
463
+ */
464
+ @interface FBFutureContext <T : id> : NSObject
465
+
466
+ #pragma mark Initializers
467
+
468
+ /**
469
+ Constructs a context with no teardown.
470
+
471
+ @param future the future to wrap.
472
+ @return a FBFutureContext wrapping the Future.
473
+ */
474
+ + (nonnull FBFutureContext<T> *)futureContextWithFuture:(nonnull FBFuture<T> *)future;
475
+
476
+ /**
477
+ Constructs a context with no teardown, from a result.
478
+
479
+ @param result the result to wrap.
480
+ @return a FBFutureContext wrapping the Future.
481
+ */
482
+ + (nonnull FBFutureContext<T> *)futureContextWithResult:(nonnull T)result;
483
+
484
+ /**
485
+ Constructs a context with no teardown, from an error.
486
+
487
+ @param error an error to raise.
488
+ @return a new Future Context.
489
+ */
490
+ + (nonnull FBFutureContext *)futureContextWithError:(nonnull NSError *)error;
491
+
492
+ /**
493
+ Constructs a FBFutureContext in Parallel.
494
+
495
+ @param contexts the contexts to use.
496
+ @return a new FBFutureContext with the underlying contexts in an array.
497
+ */
498
+ + (nonnull FBFutureContext<NSArray<id> *> *)futureContextWithFutureContexts:(nonnull NSArray<FBFutureContext *> *)contexts;
499
+
500
+ #pragma mark Public Methods
501
+
502
+ /**
503
+ Return a Future from the context.
504
+ The receiver's teardown will occur *after* the Future returned by `pop` resolves.
505
+ If you wish to keep the context alive after the `pop` then use `pend` instead.
506
+
507
+ @param queue the queue to chain on.
508
+ @param pop the function to re-map the result to a new future, only called on success.
509
+ @return a Future derived from the fmap. The teardown of the context will occur *after* this future has resolved.
510
+ */
511
+ - (nonnull FBFuture *)onQueue:(nonnull dispatch_queue_t)queue pop:(nonnull FBFuture * _Nonnull (^)(T _Nonnull result))pop;
512
+
513
+ /**
514
+ Continue to keep the context alive, but fmap a new future.
515
+ The receiver's teardown will not occur after the `pend`'s Future has resolved.
516
+
517
+ @param queue the queue to chain on.
518
+ @param fmap the function to re-map the result to a new future, only called on success.
519
+ @return a Context derived from the fmap.
520
+ */
521
+ - (nonnull FBFutureContext *)onQueue:(nonnull dispatch_queue_t)queue pend:(nonnull FBFuture * _Nonnull (^)(T _Nonnull result))fmap;
522
+
523
+ /**
524
+ Pushes another context.
525
+ This can be used to make a stack of contexts that unroll once the produced context pops.
526
+
527
+ @param queue the queue to chain on.
528
+ @param fmap the block to produce more context.
529
+ @return a Context derived from the fmap with the current context stacked below.
530
+ */
531
+ - (nonnull FBFutureContext *)onQueue:(nonnull dispatch_queue_t)queue push:(nonnull FBFutureContext * _Nonnull (^)(T _Nonnull result))fmap;
532
+
533
+ /**
534
+ Replaces the current context.
535
+ This is equivalent to replacing the top of the context stack with a different context.
536
+ @param queue the queue to chain on.
537
+ @param replace the block to produce more context.
538
+ @return a Context derived from the replace with the current context stacked below.
539
+ */
540
+ - (nonnull FBFutureContext *)onQueue:(nonnull dispatch_queue_t)queue replace:(nonnull FBFutureContext * _Nonnull (^)(T _Nonnull result))replace;
541
+
542
+ /**
543
+ Continue to keep the context alive, but handleError: a new future.
544
+ The receiver's teardown will not occur after the `handleError`'s Future has resolved.
545
+
546
+ @param queue the queue to chain on.
547
+ @param handler the function to re-map the error to a new future, only executed if caller resolves to a failure.
548
+ @return a Context derived from the handleError.
549
+ */
550
+
551
+ - (nonnull FBFutureContext *)onQueue:(nonnull dispatch_queue_t)queue handleError:(nonnull FBFuture * _Nonnull (^)(NSError * _Nonnull))handler;
552
+
553
+ /**
554
+ Adds a teardown to the context
555
+
556
+ @param queue the queue to call the teardown on
557
+ @param action the teardown action
558
+ @return a context with the teardown applied.
559
+ */
560
+ - (nonnull FBFutureContext *)onQueue:(nonnull dispatch_queue_t)queue contextualTeardown:(nonnull FBFuture<NSNull *> * _Nonnull (^)(T _Nonnull, FBFutureState))action;
561
+
562
+ /**
563
+ Extracts the wrapped context, so that it can be torn-down at a later time.
564
+ This is designed to allow a context manager to be combined with the teardown of other long-running operations.
565
+
566
+ @param queue the queue to chain on.
567
+ @param enter the block that receives two parameters. The first is the context value, the second is a future that will tear-down the context when it is resolved.
568
+ @return a Future that wraps the value returned from fmap.
569
+ */
570
+ - (nonnull FBFuture *)onQueue:(nonnull dispatch_queue_t)queue enter:(nonnull id _Nonnull (^)(T _Nonnull result, FBMutableFuture<NSNull *> * _Nonnull teardown))enter;
571
+
572
+ #pragma mark Properties
573
+
574
+ /**
575
+ The future keeping the context alive.
576
+ The context will not be torn down until this future resolves.
577
+ */
578
+ @property (nonnull, nonatomic, readonly, strong) FBFuture<T> *future;
579
+
580
+ @end