├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── codecov.yml ├── composer.json ├── composer.lock ├── examples ├── dns ├── dns-react ├── exceptions ├── hello-world ├── return-value ├── strand-suspend └── stream-raw ├── peridot.php └── src ├── Event.php ├── EventQueue.php ├── IO.php ├── IOSelect.php ├── ReferenceApi.php ├── ReferenceKernel.php ├── ReferenceStrand.php └── StrandTimeout.php /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 1.0.2 (2022-03-06) 4 | 5 | - Add support for PHP 8 6 | - Drop support for PHP 7.0, 7.1, 7.2 and 7.3 7 | 8 | ## 1.0.1 (2018-04-06) 9 | 10 | - **[FIX]** Handle `fwrite()` error conditions indicated by `0` return value ([recoilphp/react#6](https://github.com/recoilphp/react#6)) 11 | 12 | ## 1.0.0 (2017-10-18) 13 | 14 | This is the first stable release of `recoil/recoil`. There have been no changes 15 | to the API since the `1.0.0-alpha.2` release. 16 | 17 | ## 1.0.0-alpha.2 (2016-12-16) 18 | 19 | - **[NEW]** Add `select()` API operation 20 | 21 | ## 1.0.0-alpha.1 (2016-12-16) 22 | 23 | **UPGRADE WITH CAUTION** 24 | 25 | As of this version, the `recoil/recoil` package only contains the 26 | "reference kernel", which is an implementation of the kernel with no external 27 | dependencies. As such, it can not be used to execute ReactPHP code. 28 | 29 | The ReactPHP kernel is still available in the [recoil/react](https://github.com/recoilphp/react) 30 | package. 31 | 32 | Libraries and applications should be developed against the interfaces and 33 | classes provided by [recoil/api](https://github.com/recoilphp/api). The intent 34 | is to keep these interfaces as stable as possible across the various kernel 35 | implementations and versions. 36 | 37 | - **[BC]** Moved the ReactPHP-based kernel to the [recoil/react](https://github.com/recoilphp/react) package 38 | - **[BC]** Moved the public interfaces to the [recoil/api](https://github.com/recoilphp/api) package 39 | - **[BC]** Moved kernel implementation details to the [recoil/kernel](https://github.com/recoilphp/kernel) package 40 | 41 | ## 0.6.0 (2016-07-29) 42 | 43 | - **[BC]** Revert addition of `Api::resume()` and `throw()` (added in 0.5.2) 44 | - **[BC]** Added `Strand::trace()` and `setTrace()` methods 45 | - **[NEW]** `Api::suspend()` now accepts an optional terminator callback, which is invoked if the strand is terminated before it is resumed 46 | - **[NEW]** Added `StrandTrace` interface, a low-level strand observer to be used by debugging tools 47 | - **[FIXED]** `Strand::send()` and `throw()` no longer fail if the strand has already exited 48 | 49 | ## 0.5.2 (2016-07-15) 50 | 51 | - **[NEW]** Added `Api::resume()` and `throw()` to resume one strand from within another 52 | 53 | ## 0.5.1 (2016-07-12) 54 | 55 | - **[NEW]** Added a second callback parameter to `suspend()` API method which is invoked when a suspended strand is terminated 56 | 57 | ## 0.5.0 (2016-07-11) 58 | 59 | **UPGRADE WITH CAUTION** 60 | 61 | This is the first release that requires PHP 7. The internals have been rewritten 62 | from the ground up. Some features available in previous releases are no longer 63 | available as substitute functionality has not yet been added. 64 | 65 | There are far too many changes to list here individually, however much of the 66 | kernel API remains the same. 67 | 68 | - **[BC]** Channels and streams have been removed from the core package 69 | - **[BC]** `Recoil::run()` has been removed (see `ReactKernel::start()`) 70 | 71 | Kernel API changes: 72 | 73 | - **[BC]** `kernel()` has been removed 74 | - **[BC]** `eventLoop()` is only available when using `ReactKernel` 75 | - **[BC]** `return_()` has been removed, as generators can return values in PHP 7 76 | - **[BC]** `throw_()` has been removed 77 | - **[BC]** `finally_()` has been removed 78 | - **[BC]** `noop()` has been removed 79 | - **[BC]** `stop()` has been removed 80 | - **[BC]** `select()` now operates on PHP streams, rather than strands 81 | - **[NEW]** Added `read()` and `write()` 82 | - **[NEW]** Added `callback()` 83 | - **[NEW]** Added `link()` and `unlink()` 84 | - **[NEW]** Added `adopt()` 85 | - **[NEW]** Added `any()`, `some()` and `first()` 86 | 87 | ## 0.4.0 (2016-03-06) 88 | 89 | This is the final release that will operate with PHP 5. In an effort to work 90 | towards a production ready 1.0 release, future releases will require PHP 7. 91 | 92 | - **[BC]** Dropped `Interface` suffix from interfaces 93 | - **[BC]** Renamed `ReadableStream` to `ReadablePhpStream` 94 | - **[BC]** Renamed `WritableStream` to `WritablePhpStream` 95 | - **[BC]** Renamed `CoroutineAdaptor` to `StandardCoroutineAdaptor` 96 | - **[BC]** Renamed `KernelApi` to `StandardKernelApi` 97 | - **[BC]** Renamed `Strand` to `StandardStrand` 98 | - **[BC]** Renamed `StrandFactory` to `StandardStrandFactory` 99 | - **[NEW]** Added support for Guzzle promises 100 | - **[IMPROVED]** The callback given to `Recoil::suspend` is now optional 101 | 102 | ## 0.3.0 (2015-06-26) 103 | 104 | - **[BC]** Removed `StrandInterface::resume()` 105 | - **[NEW]** `return` statement can be used to return a value inside a coroutine (requires PHP 7) 106 | - **[IMPROVED]** Improved method documentation on `Recoil` facade (thanks @rjkip) 107 | 108 | ## 0.2.1 (2014-10-16) 109 | 110 | - **[IMPROVED]** Added support for cancellable promises 111 | 112 | ## 0.2.0 (2014-09-23) 113 | 114 | To faciliate several performance improvements the following backwards compatibility breaking changes have been introduced: 115 | 116 | - **[BC]** `CoroutineInterface` no longer implements `EventEmitterInterface` - several unused events were fired every time a coroutine was called 117 | - **[BC]** `Recoil::finalize()` now only works with generator based coroutines - this was previously implemented using the aforementioned events 118 | 119 | ## 0.1.0 (2014-02-04) 120 | 121 | - Initial release 122 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013 James Harris 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SOURCE = $(shell find src test -type f) 2 | 3 | test: | vendor 4 | php -c test/etc/php.ini vendor/bin/peridot 5 | 6 | coverage: artifacts/tests/coverage/index.html 7 | 8 | coverage-open: artifacts/tests/coverage/index.html 9 | open artifacts/tests/coverage/index.html 10 | 11 | lint: $(SOURCE) | vendor 12 | @mkdir -p artifacts/ 13 | vendor/bin/php-cs-fixer fix --allow-risky=yes 14 | 15 | prepare: lint coverage 16 | composer validate 17 | travis lint 18 | 19 | ci: artifacts/tests/coverage/clover.xml 20 | php -c test/etc/php.ini -d zend.assertions=-1 vendor/bin/peridot 21 | 22 | .PHONY: FORCE test coverage coverage-open lint prepare ci 23 | 24 | vendor: composer.lock 25 | composer install 26 | 27 | composer.lock: composer.json 28 | composer update 29 | 30 | artifacts/tests/coverage/index.html: $(SOURCE) | vendor 31 | phpdbg -c test/etc/php.ini -qrr vendor/bin/peridot --reporter html-code-coverage --code-coverage-path=$(@D) 32 | 33 | artifacts/tests/coverage/clover.xml: $(SOURCE) | vendor 34 | phpdbg -c test/etc/php.ini -qrr vendor/bin/peridot --reporter clover-code-coverage --code-coverage-path=$@ 35 | 36 | %.php: FORCE 37 | @php -l $@ > /dev/null 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Recoil 2 | 3 | [![Build Status](http://img.shields.io/travis/recoilphp/recoil/master.svg?style=flat-square)](https://travis-ci.org/recoilphp/recoil) 4 | [![Code Coverage](https://img.shields.io/codecov/c/github/recoilphp/recoil/master.svg?style=flat-square)](https://codecov.io/github/recoilphp/recoil) 5 | [![Code Quality](https://img.shields.io/scrutinizer/g/recoilphp/recoil/master.svg?style=flat-square)](https://scrutinizer-ci.com/g/recoilphp/recoil/) 6 | [![Latest Version](http://img.shields.io/packagist/v/recoil/recoil.svg?style=flat-square&label=semver)](https://semver.org) 7 | 8 | An asynchronous coroutine kernel for PHP 7. 9 | 10 | composer require recoil/recoil 11 | 12 | The Recoil project comprises the following packages: 13 | 14 | - [recoil/api](https://github.com/recoilphp/api) - The public Recoil API for application and library developers. 15 | - [recoil/dev](https://github.com/recoilphp/dev) - Development and debugging tools. 16 | - [recoil/recoil](https://github.com/recoilphp/recoil) (this package) - A reference implementation of the kernel described in the API. 17 | - [recoil/react](https://github.com/recoilphp/react) - A kernel implementation based on the [ReactPHP](https://github.com/reactphp/reactphp) event loop. 18 | - [recoil/kernel](https://github.com/recoilphp/kernel) - Common components used to implement the kernels. 19 | 20 | ## Overview 21 | 22 | Recoil aims to ease development of asynchronous applications by presenting asynchronous control flow in a familiar 23 | "imperative" syntax. 24 | 25 | **What does that mean?** Let's jump right in with an example that resolves multiple domain names **concurrently**. 26 | 27 | ```php 28 | use Recoil\React\ReactKernel; 29 | use Recoil\Recoil; 30 | 31 | function resolveDomainName(string $name, React\Dns\Resolver\Resolver $resolver) 32 | { 33 | try { 34 | $ip = yield $resolver->resolve($name); 35 | echo 'Resolved "' . $name . '" to ' . $ip . PHP_EOL; 36 | } catch (Exception $e) { 37 | echo 'Failed to resolve "' . $name . '" - ' . $e->getMessage() . PHP_EOL; 38 | } 39 | } 40 | 41 | ReactKernel::start(function () { 42 | // Create a React DNS resolver ... 43 | $resolver = (new React\Dns\Resolver\Factory)->create( 44 | '8.8.8.8', 45 | yield Recoil::eventLoop() 46 | ); 47 | 48 | // Concurrently resolve three domain names ... 49 | yield [ 50 | resolveDomainName('recoil.io', $resolver), 51 | resolveDomainName('php.net', $resolver), 52 | resolveDomainName('probably-wont-resolve', $resolver), 53 | ]; 54 | }); 55 | ``` 56 | 57 | This code resolves three domain names to their IP address and prints the results to the terminal. You can try the 58 | example yourself by running the following command in the root of the repository: 59 | 60 | ``` 61 | ./examples/dns 62 | ``` 63 | 64 | Run it a few times. You'll notice that the output is not always in the same order. This is because the requests are made 65 | concurrently and the results are shown as soon as they are received from the DNS server. 66 | 67 | Note that there is **no callback-passing**, and that regular PHP **exceptions are used for reporting errors**. This is 68 | what we mean by "familiar imperative syntax". 69 | 70 | **Clear as mud?** Read on :) 71 | 72 | ## Concepts 73 | 74 | ### Coroutines 75 | 76 | _Coroutines_ are essentially functions that can be suspended and resumed while maintaining their state. This is useful 77 | in asynchronous applications, as the coroutine can suspend while waiting for some task to complete or information 78 | to arrive, and the CPU is free to perform other tasks. 79 | 80 | PHP generators provide the language-level support for functions that can suspend and resume, and Recoil provides the 81 | glue that lets us use these features to perform asynchronous operations. 82 | 83 | A Recoil application is started by executing an "entry-point" generator, a little like the `main()` function in the C 84 | programming language. The Recoil kernel inspects the values yielded by the generator and identifies an operation to 85 | perform. For example, yielding a `float` with value `30` causes the coroutine to suspend execution for 30 seconds. 86 | 87 | The DNS example above shows a rather more advanced usage, including concurrent execution and integration with 88 | asynchronous code that is not part of Recoil. The resulting code, however, is quite normal looking, except for the 89 | `yield` statements! 90 | 91 | Within Recoil, the term _coroutine_ specifically refers to a PHP generator that is being executed by the Recoil kernel. 92 | It's no mistake that generators can be used in this way. [Nikita Popov](https://github.com/nikic) (who is responsible 93 | for the original generator implementation in PHP) published an [excellent article](http://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html) 94 | explaining generator-based coroutines. The article even includes an example implementation of a coroutine scheduler, 95 | though it takes a somewhat different approach. 96 | 97 | ### Strands 98 | 99 | A _Strand_ is Recoil's equivalent to your operating system's threads. Each strand has its own call-stack and may be 100 | suspended, resumed, joined and terminated without affecting other strands. The elements on the call-stack are not 101 | regular functions, but are instead coroutines. 102 | 103 | Unlike threads, execution of a strand can only suspend or resume when a coroutine specifically requests to do so, hence 104 | the term _cooperative multitasking_. 105 | 106 | Strands are very light-weight and are sometimes known as [green threads](http://en.wikipedia.org/wiki/Green_threads), or 107 | (perhaps less correctly) as [fibers](https://en.wikipedia.org/wiki/Fiber_(computer_science)). 108 | 109 | Recoil's concept of the strand is defined by the [Strand](https://github.com/recoilphp/api/blob/master/src/Strand.php) interface. 110 | 111 | ### Dispatchable Values 112 | 113 | An _Dispatchable Value_ is any value that Recoil recognises when yielded by a coroutine. For example, yielding another generator 114 | pushes that generator onto the current strand's call-stack and invokes it, thus making it a coroutine. 115 | 116 | The [Recoil facade](https://github.com/recoilphp/api/blob/master/src/Recoil.php) class describes the complete list of 117 | supported values. 118 | 119 | ### The Kernel and Kernel API 120 | 121 | The _kernel_ is responsible for creating and scheduling strands, much like the operating system kernel does for threads. 122 | 123 | The kernel and strands are manipulated using the _kernel API_, which is a set of standard operations defined in the 124 | [Recoil API](https://github.com/recoilphp/api) and accessible using the [Recoil facade](https://github.com/recoilphp/api/blob/master/src/Recoil.php). 125 | 126 | There are multiple kernel implementations available. This repository contains a stand-alone implementation based on 127 | `stream_select()`. The [`recoil/react` package](https://github.com/recoilphp/react) provides a kernel based on the [ReactPHP](https://github.com/reactphp/react) event-loop. 128 | 129 | ## Examples 130 | 131 | The following examples illustrate the basic usage of coroutines and the kernel API. Additional examples are available in 132 | the [examples folder](examples/). 133 | 134 | References to `Recoil` and `ReactKernel` refer to the [Recoil facade](https://github.com/recoilphp/api/blob/master/src/Recoil.php), 135 | and the [React kernel implementation](https://github.com/recoilphp/react), 136 | respectively. 137 | 138 | ### Basic execution 139 | 140 | The following example shows the simplest way to execute a generator as a coroutine. 141 | 142 | ```php 143 | ReactKernel::start( 144 | function () { 145 | echo 'Hello, world!' . PHP_EOL; 146 | yield; 147 | } 148 | ); 149 | ``` 150 | 151 | `ReactKernel::start()` is a convenience method that instantiates the React-based kernel and executes the given coroutine 152 | in a new strand. Yielding `null` (via `yield` with no explicit value) allows PHP to parse the function as a generator, 153 | and allows the kernel to process other strands, though there are none in this example. 154 | 155 | ### Calling one coroutine from another 156 | 157 | A coroutine can be invoked by simply yielding it, as described in the section on coroutines above. You can also use the 158 | `yield from` syntax, which may perform better but only works with generators, whereas `yield` works with any dispatchable 159 | value. 160 | 161 | ```php 162 | function hello() 163 | { 164 | echo 'Hello, '; 165 | yield; 166 | } 167 | 168 | function world() 169 | { 170 | echo 'world!' . PHP_EOL; 171 | yield; 172 | } 173 | 174 | ReactKernel::start(function () { 175 | yield hello(); 176 | yield world(); 177 | }); 178 | ``` 179 | 180 | ### Returning a value from a coroutine 181 | 182 | To return a value from a coroutine, simply use the `return` keyword as you would in a normal function. 183 | 184 | ```php 185 | function multiply($a, $b) 186 | { 187 | yield; // force PHP to parse this function as a generator 188 | return $a * $b; 189 | echo 'This code is never reached.'; 190 | } 191 | 192 | ReactKernel::start(function () { 193 | $result = yield multiply(2, 3); 194 | echo '2 * 3 is ' . $result . PHP_EOL; 195 | }); 196 | ``` 197 | 198 | ### Throwing and catching exceptions 199 | 200 | One of the major syntactic advantages of coroutines over callbacks is that errors can be reported using familiar 201 | exception handling techniques. The `throw` keyword can be used in in a coroutine just as it can in a regular function. 202 | 203 | ```php 204 | function multiply($a, $b) 205 | { 206 | if (!is_numeric($a) || !is_numeric($b)) { 207 | throw new InvalidArgumentException(); 208 | } 209 | 210 | yield; // force PHP to parse this function as a generator 211 | return $a * $b; 212 | } 213 | 214 | ReactKernel::start(function() { 215 | try { 216 | yield multiply(1, 'foo'); 217 | } catch (InvalidArgumentException $e) { 218 | echo 'Invalid argument!'; 219 | } 220 | }); 221 | ``` 222 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: off 2 | coverage: 3 | status: 4 | project: 5 | default: 6 | target: auto 7 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "recoil/recoil", 3 | "description": "Asynchronous coroutines for PHP 7.", 4 | "require": { 5 | "php": "^7.4", 6 | "recoil/api": "^1", 7 | "recoil/kernel": "^1.0.2" 8 | }, 9 | "require-dev": { 10 | "eloquent/phony": "^5", 11 | "friendsofphp/php-cs-fixer": "^2", 12 | "peridot-php/leo": "dev-php-8 as 1.999.999", 13 | "peridot-php/peridot": "dev-php-8 as 1.999.999", 14 | "peridot-php/peridot-code-coverage-reporters": "dev-php-8 as 2.999.999", 15 | "react/dns": "^0.4", 16 | "recoil/dev": "^0.4", 17 | "recoil/react": "^1" 18 | }, 19 | "repositories": [ 20 | { 21 | "type": "vcs", 22 | "url": "https://github.com/recoilphp/leo" 23 | }, 24 | { 25 | "type": "vcs", 26 | "url": "https://github.com/recoilphp/peridot" 27 | }, 28 | { 29 | "type": "vcs", 30 | "url": "https://github.com/recoilphp/peridot-code-coverage-reporters" 31 | } 32 | ], 33 | "autoload": { 34 | "psr-4": { 35 | "Recoil\\ReferenceKernel\\": "src" 36 | } 37 | }, 38 | "autoload-dev": { 39 | "psr-4": { 40 | "Recoil\\ReferenceKernel\\": "test/src" 41 | } 42 | }, 43 | "keywords": [ 44 | "coroutine", 45 | "generator", 46 | "event", 47 | "async", 48 | "asynchronous", 49 | "react", 50 | "green", 51 | "thread", 52 | "multitasking", 53 | "continuation" 54 | ], 55 | "homepage": "https://github.com/recoilphp/recoil", 56 | "license": "MIT", 57 | "authors": [ 58 | { 59 | "name": "James Harris", 60 | "email": "james.harris@icecave.com.au", 61 | "homepage": "https://github.com/jmalloc" 62 | } 63 | ], 64 | "config": { 65 | "sort-packages": true, 66 | "platform": { 67 | "php": "7.4" 68 | }, 69 | "allow-plugins": { 70 | "recoil/dev": true 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "8cefccee29d15bff2a4366625eaec9bf", 8 | "packages": [ 9 | { 10 | "name": "icecave/repr", 11 | "version": "4.0.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/icecave/repr.git", 15 | "reference": "3dad35ee43394404ae0f1926d754e7b7820da8e4" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/icecave/repr/zipball/3dad35ee43394404ae0f1926d754e7b7820da8e4", 20 | "reference": "3dad35ee43394404ae0f1926d754e7b7820da8e4", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=7.2" 25 | }, 26 | "require-dev": { 27 | "eloquent/phony-phpunit": "^6", 28 | "friendsofphp/php-cs-fixer": "^2", 29 | "phpunit/phpunit": "^8" 30 | }, 31 | "type": "library", 32 | "autoload": { 33 | "psr-4": { 34 | "Icecave\\Repr\\": "src" 35 | } 36 | }, 37 | "notification-url": "https://packagist.org/downloads/", 38 | "license": [ 39 | "MIT" 40 | ], 41 | "authors": [ 42 | { 43 | "name": "James Harris", 44 | "email": "mailjamesharris@gmail.com", 45 | "homepage": "https://github.com/jmalloc" 46 | } 47 | ], 48 | "description": "A library for generating string representations of any value, inspired by Python's reprlib library.", 49 | "homepage": "https://github.com/icecave/repr", 50 | "keywords": [ 51 | "human", 52 | "readable", 53 | "repr", 54 | "representation", 55 | "string" 56 | ], 57 | "support": { 58 | "issues": "https://github.com/icecave/repr/issues", 59 | "source": "https://github.com/icecave/repr/tree/4.0.0" 60 | }, 61 | "time": "2020-08-25T02:05:11+00:00" 62 | }, 63 | { 64 | "name": "recoil/api", 65 | "version": "1.0.2", 66 | "source": { 67 | "type": "git", 68 | "url": "https://github.com/recoilphp/api.git", 69 | "reference": "4f9b3f2638157e277606fe51718c3a0106da7807" 70 | }, 71 | "dist": { 72 | "type": "zip", 73 | "url": "https://api.github.com/repos/recoilphp/api/zipball/4f9b3f2638157e277606fe51718c3a0106da7807", 74 | "reference": "4f9b3f2638157e277606fe51718c3a0106da7807", 75 | "shasum": "" 76 | }, 77 | "require": { 78 | "php": ">=7.3" 79 | }, 80 | "require-dev": { 81 | "eloquent/phony": "^5", 82 | "eloquent/phony-phpunit": "^7", 83 | "friendsofphp/php-cs-fixer": "^2", 84 | "phpunit/phpunit": "^9" 85 | }, 86 | "type": "library", 87 | "autoload": { 88 | "psr-4": { 89 | "Recoil\\": "src" 90 | } 91 | }, 92 | "notification-url": "https://packagist.org/downloads/", 93 | "license": [ 94 | "MIT" 95 | ], 96 | "authors": [ 97 | { 98 | "name": "James Harris", 99 | "email": "mailjamesharris@gmail.com", 100 | "homepage": "https://github.com/jmalloc" 101 | } 102 | ], 103 | "description": "The public Recoil API, for library and application developers.", 104 | "homepage": "https://github.com/recoilphp/api", 105 | "keywords": [ 106 | "Thread", 107 | "async", 108 | "asynchronous", 109 | "continuation", 110 | "coroutine", 111 | "event", 112 | "generator", 113 | "green", 114 | "multitasking", 115 | "react" 116 | ], 117 | "support": { 118 | "issues": "https://github.com/recoilphp/api/issues", 119 | "source": "https://github.com/recoilphp/api/tree/1.0.2" 120 | }, 121 | "time": "2020-12-22T00:48:27+00:00" 122 | }, 123 | { 124 | "name": "recoil/kernel", 125 | "version": "1.0.5", 126 | "source": { 127 | "type": "git", 128 | "url": "https://github.com/recoilphp/kernel.git", 129 | "reference": "aa80bf44a25a5be5c1fa7a2bb53def27a81fc188" 130 | }, 131 | "dist": { 132 | "type": "zip", 133 | "url": "https://api.github.com/repos/recoilphp/kernel/zipball/aa80bf44a25a5be5c1fa7a2bb53def27a81fc188", 134 | "reference": "aa80bf44a25a5be5c1fa7a2bb53def27a81fc188", 135 | "shasum": "" 136 | }, 137 | "require": { 138 | "icecave/repr": "^4|^3|^2", 139 | "php": ">=7.4", 140 | "recoil/api": "^1.0.2" 141 | }, 142 | "require-dev": { 143 | "eloquent/phony": "^5", 144 | "friendsofphp/php-cs-fixer": "^2", 145 | "hamcrest/hamcrest-php": "^2", 146 | "peridot-php/leo": "dev-php-8 as 1.999.999", 147 | "peridot-php/peridot": "dev-php-8 as 1.999.999", 148 | "peridot-php/peridot-code-coverage-reporters": "dev-php-8 as 2.999.999" 149 | }, 150 | "type": "library", 151 | "autoload": { 152 | "psr-4": { 153 | "Recoil\\Kernel\\": "src" 154 | } 155 | }, 156 | "notification-url": "https://packagist.org/downloads/", 157 | "license": [ 158 | "MIT" 159 | ], 160 | "authors": [ 161 | { 162 | "name": "James Harris", 163 | "email": "james.harris@icecave.com.au", 164 | "homepage": "https://github.com/jmalloc" 165 | } 166 | ], 167 | "description": "Reusable components for implementing Recoil kernels.", 168 | "homepage": "https://github.com/recoilphp/kernel", 169 | "keywords": [ 170 | "Thread", 171 | "async", 172 | "asynchronous", 173 | "continuation", 174 | "coroutine", 175 | "event", 176 | "generator", 177 | "green", 178 | "multitasking", 179 | "react" 180 | ], 181 | "support": { 182 | "issues": "https://github.com/recoilphp/kernel/issues", 183 | "source": "https://github.com/recoilphp/kernel/tree/1.0.5" 184 | }, 185 | "time": "2022-03-06T02:46:48+00:00" 186 | } 187 | ], 188 | "packages-dev": [ 189 | { 190 | "name": "composer/pcre", 191 | "version": "1.0.1", 192 | "source": { 193 | "type": "git", 194 | "url": "https://github.com/composer/pcre.git", 195 | "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560" 196 | }, 197 | "dist": { 198 | "type": "zip", 199 | "url": "https://api.github.com/repos/composer/pcre/zipball/67a32d7d6f9f560b726ab25a061b38ff3a80c560", 200 | "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560", 201 | "shasum": "" 202 | }, 203 | "require": { 204 | "php": "^5.3.2 || ^7.0 || ^8.0" 205 | }, 206 | "require-dev": { 207 | "phpstan/phpstan": "^1.3", 208 | "phpstan/phpstan-strict-rules": "^1.1", 209 | "symfony/phpunit-bridge": "^4.2 || ^5" 210 | }, 211 | "type": "library", 212 | "extra": { 213 | "branch-alias": { 214 | "dev-main": "1.x-dev" 215 | } 216 | }, 217 | "autoload": { 218 | "psr-4": { 219 | "Composer\\Pcre\\": "src" 220 | } 221 | }, 222 | "notification-url": "https://packagist.org/downloads/", 223 | "license": [ 224 | "MIT" 225 | ], 226 | "authors": [ 227 | { 228 | "name": "Jordi Boggiano", 229 | "email": "j.boggiano@seld.be", 230 | "homepage": "http://seld.be" 231 | } 232 | ], 233 | "description": "PCRE wrapping library that offers type-safe preg_* replacements.", 234 | "keywords": [ 235 | "PCRE", 236 | "preg", 237 | "regex", 238 | "regular expression" 239 | ], 240 | "support": { 241 | "issues": "https://github.com/composer/pcre/issues", 242 | "source": "https://github.com/composer/pcre/tree/1.0.1" 243 | }, 244 | "funding": [ 245 | { 246 | "url": "https://packagist.com", 247 | "type": "custom" 248 | }, 249 | { 250 | "url": "https://github.com/composer", 251 | "type": "github" 252 | }, 253 | { 254 | "url": "https://tidelift.com/funding/github/packagist/composer/composer", 255 | "type": "tidelift" 256 | } 257 | ], 258 | "time": "2022-01-21T20:24:37+00:00" 259 | }, 260 | { 261 | "name": "composer/semver", 262 | "version": "3.2.9", 263 | "source": { 264 | "type": "git", 265 | "url": "https://github.com/composer/semver.git", 266 | "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649" 267 | }, 268 | "dist": { 269 | "type": "zip", 270 | "url": "https://api.github.com/repos/composer/semver/zipball/a951f614bd64dcd26137bc9b7b2637ddcfc57649", 271 | "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649", 272 | "shasum": "" 273 | }, 274 | "require": { 275 | "php": "^5.3.2 || ^7.0 || ^8.0" 276 | }, 277 | "require-dev": { 278 | "phpstan/phpstan": "^1.4", 279 | "symfony/phpunit-bridge": "^4.2 || ^5" 280 | }, 281 | "type": "library", 282 | "extra": { 283 | "branch-alias": { 284 | "dev-main": "3.x-dev" 285 | } 286 | }, 287 | "autoload": { 288 | "psr-4": { 289 | "Composer\\Semver\\": "src" 290 | } 291 | }, 292 | "notification-url": "https://packagist.org/downloads/", 293 | "license": [ 294 | "MIT" 295 | ], 296 | "authors": [ 297 | { 298 | "name": "Nils Adermann", 299 | "email": "naderman@naderman.de", 300 | "homepage": "http://www.naderman.de" 301 | }, 302 | { 303 | "name": "Jordi Boggiano", 304 | "email": "j.boggiano@seld.be", 305 | "homepage": "http://seld.be" 306 | }, 307 | { 308 | "name": "Rob Bast", 309 | "email": "rob.bast@gmail.com", 310 | "homepage": "http://robbast.nl" 311 | } 312 | ], 313 | "description": "Semver library that offers utilities, version constraint parsing and validation.", 314 | "keywords": [ 315 | "semantic", 316 | "semver", 317 | "validation", 318 | "versioning" 319 | ], 320 | "support": { 321 | "irc": "irc://irc.freenode.org/composer", 322 | "issues": "https://github.com/composer/semver/issues", 323 | "source": "https://github.com/composer/semver/tree/3.2.9" 324 | }, 325 | "funding": [ 326 | { 327 | "url": "https://packagist.com", 328 | "type": "custom" 329 | }, 330 | { 331 | "url": "https://github.com/composer", 332 | "type": "github" 333 | }, 334 | { 335 | "url": "https://tidelift.com/funding/github/packagist/composer/composer", 336 | "type": "tidelift" 337 | } 338 | ], 339 | "time": "2022-02-04T13:58:43+00:00" 340 | }, 341 | { 342 | "name": "composer/xdebug-handler", 343 | "version": "2.0.5", 344 | "source": { 345 | "type": "git", 346 | "url": "https://github.com/composer/xdebug-handler.git", 347 | "reference": "9e36aeed4616366d2b690bdce11f71e9178c579a" 348 | }, 349 | "dist": { 350 | "type": "zip", 351 | "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/9e36aeed4616366d2b690bdce11f71e9178c579a", 352 | "reference": "9e36aeed4616366d2b690bdce11f71e9178c579a", 353 | "shasum": "" 354 | }, 355 | "require": { 356 | "composer/pcre": "^1", 357 | "php": "^5.3.2 || ^7.0 || ^8.0", 358 | "psr/log": "^1 || ^2 || ^3" 359 | }, 360 | "require-dev": { 361 | "phpstan/phpstan": "^1.0", 362 | "phpstan/phpstan-strict-rules": "^1.1", 363 | "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" 364 | }, 365 | "type": "library", 366 | "autoload": { 367 | "psr-4": { 368 | "Composer\\XdebugHandler\\": "src" 369 | } 370 | }, 371 | "notification-url": "https://packagist.org/downloads/", 372 | "license": [ 373 | "MIT" 374 | ], 375 | "authors": [ 376 | { 377 | "name": "John Stevenson", 378 | "email": "john-stevenson@blueyonder.co.uk" 379 | } 380 | ], 381 | "description": "Restarts a process without Xdebug.", 382 | "keywords": [ 383 | "Xdebug", 384 | "performance" 385 | ], 386 | "support": { 387 | "irc": "irc://irc.freenode.org/composer", 388 | "issues": "https://github.com/composer/xdebug-handler/issues", 389 | "source": "https://github.com/composer/xdebug-handler/tree/2.0.5" 390 | }, 391 | "funding": [ 392 | { 393 | "url": "https://packagist.com", 394 | "type": "custom" 395 | }, 396 | { 397 | "url": "https://github.com/composer", 398 | "type": "github" 399 | }, 400 | { 401 | "url": "https://tidelift.com/funding/github/packagist/composer/composer", 402 | "type": "tidelift" 403 | } 404 | ], 405 | "time": "2022-02-24T20:20:32+00:00" 406 | }, 407 | { 408 | "name": "doctrine/annotations", 409 | "version": "1.13.2", 410 | "source": { 411 | "type": "git", 412 | "url": "https://github.com/doctrine/annotations.git", 413 | "reference": "5b668aef16090008790395c02c893b1ba13f7e08" 414 | }, 415 | "dist": { 416 | "type": "zip", 417 | "url": "https://api.github.com/repos/doctrine/annotations/zipball/5b668aef16090008790395c02c893b1ba13f7e08", 418 | "reference": "5b668aef16090008790395c02c893b1ba13f7e08", 419 | "shasum": "" 420 | }, 421 | "require": { 422 | "doctrine/lexer": "1.*", 423 | "ext-tokenizer": "*", 424 | "php": "^7.1 || ^8.0", 425 | "psr/cache": "^1 || ^2 || ^3" 426 | }, 427 | "require-dev": { 428 | "doctrine/cache": "^1.11 || ^2.0", 429 | "doctrine/coding-standard": "^6.0 || ^8.1", 430 | "phpstan/phpstan": "^0.12.20", 431 | "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", 432 | "symfony/cache": "^4.4 || ^5.2" 433 | }, 434 | "type": "library", 435 | "autoload": { 436 | "psr-4": { 437 | "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" 438 | } 439 | }, 440 | "notification-url": "https://packagist.org/downloads/", 441 | "license": [ 442 | "MIT" 443 | ], 444 | "authors": [ 445 | { 446 | "name": "Guilherme Blanco", 447 | "email": "guilhermeblanco@gmail.com" 448 | }, 449 | { 450 | "name": "Roman Borschel", 451 | "email": "roman@code-factory.org" 452 | }, 453 | { 454 | "name": "Benjamin Eberlei", 455 | "email": "kontakt@beberlei.de" 456 | }, 457 | { 458 | "name": "Jonathan Wage", 459 | "email": "jonwage@gmail.com" 460 | }, 461 | { 462 | "name": "Johannes Schmitt", 463 | "email": "schmittjoh@gmail.com" 464 | } 465 | ], 466 | "description": "Docblock Annotations Parser", 467 | "homepage": "https://www.doctrine-project.org/projects/annotations.html", 468 | "keywords": [ 469 | "annotations", 470 | "docblock", 471 | "parser" 472 | ], 473 | "support": { 474 | "issues": "https://github.com/doctrine/annotations/issues", 475 | "source": "https://github.com/doctrine/annotations/tree/1.13.2" 476 | }, 477 | "time": "2021-08-05T19:00:23+00:00" 478 | }, 479 | { 480 | "name": "doctrine/lexer", 481 | "version": "1.2.3", 482 | "source": { 483 | "type": "git", 484 | "url": "https://github.com/doctrine/lexer.git", 485 | "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" 486 | }, 487 | "dist": { 488 | "type": "zip", 489 | "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", 490 | "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", 491 | "shasum": "" 492 | }, 493 | "require": { 494 | "php": "^7.1 || ^8.0" 495 | }, 496 | "require-dev": { 497 | "doctrine/coding-standard": "^9.0", 498 | "phpstan/phpstan": "^1.3", 499 | "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", 500 | "vimeo/psalm": "^4.11" 501 | }, 502 | "type": "library", 503 | "autoload": { 504 | "psr-4": { 505 | "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" 506 | } 507 | }, 508 | "notification-url": "https://packagist.org/downloads/", 509 | "license": [ 510 | "MIT" 511 | ], 512 | "authors": [ 513 | { 514 | "name": "Guilherme Blanco", 515 | "email": "guilhermeblanco@gmail.com" 516 | }, 517 | { 518 | "name": "Roman Borschel", 519 | "email": "roman@code-factory.org" 520 | }, 521 | { 522 | "name": "Johannes Schmitt", 523 | "email": "schmittjoh@gmail.com" 524 | } 525 | ], 526 | "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", 527 | "homepage": "https://www.doctrine-project.org/projects/lexer.html", 528 | "keywords": [ 529 | "annotations", 530 | "docblock", 531 | "lexer", 532 | "parser", 533 | "php" 534 | ], 535 | "support": { 536 | "issues": "https://github.com/doctrine/lexer/issues", 537 | "source": "https://github.com/doctrine/lexer/tree/1.2.3" 538 | }, 539 | "funding": [ 540 | { 541 | "url": "https://www.doctrine-project.org/sponsorship.html", 542 | "type": "custom" 543 | }, 544 | { 545 | "url": "https://www.patreon.com/phpdoctrine", 546 | "type": "patreon" 547 | }, 548 | { 549 | "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", 550 | "type": "tidelift" 551 | } 552 | ], 553 | "time": "2022-02-28T11:07:21+00:00" 554 | }, 555 | { 556 | "name": "eloquent/enumeration", 557 | "version": "5.1.1", 558 | "source": { 559 | "type": "git", 560 | "url": "https://github.com/eloquent/enumeration.git", 561 | "reference": "0242859435d9b135939816858348556d3cde9e3c" 562 | }, 563 | "dist": { 564 | "type": "zip", 565 | "url": "https://api.github.com/repos/eloquent/enumeration/zipball/0242859435d9b135939816858348556d3cde9e3c", 566 | "reference": "0242859435d9b135939816858348556d3cde9e3c", 567 | "shasum": "" 568 | }, 569 | "require": { 570 | "php": ">=5.3" 571 | }, 572 | "require-dev": { 573 | "icecave/archer": "dev-develop", 574 | "phpunit/phpunit": "^4", 575 | "sami/sami": "^3" 576 | }, 577 | "type": "library", 578 | "autoload": { 579 | "psr-4": { 580 | "Eloquent\\Enumeration\\": "src" 581 | } 582 | }, 583 | "notification-url": "https://packagist.org/downloads/", 584 | "license": [ 585 | "MIT" 586 | ], 587 | "authors": [ 588 | { 589 | "name": "Erin Millard", 590 | "email": "ezzatron@gmail.com", 591 | "homepage": "http://ezzatron.com/" 592 | } 593 | ], 594 | "description": "An enumeration implementation for PHP.", 595 | "homepage": "https://github.com/eloquent/enumeration", 596 | "keywords": [ 597 | "class", 598 | "enum", 599 | "enumeration", 600 | "multiton", 601 | "set", 602 | "type" 603 | ], 604 | "support": { 605 | "issues": "https://github.com/eloquent/enumeration/issues", 606 | "source": "https://github.com/eloquent/enumeration/tree/master" 607 | }, 608 | "time": "2015-11-03T22:21:38+00:00" 609 | }, 610 | { 611 | "name": "eloquent/phony", 612 | "version": "5.0.2", 613 | "source": { 614 | "type": "git", 615 | "url": "https://github.com/eloquent/phony.git", 616 | "reference": "f34d67d6db6b6f351ea7e8aa8066107e756ec26b" 617 | }, 618 | "dist": { 619 | "type": "zip", 620 | "url": "https://api.github.com/repos/eloquent/phony/zipball/f34d67d6db6b6f351ea7e8aa8066107e756ec26b", 621 | "reference": "f34d67d6db6b6f351ea7e8aa8066107e756ec26b", 622 | "shasum": "" 623 | }, 624 | "require": { 625 | "php": "^7.3 || ^8" 626 | }, 627 | "require-dev": { 628 | "eloquent/code-style": "^1.0", 629 | "eloquent/phpstan-phony": "^0.7", 630 | "errors/exceptions": "^0.2", 631 | "ext-pdo": "*", 632 | "friendsofphp/php-cs-fixer": "^2", 633 | "hamcrest/hamcrest-php": "^2", 634 | "phpstan/extension-installer": "^1", 635 | "phpstan/phpstan": "^0.12", 636 | "phpstan/phpstan-phpunit": "^0.12", 637 | "phpunit/phpunit": "^9" 638 | }, 639 | "type": "library", 640 | "extra": { 641 | "branch-alias": { 642 | "dev-master": "5.1.x-dev" 643 | } 644 | }, 645 | "autoload": { 646 | "files": [ 647 | "src/initialize.php", 648 | "src/functions.php" 649 | ], 650 | "psr-4": { 651 | "Eloquent\\Phony\\": "src" 652 | } 653 | }, 654 | "notification-url": "https://packagist.org/downloads/", 655 | "license": [ 656 | "MIT" 657 | ], 658 | "authors": [ 659 | { 660 | "name": "Erin Millard", 661 | "email": "ezzatron@gmail.com", 662 | "homepage": "http://ezzatron.com/" 663 | } 664 | ], 665 | "description": "Mocks, stubs, and spies for PHP.", 666 | "homepage": "http://eloquent-software.com/phony/", 667 | "keywords": [ 668 | "Double", 669 | "Dummy", 670 | "fake", 671 | "mock", 672 | "mocking", 673 | "spy", 674 | "stub", 675 | "stubbing", 676 | "test" 677 | ], 678 | "support": { 679 | "issues": "https://github.com/eloquent/phony/issues", 680 | "source": "https://github.com/eloquent/phony/tree/5.0.2" 681 | }, 682 | "time": "2021-02-17T01:45:10+00:00" 683 | }, 684 | { 685 | "name": "evenement/evenement", 686 | "version": "v3.0.1", 687 | "source": { 688 | "type": "git", 689 | "url": "https://github.com/igorw/evenement.git", 690 | "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7" 691 | }, 692 | "dist": { 693 | "type": "zip", 694 | "url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7", 695 | "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7", 696 | "shasum": "" 697 | }, 698 | "require": { 699 | "php": ">=7.0" 700 | }, 701 | "require-dev": { 702 | "phpunit/phpunit": "^6.0" 703 | }, 704 | "type": "library", 705 | "autoload": { 706 | "psr-0": { 707 | "Evenement": "src" 708 | } 709 | }, 710 | "notification-url": "https://packagist.org/downloads/", 711 | "license": [ 712 | "MIT" 713 | ], 714 | "authors": [ 715 | { 716 | "name": "Igor Wiedler", 717 | "email": "igor@wiedler.ch" 718 | } 719 | ], 720 | "description": "Événement is a very simple event dispatching library for PHP", 721 | "keywords": [ 722 | "event-dispatcher", 723 | "event-emitter" 724 | ], 725 | "support": { 726 | "issues": "https://github.com/igorw/evenement/issues", 727 | "source": "https://github.com/igorw/evenement/tree/master" 728 | }, 729 | "time": "2017-07-23T21:35:13+00:00" 730 | }, 731 | { 732 | "name": "friendsofphp/php-cs-fixer", 733 | "version": "v2.19.3", 734 | "source": { 735 | "type": "git", 736 | "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", 737 | "reference": "75ac86f33fab4714ea5a39a396784d83ae3b5ed8" 738 | }, 739 | "dist": { 740 | "type": "zip", 741 | "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/75ac86f33fab4714ea5a39a396784d83ae3b5ed8", 742 | "reference": "75ac86f33fab4714ea5a39a396784d83ae3b5ed8", 743 | "shasum": "" 744 | }, 745 | "require": { 746 | "composer/semver": "^1.4 || ^2.0 || ^3.0", 747 | "composer/xdebug-handler": "^1.2 || ^2.0", 748 | "doctrine/annotations": "^1.2", 749 | "ext-json": "*", 750 | "ext-tokenizer": "*", 751 | "php": "^5.6 || ^7.0 || ^8.0", 752 | "php-cs-fixer/diff": "^1.3", 753 | "symfony/console": "^3.4.43 || ^4.1.6 || ^5.0", 754 | "symfony/event-dispatcher": "^3.0 || ^4.0 || ^5.0", 755 | "symfony/filesystem": "^3.0 || ^4.0 || ^5.0", 756 | "symfony/finder": "^3.0 || ^4.0 || ^5.0", 757 | "symfony/options-resolver": "^3.0 || ^4.0 || ^5.0", 758 | "symfony/polyfill-php70": "^1.0", 759 | "symfony/polyfill-php72": "^1.4", 760 | "symfony/process": "^3.0 || ^4.0 || ^5.0", 761 | "symfony/stopwatch": "^3.0 || ^4.0 || ^5.0" 762 | }, 763 | "require-dev": { 764 | "justinrainbow/json-schema": "^5.0", 765 | "keradus/cli-executor": "^1.4", 766 | "mikey179/vfsstream": "^1.6", 767 | "php-coveralls/php-coveralls": "^2.4.2", 768 | "php-cs-fixer/accessible-object": "^1.0", 769 | "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", 770 | "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", 771 | "phpspec/prophecy-phpunit": "^1.1 || ^2.0", 772 | "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.13 || ^9.5", 773 | "phpunitgoodpractices/polyfill": "^1.5", 774 | "phpunitgoodpractices/traits": "^1.9.1", 775 | "sanmai/phpunit-legacy-adapter": "^6.4 || ^8.2.1", 776 | "symfony/phpunit-bridge": "^5.2.1", 777 | "symfony/yaml": "^3.0 || ^4.0 || ^5.0" 778 | }, 779 | "suggest": { 780 | "ext-dom": "For handling output formats in XML", 781 | "ext-mbstring": "For handling non-UTF8 characters.", 782 | "php-cs-fixer/phpunit-constraint-isidenticalstring": "For IsIdenticalString constraint.", 783 | "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "For XmlMatchesXsd constraint.", 784 | "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." 785 | }, 786 | "bin": [ 787 | "php-cs-fixer" 788 | ], 789 | "type": "application", 790 | "extra": { 791 | "branch-alias": { 792 | "dev-master": "2.19-dev" 793 | } 794 | }, 795 | "autoload": { 796 | "psr-4": { 797 | "PhpCsFixer\\": "src/" 798 | }, 799 | "classmap": [ 800 | "tests/Test/AbstractFixerTestCase.php", 801 | "tests/Test/AbstractIntegrationCaseFactory.php", 802 | "tests/Test/AbstractIntegrationTestCase.php", 803 | "tests/Test/Assert/AssertTokensTrait.php", 804 | "tests/Test/IntegrationCase.php", 805 | "tests/Test/IntegrationCaseFactory.php", 806 | "tests/Test/IntegrationCaseFactoryInterface.php", 807 | "tests/Test/InternalIntegrationCaseFactory.php", 808 | "tests/Test/IsIdenticalConstraint.php", 809 | "tests/Test/TokensWithObservedTransformers.php", 810 | "tests/TestCase.php" 811 | ] 812 | }, 813 | "notification-url": "https://packagist.org/downloads/", 814 | "license": [ 815 | "MIT" 816 | ], 817 | "authors": [ 818 | { 819 | "name": "Fabien Potencier", 820 | "email": "fabien@symfony.com" 821 | }, 822 | { 823 | "name": "Dariusz Rumiński", 824 | "email": "dariusz.ruminski@gmail.com" 825 | } 826 | ], 827 | "description": "A tool to automatically fix PHP code style", 828 | "support": { 829 | "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", 830 | "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v2.19.3" 831 | }, 832 | "funding": [ 833 | { 834 | "url": "https://github.com/keradus", 835 | "type": "github" 836 | } 837 | ], 838 | "time": "2021-11-15T17:17:55+00:00" 839 | }, 840 | { 841 | "name": "hamcrest/hamcrest-php", 842 | "version": "v2.0.1", 843 | "source": { 844 | "type": "git", 845 | "url": "https://github.com/hamcrest/hamcrest-php.git", 846 | "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" 847 | }, 848 | "dist": { 849 | "type": "zip", 850 | "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", 851 | "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", 852 | "shasum": "" 853 | }, 854 | "require": { 855 | "php": "^5.3|^7.0|^8.0" 856 | }, 857 | "replace": { 858 | "cordoval/hamcrest-php": "*", 859 | "davedevelopment/hamcrest-php": "*", 860 | "kodova/hamcrest-php": "*" 861 | }, 862 | "require-dev": { 863 | "phpunit/php-file-iterator": "^1.4 || ^2.0", 864 | "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" 865 | }, 866 | "type": "library", 867 | "extra": { 868 | "branch-alias": { 869 | "dev-master": "2.1-dev" 870 | } 871 | }, 872 | "autoload": { 873 | "classmap": [ 874 | "hamcrest" 875 | ] 876 | }, 877 | "notification-url": "https://packagist.org/downloads/", 878 | "license": [ 879 | "BSD-3-Clause" 880 | ], 881 | "description": "This is the PHP port of Hamcrest Matchers", 882 | "keywords": [ 883 | "test" 884 | ], 885 | "support": { 886 | "issues": "https://github.com/hamcrest/hamcrest-php/issues", 887 | "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" 888 | }, 889 | "time": "2020-07-09T08:09:16+00:00" 890 | }, 891 | { 892 | "name": "nikic/php-parser", 893 | "version": "v4.13.2", 894 | "source": { 895 | "type": "git", 896 | "url": "https://github.com/nikic/PHP-Parser.git", 897 | "reference": "210577fe3cf7badcc5814d99455df46564f3c077" 898 | }, 899 | "dist": { 900 | "type": "zip", 901 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", 902 | "reference": "210577fe3cf7badcc5814d99455df46564f3c077", 903 | "shasum": "" 904 | }, 905 | "require": { 906 | "ext-tokenizer": "*", 907 | "php": ">=7.0" 908 | }, 909 | "require-dev": { 910 | "ircmaxell/php-yacc": "^0.0.7", 911 | "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" 912 | }, 913 | "bin": [ 914 | "bin/php-parse" 915 | ], 916 | "type": "library", 917 | "extra": { 918 | "branch-alias": { 919 | "dev-master": "4.9-dev" 920 | } 921 | }, 922 | "autoload": { 923 | "psr-4": { 924 | "PhpParser\\": "lib/PhpParser" 925 | } 926 | }, 927 | "notification-url": "https://packagist.org/downloads/", 928 | "license": [ 929 | "BSD-3-Clause" 930 | ], 931 | "authors": [ 932 | { 933 | "name": "Nikita Popov" 934 | } 935 | ], 936 | "description": "A PHP parser written in PHP", 937 | "keywords": [ 938 | "parser", 939 | "php" 940 | ], 941 | "support": { 942 | "issues": "https://github.com/nikic/PHP-Parser/issues", 943 | "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" 944 | }, 945 | "time": "2021-11-30T19:35:32+00:00" 946 | }, 947 | { 948 | "name": "peridot-php/leo", 949 | "version": "dev-php-8", 950 | "source": { 951 | "type": "git", 952 | "url": "https://github.com/recoilphp/leo.git", 953 | "reference": "8a3d838fa0078715f2a2c69290af90570184e528" 954 | }, 955 | "dist": { 956 | "type": "zip", 957 | "url": "https://api.github.com/repos/recoilphp/leo/zipball/8a3d838fa0078715f2a2c69290af90570184e528", 958 | "reference": "8a3d838fa0078715f2a2c69290af90570184e528", 959 | "shasum": "" 960 | }, 961 | "require": { 962 | "php": ">=5.4" 963 | }, 964 | "require-dev": { 965 | "apigen/apigen": "^4", 966 | "friendsofphp/php-cs-fixer": "^1", 967 | "peridot-php/peridot-jumpstart": "^1", 968 | "peridot-php/peridot-prophecy-plugin": "^1" 969 | }, 970 | "type": "library", 971 | "autoload": { 972 | "psr-4": { 973 | "Peridot\\Leo\\": "src" 974 | }, 975 | "files": [ 976 | "src/Interfaces/_interface.bdd.php" 977 | ] 978 | }, 979 | "license": [ 980 | "MIT" 981 | ], 982 | "authors": [ 983 | { 984 | "name": "Brian Scaturro", 985 | "email": "scaturrob@gmail.com" 986 | } 987 | ], 988 | "description": "Next level assertion and matcher library for PHP", 989 | "keywords": [ 990 | "assert", 991 | "expect", 992 | "expectation", 993 | "matcher", 994 | "testing" 995 | ], 996 | "support": { 997 | "source": "https://github.com/recoilphp/leo/tree/php-8" 998 | }, 999 | "time": "2022-03-06T00:51:53+00:00" 1000 | }, 1001 | { 1002 | "name": "peridot-php/peridot", 1003 | "version": "dev-php-8", 1004 | "source": { 1005 | "type": "git", 1006 | "url": "https://github.com/recoilphp/peridot.git", 1007 | "reference": "2f0b3923e4a91fb42cb7dcda524b1b30df8ea39c" 1008 | }, 1009 | "dist": { 1010 | "type": "zip", 1011 | "url": "https://api.github.com/repos/recoilphp/peridot/zipball/2f0b3923e4a91fb42cb7dcda524b1b30df8ea39c", 1012 | "reference": "2f0b3923e4a91fb42cb7dcda524b1b30df8ea39c", 1013 | "shasum": "" 1014 | }, 1015 | "require": { 1016 | "evenement/evenement": "^3.0 || ^2.0", 1017 | "peridot-php/peridot-scope": "^1", 1018 | "php": ">=7.4", 1019 | "symfony/console": "^4" 1020 | }, 1021 | "require-dev": { 1022 | "consolidation/robo": "^0.4", 1023 | "phpunit/php-code-coverage": "^6" 1024 | }, 1025 | "bin": [ 1026 | "bin/peridot" 1027 | ], 1028 | "type": "library", 1029 | "autoload": { 1030 | "psr-4": { 1031 | "Peridot\\": "src/" 1032 | } 1033 | }, 1034 | "autoload-dev": { 1035 | "files": [ 1036 | "fixtures/error-polyfill.php" 1037 | ] 1038 | }, 1039 | "license": [ 1040 | "MIT" 1041 | ], 1042 | "authors": [ 1043 | { 1044 | "name": "Brian Scaturro", 1045 | "email": "scaturrob@gmail.com" 1046 | }, 1047 | { 1048 | "name": "Austin Morris", 1049 | "email": "austin.morris@gmail.com" 1050 | } 1051 | ], 1052 | "description": "Event driven BDD test framework for PHP 7.1+", 1053 | "keywords": [ 1054 | "BDD", 1055 | "PHP", 1056 | "TDD", 1057 | "testing" 1058 | ], 1059 | "support": { 1060 | "source": "https://github.com/recoilphp/peridot/tree/php-8" 1061 | }, 1062 | "time": "2022-03-06T01:10:58+00:00" 1063 | }, 1064 | { 1065 | "name": "peridot-php/peridot-code-coverage-reporters", 1066 | "version": "dev-php-8", 1067 | "source": { 1068 | "type": "git", 1069 | "url": "https://github.com/recoilphp/peridot-code-coverage-reporters.git", 1070 | "reference": "1aa2483130793834921d9b2090821476b8d72971" 1071 | }, 1072 | "dist": { 1073 | "type": "zip", 1074 | "url": "https://api.github.com/repos/recoilphp/peridot-code-coverage-reporters/zipball/1aa2483130793834921d9b2090821476b8d72971", 1075 | "reference": "1aa2483130793834921d9b2090821476b8d72971", 1076 | "shasum": "" 1077 | }, 1078 | "require": { 1079 | "peridot-php/peridot": "dev-php-8 as 1.999.999", 1080 | "phpunit/php-code-coverage": "^9" 1081 | }, 1082 | "type": "library", 1083 | "autoload": { 1084 | "psr-4": { 1085 | "Peridot\\Reporter\\": "src" 1086 | } 1087 | }, 1088 | "license": [ 1089 | "MIT" 1090 | ], 1091 | "authors": [ 1092 | { 1093 | "name": "Austin Morris", 1094 | "email": "austin.morris@gmail.com" 1095 | }, 1096 | { 1097 | "name": "Brian Scaturro", 1098 | "email": "scaturrob@gmail.com" 1099 | } 1100 | ], 1101 | "description": "Code coverage reporters for Peridot PHP.", 1102 | "support": { 1103 | "source": "https://github.com/recoilphp/peridot-code-coverage-reporters/tree/php-8" 1104 | }, 1105 | "time": "2022-03-06T02:35:33+00:00" 1106 | }, 1107 | { 1108 | "name": "peridot-php/peridot-scope", 1109 | "version": "1.3.0", 1110 | "source": { 1111 | "type": "git", 1112 | "url": "https://github.com/peridot-php/peridot-scope.git", 1113 | "reference": "b5cc7ac35b2116d0f495b326218e7e93a823ab8e" 1114 | }, 1115 | "dist": { 1116 | "type": "zip", 1117 | "url": "https://api.github.com/repos/peridot-php/peridot-scope/zipball/b5cc7ac35b2116d0f495b326218e7e93a823ab8e", 1118 | "reference": "b5cc7ac35b2116d0f495b326218e7e93a823ab8e", 1119 | "shasum": "" 1120 | }, 1121 | "require": { 1122 | "php": ">=5.4.0" 1123 | }, 1124 | "require-dev": { 1125 | "peridot-php/peridot-jumpstart": "~1.0" 1126 | }, 1127 | "type": "library", 1128 | "autoload": { 1129 | "psr-4": { 1130 | "Peridot\\Scope\\": "src/" 1131 | } 1132 | }, 1133 | "notification-url": "https://packagist.org/downloads/", 1134 | "license": [ 1135 | "MIT" 1136 | ], 1137 | "authors": [ 1138 | { 1139 | "name": "Brian Scaturro", 1140 | "email": "scaturrob@gmail.com" 1141 | } 1142 | ], 1143 | "description": "Scopes for function binding and mixins", 1144 | "support": { 1145 | "issues": "https://github.com/peridot-php/peridot-scope/issues", 1146 | "source": "https://github.com/peridot-php/peridot-scope/tree/master" 1147 | }, 1148 | "time": "2016-02-22T13:27:54+00:00" 1149 | }, 1150 | { 1151 | "name": "php-cs-fixer/diff", 1152 | "version": "v1.3.1", 1153 | "source": { 1154 | "type": "git", 1155 | "url": "https://github.com/PHP-CS-Fixer/diff.git", 1156 | "reference": "dbd31aeb251639ac0b9e7e29405c1441907f5759" 1157 | }, 1158 | "dist": { 1159 | "type": "zip", 1160 | "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/dbd31aeb251639ac0b9e7e29405c1441907f5759", 1161 | "reference": "dbd31aeb251639ac0b9e7e29405c1441907f5759", 1162 | "shasum": "" 1163 | }, 1164 | "require": { 1165 | "php": "^5.6 || ^7.0 || ^8.0" 1166 | }, 1167 | "require-dev": { 1168 | "phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0", 1169 | "symfony/process": "^3.3" 1170 | }, 1171 | "type": "library", 1172 | "autoload": { 1173 | "classmap": [ 1174 | "src/" 1175 | ] 1176 | }, 1177 | "notification-url": "https://packagist.org/downloads/", 1178 | "license": [ 1179 | "BSD-3-Clause" 1180 | ], 1181 | "authors": [ 1182 | { 1183 | "name": "Sebastian Bergmann", 1184 | "email": "sebastian@phpunit.de" 1185 | }, 1186 | { 1187 | "name": "Kore Nordmann", 1188 | "email": "mail@kore-nordmann.de" 1189 | }, 1190 | { 1191 | "name": "SpacePossum" 1192 | } 1193 | ], 1194 | "description": "sebastian/diff v2 backport support for PHP5.6", 1195 | "homepage": "https://github.com/PHP-CS-Fixer", 1196 | "keywords": [ 1197 | "diff" 1198 | ], 1199 | "support": { 1200 | "issues": "https://github.com/PHP-CS-Fixer/diff/issues", 1201 | "source": "https://github.com/PHP-CS-Fixer/diff/tree/v1.3.1" 1202 | }, 1203 | "time": "2020-10-14T08:39:05+00:00" 1204 | }, 1205 | { 1206 | "name": "phpunit/php-code-coverage", 1207 | "version": "9.2.14", 1208 | "source": { 1209 | "type": "git", 1210 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 1211 | "reference": "9f4d60b6afe5546421462b76cd4e633ebc364ab4" 1212 | }, 1213 | "dist": { 1214 | "type": "zip", 1215 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f4d60b6afe5546421462b76cd4e633ebc364ab4", 1216 | "reference": "9f4d60b6afe5546421462b76cd4e633ebc364ab4", 1217 | "shasum": "" 1218 | }, 1219 | "require": { 1220 | "ext-dom": "*", 1221 | "ext-libxml": "*", 1222 | "ext-xmlwriter": "*", 1223 | "nikic/php-parser": "^4.13.0", 1224 | "php": ">=7.3", 1225 | "phpunit/php-file-iterator": "^3.0.3", 1226 | "phpunit/php-text-template": "^2.0.2", 1227 | "sebastian/code-unit-reverse-lookup": "^2.0.2", 1228 | "sebastian/complexity": "^2.0", 1229 | "sebastian/environment": "^5.1.2", 1230 | "sebastian/lines-of-code": "^1.0.3", 1231 | "sebastian/version": "^3.0.1", 1232 | "theseer/tokenizer": "^1.2.0" 1233 | }, 1234 | "require-dev": { 1235 | "phpunit/phpunit": "^9.3" 1236 | }, 1237 | "suggest": { 1238 | "ext-pcov": "*", 1239 | "ext-xdebug": "*" 1240 | }, 1241 | "type": "library", 1242 | "extra": { 1243 | "branch-alias": { 1244 | "dev-master": "9.2-dev" 1245 | } 1246 | }, 1247 | "autoload": { 1248 | "classmap": [ 1249 | "src/" 1250 | ] 1251 | }, 1252 | "notification-url": "https://packagist.org/downloads/", 1253 | "license": [ 1254 | "BSD-3-Clause" 1255 | ], 1256 | "authors": [ 1257 | { 1258 | "name": "Sebastian Bergmann", 1259 | "email": "sebastian@phpunit.de", 1260 | "role": "lead" 1261 | } 1262 | ], 1263 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 1264 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 1265 | "keywords": [ 1266 | "coverage", 1267 | "testing", 1268 | "xunit" 1269 | ], 1270 | "support": { 1271 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", 1272 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.14" 1273 | }, 1274 | "funding": [ 1275 | { 1276 | "url": "https://github.com/sebastianbergmann", 1277 | "type": "github" 1278 | } 1279 | ], 1280 | "time": "2022-02-28T12:38:02+00:00" 1281 | }, 1282 | { 1283 | "name": "phpunit/php-file-iterator", 1284 | "version": "3.0.6", 1285 | "source": { 1286 | "type": "git", 1287 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 1288 | "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" 1289 | }, 1290 | "dist": { 1291 | "type": "zip", 1292 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", 1293 | "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", 1294 | "shasum": "" 1295 | }, 1296 | "require": { 1297 | "php": ">=7.3" 1298 | }, 1299 | "require-dev": { 1300 | "phpunit/phpunit": "^9.3" 1301 | }, 1302 | "type": "library", 1303 | "extra": { 1304 | "branch-alias": { 1305 | "dev-master": "3.0-dev" 1306 | } 1307 | }, 1308 | "autoload": { 1309 | "classmap": [ 1310 | "src/" 1311 | ] 1312 | }, 1313 | "notification-url": "https://packagist.org/downloads/", 1314 | "license": [ 1315 | "BSD-3-Clause" 1316 | ], 1317 | "authors": [ 1318 | { 1319 | "name": "Sebastian Bergmann", 1320 | "email": "sebastian@phpunit.de", 1321 | "role": "lead" 1322 | } 1323 | ], 1324 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 1325 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 1326 | "keywords": [ 1327 | "filesystem", 1328 | "iterator" 1329 | ], 1330 | "support": { 1331 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", 1332 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" 1333 | }, 1334 | "funding": [ 1335 | { 1336 | "url": "https://github.com/sebastianbergmann", 1337 | "type": "github" 1338 | } 1339 | ], 1340 | "time": "2021-12-02T12:48:52+00:00" 1341 | }, 1342 | { 1343 | "name": "phpunit/php-text-template", 1344 | "version": "2.0.4", 1345 | "source": { 1346 | "type": "git", 1347 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 1348 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" 1349 | }, 1350 | "dist": { 1351 | "type": "zip", 1352 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", 1353 | "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", 1354 | "shasum": "" 1355 | }, 1356 | "require": { 1357 | "php": ">=7.3" 1358 | }, 1359 | "require-dev": { 1360 | "phpunit/phpunit": "^9.3" 1361 | }, 1362 | "type": "library", 1363 | "extra": { 1364 | "branch-alias": { 1365 | "dev-master": "2.0-dev" 1366 | } 1367 | }, 1368 | "autoload": { 1369 | "classmap": [ 1370 | "src/" 1371 | ] 1372 | }, 1373 | "notification-url": "https://packagist.org/downloads/", 1374 | "license": [ 1375 | "BSD-3-Clause" 1376 | ], 1377 | "authors": [ 1378 | { 1379 | "name": "Sebastian Bergmann", 1380 | "email": "sebastian@phpunit.de", 1381 | "role": "lead" 1382 | } 1383 | ], 1384 | "description": "Simple template engine.", 1385 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 1386 | "keywords": [ 1387 | "template" 1388 | ], 1389 | "support": { 1390 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues", 1391 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" 1392 | }, 1393 | "funding": [ 1394 | { 1395 | "url": "https://github.com/sebastianbergmann", 1396 | "type": "github" 1397 | } 1398 | ], 1399 | "time": "2020-10-26T05:33:50+00:00" 1400 | }, 1401 | { 1402 | "name": "psr/cache", 1403 | "version": "1.0.1", 1404 | "source": { 1405 | "type": "git", 1406 | "url": "https://github.com/php-fig/cache.git", 1407 | "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" 1408 | }, 1409 | "dist": { 1410 | "type": "zip", 1411 | "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", 1412 | "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", 1413 | "shasum": "" 1414 | }, 1415 | "require": { 1416 | "php": ">=5.3.0" 1417 | }, 1418 | "type": "library", 1419 | "extra": { 1420 | "branch-alias": { 1421 | "dev-master": "1.0.x-dev" 1422 | } 1423 | }, 1424 | "autoload": { 1425 | "psr-4": { 1426 | "Psr\\Cache\\": "src/" 1427 | } 1428 | }, 1429 | "notification-url": "https://packagist.org/downloads/", 1430 | "license": [ 1431 | "MIT" 1432 | ], 1433 | "authors": [ 1434 | { 1435 | "name": "PHP-FIG", 1436 | "homepage": "http://www.php-fig.org/" 1437 | } 1438 | ], 1439 | "description": "Common interface for caching libraries", 1440 | "keywords": [ 1441 | "cache", 1442 | "psr", 1443 | "psr-6" 1444 | ], 1445 | "support": { 1446 | "source": "https://github.com/php-fig/cache/tree/master" 1447 | }, 1448 | "time": "2016-08-06T20:24:11+00:00" 1449 | }, 1450 | { 1451 | "name": "psr/container", 1452 | "version": "1.1.2", 1453 | "source": { 1454 | "type": "git", 1455 | "url": "https://github.com/php-fig/container.git", 1456 | "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" 1457 | }, 1458 | "dist": { 1459 | "type": "zip", 1460 | "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", 1461 | "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", 1462 | "shasum": "" 1463 | }, 1464 | "require": { 1465 | "php": ">=7.4.0" 1466 | }, 1467 | "type": "library", 1468 | "autoload": { 1469 | "psr-4": { 1470 | "Psr\\Container\\": "src/" 1471 | } 1472 | }, 1473 | "notification-url": "https://packagist.org/downloads/", 1474 | "license": [ 1475 | "MIT" 1476 | ], 1477 | "authors": [ 1478 | { 1479 | "name": "PHP-FIG", 1480 | "homepage": "https://www.php-fig.org/" 1481 | } 1482 | ], 1483 | "description": "Common Container Interface (PHP FIG PSR-11)", 1484 | "homepage": "https://github.com/php-fig/container", 1485 | "keywords": [ 1486 | "PSR-11", 1487 | "container", 1488 | "container-interface", 1489 | "container-interop", 1490 | "psr" 1491 | ], 1492 | "support": { 1493 | "issues": "https://github.com/php-fig/container/issues", 1494 | "source": "https://github.com/php-fig/container/tree/1.1.2" 1495 | }, 1496 | "time": "2021-11-05T16:50:12+00:00" 1497 | }, 1498 | { 1499 | "name": "psr/log", 1500 | "version": "1.1.4", 1501 | "source": { 1502 | "type": "git", 1503 | "url": "https://github.com/php-fig/log.git", 1504 | "reference": "d49695b909c3b7628b6289db5479a1c204601f11" 1505 | }, 1506 | "dist": { 1507 | "type": "zip", 1508 | "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", 1509 | "reference": "d49695b909c3b7628b6289db5479a1c204601f11", 1510 | "shasum": "" 1511 | }, 1512 | "require": { 1513 | "php": ">=5.3.0" 1514 | }, 1515 | "type": "library", 1516 | "extra": { 1517 | "branch-alias": { 1518 | "dev-master": "1.1.x-dev" 1519 | } 1520 | }, 1521 | "autoload": { 1522 | "psr-4": { 1523 | "Psr\\Log\\": "Psr/Log/" 1524 | } 1525 | }, 1526 | "notification-url": "https://packagist.org/downloads/", 1527 | "license": [ 1528 | "MIT" 1529 | ], 1530 | "authors": [ 1531 | { 1532 | "name": "PHP-FIG", 1533 | "homepage": "https://www.php-fig.org/" 1534 | } 1535 | ], 1536 | "description": "Common interface for logging libraries", 1537 | "homepage": "https://github.com/php-fig/log", 1538 | "keywords": [ 1539 | "log", 1540 | "psr", 1541 | "psr-3" 1542 | ], 1543 | "support": { 1544 | "source": "https://github.com/php-fig/log/tree/1.1.4" 1545 | }, 1546 | "time": "2021-05-03T11:20:27+00:00" 1547 | }, 1548 | { 1549 | "name": "react/cache", 1550 | "version": "v1.1.1", 1551 | "source": { 1552 | "type": "git", 1553 | "url": "https://github.com/reactphp/cache.git", 1554 | "reference": "4bf736a2cccec7298bdf745db77585966fc2ca7e" 1555 | }, 1556 | "dist": { 1557 | "type": "zip", 1558 | "url": "https://api.github.com/repos/reactphp/cache/zipball/4bf736a2cccec7298bdf745db77585966fc2ca7e", 1559 | "reference": "4bf736a2cccec7298bdf745db77585966fc2ca7e", 1560 | "shasum": "" 1561 | }, 1562 | "require": { 1563 | "php": ">=5.3.0", 1564 | "react/promise": "^3.0 || ^2.0 || ^1.1" 1565 | }, 1566 | "require-dev": { 1567 | "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" 1568 | }, 1569 | "type": "library", 1570 | "autoload": { 1571 | "psr-4": { 1572 | "React\\Cache\\": "src/" 1573 | } 1574 | }, 1575 | "notification-url": "https://packagist.org/downloads/", 1576 | "license": [ 1577 | "MIT" 1578 | ], 1579 | "authors": [ 1580 | { 1581 | "name": "Christian Lück", 1582 | "email": "christian@clue.engineering", 1583 | "homepage": "https://clue.engineering/" 1584 | }, 1585 | { 1586 | "name": "Cees-Jan Kiewiet", 1587 | "email": "reactphp@ceesjankiewiet.nl", 1588 | "homepage": "https://wyrihaximus.net/" 1589 | }, 1590 | { 1591 | "name": "Jan Sorgalla", 1592 | "email": "jsorgalla@gmail.com", 1593 | "homepage": "https://sorgalla.com/" 1594 | }, 1595 | { 1596 | "name": "Chris Boden", 1597 | "email": "cboden@gmail.com", 1598 | "homepage": "https://cboden.dev/" 1599 | } 1600 | ], 1601 | "description": "Async, Promise-based cache interface for ReactPHP", 1602 | "keywords": [ 1603 | "cache", 1604 | "caching", 1605 | "promise", 1606 | "reactphp" 1607 | ], 1608 | "support": { 1609 | "issues": "https://github.com/reactphp/cache/issues", 1610 | "source": "https://github.com/reactphp/cache/tree/v1.1.1" 1611 | }, 1612 | "funding": [ 1613 | { 1614 | "url": "https://github.com/WyriHaximus", 1615 | "type": "github" 1616 | }, 1617 | { 1618 | "url": "https://github.com/clue", 1619 | "type": "github" 1620 | } 1621 | ], 1622 | "time": "2021-02-02T06:47:52+00:00" 1623 | }, 1624 | { 1625 | "name": "react/dns", 1626 | "version": "v0.4.19", 1627 | "source": { 1628 | "type": "git", 1629 | "url": "https://github.com/reactphp/dns.git", 1630 | "reference": "6852fb98e22d2e5bb35fe5aeeaa96551b120e7c9" 1631 | }, 1632 | "dist": { 1633 | "type": "zip", 1634 | "url": "https://api.github.com/repos/reactphp/dns/zipball/6852fb98e22d2e5bb35fe5aeeaa96551b120e7c9", 1635 | "reference": "6852fb98e22d2e5bb35fe5aeeaa96551b120e7c9", 1636 | "shasum": "" 1637 | }, 1638 | "require": { 1639 | "php": ">=5.3.0", 1640 | "react/cache": "^1.0 || ^0.6 || ^0.5", 1641 | "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5", 1642 | "react/promise": "^2.1 || ^1.2.1", 1643 | "react/promise-timer": "^1.2", 1644 | "react/stream": "^1.0 || ^0.7 || ^0.6 || ^0.5 || ^0.4.5" 1645 | }, 1646 | "require-dev": { 1647 | "clue/block-react": "^1.2", 1648 | "phpunit/phpunit": "^7.0 || ^6.4 || ^5.7 || ^4.8.35" 1649 | }, 1650 | "type": "library", 1651 | "autoload": { 1652 | "psr-4": { 1653 | "React\\Dns\\": "src" 1654 | } 1655 | }, 1656 | "notification-url": "https://packagist.org/downloads/", 1657 | "license": [ 1658 | "MIT" 1659 | ], 1660 | "description": "Async DNS resolver for ReactPHP", 1661 | "keywords": [ 1662 | "async", 1663 | "dns", 1664 | "dns-resolver", 1665 | "reactphp" 1666 | ], 1667 | "support": { 1668 | "issues": "https://github.com/reactphp/dns/issues", 1669 | "source": "https://github.com/reactphp/dns/tree/v0.4.19" 1670 | }, 1671 | "time": "2019-07-10T21:00:53+00:00" 1672 | }, 1673 | { 1674 | "name": "react/event-loop", 1675 | "version": "v1.2.0", 1676 | "source": { 1677 | "type": "git", 1678 | "url": "https://github.com/reactphp/event-loop.git", 1679 | "reference": "be6dee480fc4692cec0504e65eb486e3be1aa6f2" 1680 | }, 1681 | "dist": { 1682 | "type": "zip", 1683 | "url": "https://api.github.com/repos/reactphp/event-loop/zipball/be6dee480fc4692cec0504e65eb486e3be1aa6f2", 1684 | "reference": "be6dee480fc4692cec0504e65eb486e3be1aa6f2", 1685 | "shasum": "" 1686 | }, 1687 | "require": { 1688 | "php": ">=5.3.0" 1689 | }, 1690 | "require-dev": { 1691 | "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" 1692 | }, 1693 | "suggest": { 1694 | "ext-event": "~1.0 for ExtEventLoop", 1695 | "ext-pcntl": "For signal handling support when using the StreamSelectLoop", 1696 | "ext-uv": "* for ExtUvLoop" 1697 | }, 1698 | "type": "library", 1699 | "autoload": { 1700 | "psr-4": { 1701 | "React\\EventLoop\\": "src" 1702 | } 1703 | }, 1704 | "notification-url": "https://packagist.org/downloads/", 1705 | "license": [ 1706 | "MIT" 1707 | ], 1708 | "authors": [ 1709 | { 1710 | "name": "Christian Lück", 1711 | "email": "christian@clue.engineering", 1712 | "homepage": "https://clue.engineering/" 1713 | }, 1714 | { 1715 | "name": "Cees-Jan Kiewiet", 1716 | "email": "reactphp@ceesjankiewiet.nl", 1717 | "homepage": "https://wyrihaximus.net/" 1718 | }, 1719 | { 1720 | "name": "Jan Sorgalla", 1721 | "email": "jsorgalla@gmail.com", 1722 | "homepage": "https://sorgalla.com/" 1723 | }, 1724 | { 1725 | "name": "Chris Boden", 1726 | "email": "cboden@gmail.com", 1727 | "homepage": "https://cboden.dev/" 1728 | } 1729 | ], 1730 | "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", 1731 | "keywords": [ 1732 | "asynchronous", 1733 | "event-loop" 1734 | ], 1735 | "support": { 1736 | "issues": "https://github.com/reactphp/event-loop/issues", 1737 | "source": "https://github.com/reactphp/event-loop/tree/v1.2.0" 1738 | }, 1739 | "funding": [ 1740 | { 1741 | "url": "https://github.com/WyriHaximus", 1742 | "type": "github" 1743 | }, 1744 | { 1745 | "url": "https://github.com/clue", 1746 | "type": "github" 1747 | } 1748 | ], 1749 | "time": "2021-07-11T12:31:24+00:00" 1750 | }, 1751 | { 1752 | "name": "react/promise", 1753 | "version": "v2.9.0", 1754 | "source": { 1755 | "type": "git", 1756 | "url": "https://github.com/reactphp/promise.git", 1757 | "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910" 1758 | }, 1759 | "dist": { 1760 | "type": "zip", 1761 | "url": "https://api.github.com/repos/reactphp/promise/zipball/234f8fd1023c9158e2314fa9d7d0e6a83db42910", 1762 | "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910", 1763 | "shasum": "" 1764 | }, 1765 | "require": { 1766 | "php": ">=5.4.0" 1767 | }, 1768 | "require-dev": { 1769 | "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" 1770 | }, 1771 | "type": "library", 1772 | "autoload": { 1773 | "files": [ 1774 | "src/functions_include.php" 1775 | ], 1776 | "psr-4": { 1777 | "React\\Promise\\": "src/" 1778 | } 1779 | }, 1780 | "notification-url": "https://packagist.org/downloads/", 1781 | "license": [ 1782 | "MIT" 1783 | ], 1784 | "authors": [ 1785 | { 1786 | "name": "Jan Sorgalla", 1787 | "email": "jsorgalla@gmail.com", 1788 | "homepage": "https://sorgalla.com/" 1789 | }, 1790 | { 1791 | "name": "Christian Lück", 1792 | "email": "christian@clue.engineering", 1793 | "homepage": "https://clue.engineering/" 1794 | }, 1795 | { 1796 | "name": "Cees-Jan Kiewiet", 1797 | "email": "reactphp@ceesjankiewiet.nl", 1798 | "homepage": "https://wyrihaximus.net/" 1799 | }, 1800 | { 1801 | "name": "Chris Boden", 1802 | "email": "cboden@gmail.com", 1803 | "homepage": "https://cboden.dev/" 1804 | } 1805 | ], 1806 | "description": "A lightweight implementation of CommonJS Promises/A for PHP", 1807 | "keywords": [ 1808 | "promise", 1809 | "promises" 1810 | ], 1811 | "support": { 1812 | "issues": "https://github.com/reactphp/promise/issues", 1813 | "source": "https://github.com/reactphp/promise/tree/v2.9.0" 1814 | }, 1815 | "funding": [ 1816 | { 1817 | "url": "https://github.com/WyriHaximus", 1818 | "type": "github" 1819 | }, 1820 | { 1821 | "url": "https://github.com/clue", 1822 | "type": "github" 1823 | } 1824 | ], 1825 | "time": "2022-02-11T10:27:51+00:00" 1826 | }, 1827 | { 1828 | "name": "react/promise-timer", 1829 | "version": "v1.8.0", 1830 | "source": { 1831 | "type": "git", 1832 | "url": "https://github.com/reactphp/promise-timer.git", 1833 | "reference": "0bbbcc79589e5bfdddba68a287f1cb805581a479" 1834 | }, 1835 | "dist": { 1836 | "type": "zip", 1837 | "url": "https://api.github.com/repos/reactphp/promise-timer/zipball/0bbbcc79589e5bfdddba68a287f1cb805581a479", 1838 | "reference": "0bbbcc79589e5bfdddba68a287f1cb805581a479", 1839 | "shasum": "" 1840 | }, 1841 | "require": { 1842 | "php": ">=5.3", 1843 | "react/event-loop": "^1.2", 1844 | "react/promise": "^3.0 || ^2.7.0 || ^1.2.1" 1845 | }, 1846 | "require-dev": { 1847 | "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" 1848 | }, 1849 | "type": "library", 1850 | "autoload": { 1851 | "files": [ 1852 | "src/functions_include.php" 1853 | ], 1854 | "psr-4": { 1855 | "React\\Promise\\Timer\\": "src/" 1856 | } 1857 | }, 1858 | "notification-url": "https://packagist.org/downloads/", 1859 | "license": [ 1860 | "MIT" 1861 | ], 1862 | "authors": [ 1863 | { 1864 | "name": "Christian Lück", 1865 | "email": "christian@clue.engineering", 1866 | "homepage": "https://clue.engineering/" 1867 | }, 1868 | { 1869 | "name": "Cees-Jan Kiewiet", 1870 | "email": "reactphp@ceesjankiewiet.nl", 1871 | "homepage": "https://wyrihaximus.net/" 1872 | }, 1873 | { 1874 | "name": "Jan Sorgalla", 1875 | "email": "jsorgalla@gmail.com", 1876 | "homepage": "https://sorgalla.com/" 1877 | }, 1878 | { 1879 | "name": "Chris Boden", 1880 | "email": "cboden@gmail.com", 1881 | "homepage": "https://cboden.dev/" 1882 | } 1883 | ], 1884 | "description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.", 1885 | "homepage": "https://github.com/reactphp/promise-timer", 1886 | "keywords": [ 1887 | "async", 1888 | "event-loop", 1889 | "promise", 1890 | "reactphp", 1891 | "timeout", 1892 | "timer" 1893 | ], 1894 | "support": { 1895 | "issues": "https://github.com/reactphp/promise-timer/issues", 1896 | "source": "https://github.com/reactphp/promise-timer/tree/v1.8.0" 1897 | }, 1898 | "funding": [ 1899 | { 1900 | "url": "https://github.com/WyriHaximus", 1901 | "type": "github" 1902 | }, 1903 | { 1904 | "url": "https://github.com/clue", 1905 | "type": "github" 1906 | } 1907 | ], 1908 | "time": "2021-12-06T11:08:48+00:00" 1909 | }, 1910 | { 1911 | "name": "react/stream", 1912 | "version": "v1.2.0", 1913 | "source": { 1914 | "type": "git", 1915 | "url": "https://github.com/reactphp/stream.git", 1916 | "reference": "7a423506ee1903e89f1e08ec5f0ed430ff784ae9" 1917 | }, 1918 | "dist": { 1919 | "type": "zip", 1920 | "url": "https://api.github.com/repos/reactphp/stream/zipball/7a423506ee1903e89f1e08ec5f0ed430ff784ae9", 1921 | "reference": "7a423506ee1903e89f1e08ec5f0ed430ff784ae9", 1922 | "shasum": "" 1923 | }, 1924 | "require": { 1925 | "evenement/evenement": "^3.0 || ^2.0 || ^1.0", 1926 | "php": ">=5.3.8", 1927 | "react/event-loop": "^1.2" 1928 | }, 1929 | "require-dev": { 1930 | "clue/stream-filter": "~1.2", 1931 | "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" 1932 | }, 1933 | "type": "library", 1934 | "autoload": { 1935 | "psr-4": { 1936 | "React\\Stream\\": "src" 1937 | } 1938 | }, 1939 | "notification-url": "https://packagist.org/downloads/", 1940 | "license": [ 1941 | "MIT" 1942 | ], 1943 | "authors": [ 1944 | { 1945 | "name": "Christian Lück", 1946 | "email": "christian@clue.engineering", 1947 | "homepage": "https://clue.engineering/" 1948 | }, 1949 | { 1950 | "name": "Cees-Jan Kiewiet", 1951 | "email": "reactphp@ceesjankiewiet.nl", 1952 | "homepage": "https://wyrihaximus.net/" 1953 | }, 1954 | { 1955 | "name": "Jan Sorgalla", 1956 | "email": "jsorgalla@gmail.com", 1957 | "homepage": "https://sorgalla.com/" 1958 | }, 1959 | { 1960 | "name": "Chris Boden", 1961 | "email": "cboden@gmail.com", 1962 | "homepage": "https://cboden.dev/" 1963 | } 1964 | ], 1965 | "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", 1966 | "keywords": [ 1967 | "event-driven", 1968 | "io", 1969 | "non-blocking", 1970 | "pipe", 1971 | "reactphp", 1972 | "readable", 1973 | "stream", 1974 | "writable" 1975 | ], 1976 | "support": { 1977 | "issues": "https://github.com/reactphp/stream/issues", 1978 | "source": "https://github.com/reactphp/stream/tree/v1.2.0" 1979 | }, 1980 | "funding": [ 1981 | { 1982 | "url": "https://github.com/WyriHaximus", 1983 | "type": "github" 1984 | }, 1985 | { 1986 | "url": "https://github.com/clue", 1987 | "type": "github" 1988 | } 1989 | ], 1990 | "time": "2021-07-11T12:37:55+00:00" 1991 | }, 1992 | { 1993 | "name": "recoil/dev", 1994 | "version": "0.4.2", 1995 | "source": { 1996 | "type": "git", 1997 | "url": "https://github.com/recoilphp/dev.git", 1998 | "reference": "7e422c97bbc6931ef4baf83b46b7fb91678fa661" 1999 | }, 2000 | "dist": { 2001 | "type": "zip", 2002 | "url": "https://api.github.com/repos/recoilphp/dev/zipball/7e422c97bbc6931ef4baf83b46b7fb91678fa661", 2003 | "reference": "7e422c97bbc6931ef4baf83b46b7fb91678fa661", 2004 | "shasum": "" 2005 | }, 2006 | "require": { 2007 | "composer-plugin-api": "^1|^2", 2008 | "eloquent/enumeration": "^5", 2009 | "hamcrest/hamcrest-php": "^2", 2010 | "nikic/php-parser": "^4", 2011 | "php": ">=7.4", 2012 | "recoil/api": "^1" 2013 | }, 2014 | "require-dev": { 2015 | "composer/composer": "^1|^2", 2016 | "eloquent/phony": "^5", 2017 | "friendsofphp/php-cs-fixer": "^2", 2018 | "peridot-php/leo": "dev-php-8 as 1.999.999", 2019 | "peridot-php/peridot": "dev-php-8 as 1.999.999", 2020 | "peridot-php/peridot-code-coverage-reporters": "dev-php-8 as 2.999.999", 2021 | "recoil/recoil": "^1" 2022 | }, 2023 | "bin": [ 2024 | "bin/recoil-instrument" 2025 | ], 2026 | "type": "composer-plugin", 2027 | "extra": { 2028 | "class": "Recoil\\Dev\\Composer\\Plugin" 2029 | }, 2030 | "autoload": { 2031 | "psr-4": { 2032 | "Recoil\\Dev\\": "src" 2033 | } 2034 | }, 2035 | "notification-url": "https://packagist.org/downloads/", 2036 | "license": [ 2037 | "MIT" 2038 | ], 2039 | "authors": [ 2040 | { 2041 | "name": "James Harris", 2042 | "email": "james.harris@icecave.com.au", 2043 | "homepage": "https://github.com/jmalloc" 2044 | } 2045 | ], 2046 | "description": "Development and debugging tools for Recoil applications.", 2047 | "homepage": "https://github.com/recoilphp/dev", 2048 | "keywords": [ 2049 | "async", 2050 | "asynchronous", 2051 | "debug", 2052 | "exception", 2053 | "instrumentation", 2054 | "recoil", 2055 | "stack", 2056 | "trace" 2057 | ], 2058 | "support": { 2059 | "issues": "https://github.com/recoilphp/dev/issues", 2060 | "source": "https://github.com/recoilphp/dev/tree/0.4.2" 2061 | }, 2062 | "time": "2022-03-06T04:11:59+00:00" 2063 | }, 2064 | { 2065 | "name": "recoil/react", 2066 | "version": "1.0.3", 2067 | "source": { 2068 | "type": "git", 2069 | "url": "https://github.com/recoilphp/react.git", 2070 | "reference": "a928961155f2663a735fb03aa1c4941a3f70ff1a" 2071 | }, 2072 | "dist": { 2073 | "type": "zip", 2074 | "url": "https://api.github.com/repos/recoilphp/react/zipball/a928961155f2663a735fb03aa1c4941a3f70ff1a", 2075 | "reference": "a928961155f2663a735fb03aa1c4941a3f70ff1a", 2076 | "shasum": "" 2077 | }, 2078 | "require": { 2079 | "php": ">=7.4", 2080 | "react/event-loop": "^1.0 || ^0.5 || ^0.4", 2081 | "react/promise": "^2", 2082 | "recoil/api": "^1.0.2", 2083 | "recoil/kernel": "^1" 2084 | }, 2085 | "require-dev": { 2086 | "eloquent/phony": "^5", 2087 | "friendsofphp/php-cs-fixer": "^2", 2088 | "hamcrest/hamcrest-php": "^2", 2089 | "peridot-php/leo": "dev-php-8 as 1.999.999", 2090 | "peridot-php/peridot": "dev-php-8 as 1.999.999", 2091 | "peridot-php/peridot-code-coverage-reporters": "dev-php-8 as 2.999.999", 2092 | "recoil/dev": "^0.4" 2093 | }, 2094 | "type": "library", 2095 | "autoload": { 2096 | "psr-4": { 2097 | "Recoil\\React\\": "src" 2098 | } 2099 | }, 2100 | "notification-url": "https://packagist.org/downloads/", 2101 | "license": [ 2102 | "MIT" 2103 | ], 2104 | "authors": [ 2105 | { 2106 | "name": "James Harris", 2107 | "email": "james.harris@icecave.com.au", 2108 | "homepage": "https://github.com/jmalloc" 2109 | } 2110 | ], 2111 | "description": "Integrate Recoil with ReactPHP.", 2112 | "homepage": "https://github.com/recoilphp/react", 2113 | "keywords": [ 2114 | "Thread", 2115 | "async", 2116 | "asynchronous", 2117 | "continuation", 2118 | "coroutine", 2119 | "event", 2120 | "generator", 2121 | "green", 2122 | "multitasking", 2123 | "promise", 2124 | "react" 2125 | ], 2126 | "support": { 2127 | "issues": "https://github.com/recoilphp/react/issues", 2128 | "source": "https://github.com/recoilphp/react/tree/1.0.3" 2129 | }, 2130 | "time": "2022-03-06T04:17:15+00:00" 2131 | }, 2132 | { 2133 | "name": "sebastian/code-unit-reverse-lookup", 2134 | "version": "2.0.3", 2135 | "source": { 2136 | "type": "git", 2137 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 2138 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" 2139 | }, 2140 | "dist": { 2141 | "type": "zip", 2142 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", 2143 | "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", 2144 | "shasum": "" 2145 | }, 2146 | "require": { 2147 | "php": ">=7.3" 2148 | }, 2149 | "require-dev": { 2150 | "phpunit/phpunit": "^9.3" 2151 | }, 2152 | "type": "library", 2153 | "extra": { 2154 | "branch-alias": { 2155 | "dev-master": "2.0-dev" 2156 | } 2157 | }, 2158 | "autoload": { 2159 | "classmap": [ 2160 | "src/" 2161 | ] 2162 | }, 2163 | "notification-url": "https://packagist.org/downloads/", 2164 | "license": [ 2165 | "BSD-3-Clause" 2166 | ], 2167 | "authors": [ 2168 | { 2169 | "name": "Sebastian Bergmann", 2170 | "email": "sebastian@phpunit.de" 2171 | } 2172 | ], 2173 | "description": "Looks up which function or method a line of code belongs to", 2174 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 2175 | "support": { 2176 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", 2177 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" 2178 | }, 2179 | "funding": [ 2180 | { 2181 | "url": "https://github.com/sebastianbergmann", 2182 | "type": "github" 2183 | } 2184 | ], 2185 | "time": "2020-09-28T05:30:19+00:00" 2186 | }, 2187 | { 2188 | "name": "sebastian/complexity", 2189 | "version": "2.0.2", 2190 | "source": { 2191 | "type": "git", 2192 | "url": "https://github.com/sebastianbergmann/complexity.git", 2193 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" 2194 | }, 2195 | "dist": { 2196 | "type": "zip", 2197 | "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", 2198 | "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", 2199 | "shasum": "" 2200 | }, 2201 | "require": { 2202 | "nikic/php-parser": "^4.7", 2203 | "php": ">=7.3" 2204 | }, 2205 | "require-dev": { 2206 | "phpunit/phpunit": "^9.3" 2207 | }, 2208 | "type": "library", 2209 | "extra": { 2210 | "branch-alias": { 2211 | "dev-master": "2.0-dev" 2212 | } 2213 | }, 2214 | "autoload": { 2215 | "classmap": [ 2216 | "src/" 2217 | ] 2218 | }, 2219 | "notification-url": "https://packagist.org/downloads/", 2220 | "license": [ 2221 | "BSD-3-Clause" 2222 | ], 2223 | "authors": [ 2224 | { 2225 | "name": "Sebastian Bergmann", 2226 | "email": "sebastian@phpunit.de", 2227 | "role": "lead" 2228 | } 2229 | ], 2230 | "description": "Library for calculating the complexity of PHP code units", 2231 | "homepage": "https://github.com/sebastianbergmann/complexity", 2232 | "support": { 2233 | "issues": "https://github.com/sebastianbergmann/complexity/issues", 2234 | "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" 2235 | }, 2236 | "funding": [ 2237 | { 2238 | "url": "https://github.com/sebastianbergmann", 2239 | "type": "github" 2240 | } 2241 | ], 2242 | "time": "2020-10-26T15:52:27+00:00" 2243 | }, 2244 | { 2245 | "name": "sebastian/environment", 2246 | "version": "5.1.3", 2247 | "source": { 2248 | "type": "git", 2249 | "url": "https://github.com/sebastianbergmann/environment.git", 2250 | "reference": "388b6ced16caa751030f6a69e588299fa09200ac" 2251 | }, 2252 | "dist": { 2253 | "type": "zip", 2254 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", 2255 | "reference": "388b6ced16caa751030f6a69e588299fa09200ac", 2256 | "shasum": "" 2257 | }, 2258 | "require": { 2259 | "php": ">=7.3" 2260 | }, 2261 | "require-dev": { 2262 | "phpunit/phpunit": "^9.3" 2263 | }, 2264 | "suggest": { 2265 | "ext-posix": "*" 2266 | }, 2267 | "type": "library", 2268 | "extra": { 2269 | "branch-alias": { 2270 | "dev-master": "5.1-dev" 2271 | } 2272 | }, 2273 | "autoload": { 2274 | "classmap": [ 2275 | "src/" 2276 | ] 2277 | }, 2278 | "notification-url": "https://packagist.org/downloads/", 2279 | "license": [ 2280 | "BSD-3-Clause" 2281 | ], 2282 | "authors": [ 2283 | { 2284 | "name": "Sebastian Bergmann", 2285 | "email": "sebastian@phpunit.de" 2286 | } 2287 | ], 2288 | "description": "Provides functionality to handle HHVM/PHP environments", 2289 | "homepage": "http://www.github.com/sebastianbergmann/environment", 2290 | "keywords": [ 2291 | "Xdebug", 2292 | "environment", 2293 | "hhvm" 2294 | ], 2295 | "support": { 2296 | "issues": "https://github.com/sebastianbergmann/environment/issues", 2297 | "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" 2298 | }, 2299 | "funding": [ 2300 | { 2301 | "url": "https://github.com/sebastianbergmann", 2302 | "type": "github" 2303 | } 2304 | ], 2305 | "time": "2020-09-28T05:52:38+00:00" 2306 | }, 2307 | { 2308 | "name": "sebastian/lines-of-code", 2309 | "version": "1.0.3", 2310 | "source": { 2311 | "type": "git", 2312 | "url": "https://github.com/sebastianbergmann/lines-of-code.git", 2313 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" 2314 | }, 2315 | "dist": { 2316 | "type": "zip", 2317 | "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", 2318 | "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", 2319 | "shasum": "" 2320 | }, 2321 | "require": { 2322 | "nikic/php-parser": "^4.6", 2323 | "php": ">=7.3" 2324 | }, 2325 | "require-dev": { 2326 | "phpunit/phpunit": "^9.3" 2327 | }, 2328 | "type": "library", 2329 | "extra": { 2330 | "branch-alias": { 2331 | "dev-master": "1.0-dev" 2332 | } 2333 | }, 2334 | "autoload": { 2335 | "classmap": [ 2336 | "src/" 2337 | ] 2338 | }, 2339 | "notification-url": "https://packagist.org/downloads/", 2340 | "license": [ 2341 | "BSD-3-Clause" 2342 | ], 2343 | "authors": [ 2344 | { 2345 | "name": "Sebastian Bergmann", 2346 | "email": "sebastian@phpunit.de", 2347 | "role": "lead" 2348 | } 2349 | ], 2350 | "description": "Library for counting the lines of code in PHP source code", 2351 | "homepage": "https://github.com/sebastianbergmann/lines-of-code", 2352 | "support": { 2353 | "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", 2354 | "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" 2355 | }, 2356 | "funding": [ 2357 | { 2358 | "url": "https://github.com/sebastianbergmann", 2359 | "type": "github" 2360 | } 2361 | ], 2362 | "time": "2020-11-28T06:42:11+00:00" 2363 | }, 2364 | { 2365 | "name": "sebastian/version", 2366 | "version": "3.0.2", 2367 | "source": { 2368 | "type": "git", 2369 | "url": "https://github.com/sebastianbergmann/version.git", 2370 | "reference": "c6c1022351a901512170118436c764e473f6de8c" 2371 | }, 2372 | "dist": { 2373 | "type": "zip", 2374 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", 2375 | "reference": "c6c1022351a901512170118436c764e473f6de8c", 2376 | "shasum": "" 2377 | }, 2378 | "require": { 2379 | "php": ">=7.3" 2380 | }, 2381 | "type": "library", 2382 | "extra": { 2383 | "branch-alias": { 2384 | "dev-master": "3.0-dev" 2385 | } 2386 | }, 2387 | "autoload": { 2388 | "classmap": [ 2389 | "src/" 2390 | ] 2391 | }, 2392 | "notification-url": "https://packagist.org/downloads/", 2393 | "license": [ 2394 | "BSD-3-Clause" 2395 | ], 2396 | "authors": [ 2397 | { 2398 | "name": "Sebastian Bergmann", 2399 | "email": "sebastian@phpunit.de", 2400 | "role": "lead" 2401 | } 2402 | ], 2403 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 2404 | "homepage": "https://github.com/sebastianbergmann/version", 2405 | "support": { 2406 | "issues": "https://github.com/sebastianbergmann/version/issues", 2407 | "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" 2408 | }, 2409 | "funding": [ 2410 | { 2411 | "url": "https://github.com/sebastianbergmann", 2412 | "type": "github" 2413 | } 2414 | ], 2415 | "time": "2020-09-28T06:39:44+00:00" 2416 | }, 2417 | { 2418 | "name": "symfony/console", 2419 | "version": "v4.4.38", 2420 | "source": { 2421 | "type": "git", 2422 | "url": "https://github.com/symfony/console.git", 2423 | "reference": "5a50085bf5460f0c0d60a50b58388c1249826b8a" 2424 | }, 2425 | "dist": { 2426 | "type": "zip", 2427 | "url": "https://api.github.com/repos/symfony/console/zipball/5a50085bf5460f0c0d60a50b58388c1249826b8a", 2428 | "reference": "5a50085bf5460f0c0d60a50b58388c1249826b8a", 2429 | "shasum": "" 2430 | }, 2431 | "require": { 2432 | "php": ">=7.1.3", 2433 | "symfony/polyfill-mbstring": "~1.0", 2434 | "symfony/polyfill-php73": "^1.8", 2435 | "symfony/polyfill-php80": "^1.16", 2436 | "symfony/service-contracts": "^1.1|^2" 2437 | }, 2438 | "conflict": { 2439 | "psr/log": ">=3", 2440 | "symfony/dependency-injection": "<3.4", 2441 | "symfony/event-dispatcher": "<4.3|>=5", 2442 | "symfony/lock": "<4.4", 2443 | "symfony/process": "<3.3" 2444 | }, 2445 | "provide": { 2446 | "psr/log-implementation": "1.0|2.0" 2447 | }, 2448 | "require-dev": { 2449 | "psr/log": "^1|^2", 2450 | "symfony/config": "^3.4|^4.0|^5.0", 2451 | "symfony/dependency-injection": "^3.4|^4.0|^5.0", 2452 | "symfony/event-dispatcher": "^4.3", 2453 | "symfony/lock": "^4.4|^5.0", 2454 | "symfony/process": "^3.4|^4.0|^5.0", 2455 | "symfony/var-dumper": "^4.3|^5.0" 2456 | }, 2457 | "suggest": { 2458 | "psr/log": "For using the console logger", 2459 | "symfony/event-dispatcher": "", 2460 | "symfony/lock": "", 2461 | "symfony/process": "" 2462 | }, 2463 | "type": "library", 2464 | "autoload": { 2465 | "psr-4": { 2466 | "Symfony\\Component\\Console\\": "" 2467 | }, 2468 | "exclude-from-classmap": [ 2469 | "/Tests/" 2470 | ] 2471 | }, 2472 | "notification-url": "https://packagist.org/downloads/", 2473 | "license": [ 2474 | "MIT" 2475 | ], 2476 | "authors": [ 2477 | { 2478 | "name": "Fabien Potencier", 2479 | "email": "fabien@symfony.com" 2480 | }, 2481 | { 2482 | "name": "Symfony Community", 2483 | "homepage": "https://symfony.com/contributors" 2484 | } 2485 | ], 2486 | "description": "Eases the creation of beautiful and testable command line interfaces", 2487 | "homepage": "https://symfony.com", 2488 | "support": { 2489 | "source": "https://github.com/symfony/console/tree/v4.4.38" 2490 | }, 2491 | "funding": [ 2492 | { 2493 | "url": "https://symfony.com/sponsor", 2494 | "type": "custom" 2495 | }, 2496 | { 2497 | "url": "https://github.com/fabpot", 2498 | "type": "github" 2499 | }, 2500 | { 2501 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2502 | "type": "tidelift" 2503 | } 2504 | ], 2505 | "time": "2022-01-30T21:23:57+00:00" 2506 | }, 2507 | { 2508 | "name": "symfony/deprecation-contracts", 2509 | "version": "v2.5.0", 2510 | "source": { 2511 | "type": "git", 2512 | "url": "https://github.com/symfony/deprecation-contracts.git", 2513 | "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" 2514 | }, 2515 | "dist": { 2516 | "type": "zip", 2517 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", 2518 | "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", 2519 | "shasum": "" 2520 | }, 2521 | "require": { 2522 | "php": ">=7.1" 2523 | }, 2524 | "type": "library", 2525 | "extra": { 2526 | "branch-alias": { 2527 | "dev-main": "2.5-dev" 2528 | }, 2529 | "thanks": { 2530 | "name": "symfony/contracts", 2531 | "url": "https://github.com/symfony/contracts" 2532 | } 2533 | }, 2534 | "autoload": { 2535 | "files": [ 2536 | "function.php" 2537 | ] 2538 | }, 2539 | "notification-url": "https://packagist.org/downloads/", 2540 | "license": [ 2541 | "MIT" 2542 | ], 2543 | "authors": [ 2544 | { 2545 | "name": "Nicolas Grekas", 2546 | "email": "p@tchwork.com" 2547 | }, 2548 | { 2549 | "name": "Symfony Community", 2550 | "homepage": "https://symfony.com/contributors" 2551 | } 2552 | ], 2553 | "description": "A generic function and convention to trigger deprecation notices", 2554 | "homepage": "https://symfony.com", 2555 | "support": { 2556 | "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" 2557 | }, 2558 | "funding": [ 2559 | { 2560 | "url": "https://symfony.com/sponsor", 2561 | "type": "custom" 2562 | }, 2563 | { 2564 | "url": "https://github.com/fabpot", 2565 | "type": "github" 2566 | }, 2567 | { 2568 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2569 | "type": "tidelift" 2570 | } 2571 | ], 2572 | "time": "2021-07-12T14:48:14+00:00" 2573 | }, 2574 | { 2575 | "name": "symfony/event-dispatcher", 2576 | "version": "v4.4.37", 2577 | "source": { 2578 | "type": "git", 2579 | "url": "https://github.com/symfony/event-dispatcher.git", 2580 | "reference": "3ccfcfb96ecce1217d7b0875a0736976bc6e63dc" 2581 | }, 2582 | "dist": { 2583 | "type": "zip", 2584 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3ccfcfb96ecce1217d7b0875a0736976bc6e63dc", 2585 | "reference": "3ccfcfb96ecce1217d7b0875a0736976bc6e63dc", 2586 | "shasum": "" 2587 | }, 2588 | "require": { 2589 | "php": ">=7.1.3", 2590 | "symfony/event-dispatcher-contracts": "^1.1", 2591 | "symfony/polyfill-php80": "^1.16" 2592 | }, 2593 | "conflict": { 2594 | "symfony/dependency-injection": "<3.4" 2595 | }, 2596 | "provide": { 2597 | "psr/event-dispatcher-implementation": "1.0", 2598 | "symfony/event-dispatcher-implementation": "1.1" 2599 | }, 2600 | "require-dev": { 2601 | "psr/log": "^1|^2|^3", 2602 | "symfony/config": "^3.4|^4.0|^5.0", 2603 | "symfony/dependency-injection": "^3.4|^4.0|^5.0", 2604 | "symfony/error-handler": "~3.4|~4.4", 2605 | "symfony/expression-language": "^3.4|^4.0|^5.0", 2606 | "symfony/http-foundation": "^3.4|^4.0|^5.0", 2607 | "symfony/service-contracts": "^1.1|^2", 2608 | "symfony/stopwatch": "^3.4|^4.0|^5.0" 2609 | }, 2610 | "suggest": { 2611 | "symfony/dependency-injection": "", 2612 | "symfony/http-kernel": "" 2613 | }, 2614 | "type": "library", 2615 | "autoload": { 2616 | "psr-4": { 2617 | "Symfony\\Component\\EventDispatcher\\": "" 2618 | }, 2619 | "exclude-from-classmap": [ 2620 | "/Tests/" 2621 | ] 2622 | }, 2623 | "notification-url": "https://packagist.org/downloads/", 2624 | "license": [ 2625 | "MIT" 2626 | ], 2627 | "authors": [ 2628 | { 2629 | "name": "Fabien Potencier", 2630 | "email": "fabien@symfony.com" 2631 | }, 2632 | { 2633 | "name": "Symfony Community", 2634 | "homepage": "https://symfony.com/contributors" 2635 | } 2636 | ], 2637 | "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", 2638 | "homepage": "https://symfony.com", 2639 | "support": { 2640 | "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.37" 2641 | }, 2642 | "funding": [ 2643 | { 2644 | "url": "https://symfony.com/sponsor", 2645 | "type": "custom" 2646 | }, 2647 | { 2648 | "url": "https://github.com/fabpot", 2649 | "type": "github" 2650 | }, 2651 | { 2652 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2653 | "type": "tidelift" 2654 | } 2655 | ], 2656 | "time": "2022-01-02T09:41:36+00:00" 2657 | }, 2658 | { 2659 | "name": "symfony/event-dispatcher-contracts", 2660 | "version": "v1.1.11", 2661 | "source": { 2662 | "type": "git", 2663 | "url": "https://github.com/symfony/event-dispatcher-contracts.git", 2664 | "reference": "01e9a4efac0ee33a05dfdf93b346f62e7d0e998c" 2665 | }, 2666 | "dist": { 2667 | "type": "zip", 2668 | "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/01e9a4efac0ee33a05dfdf93b346f62e7d0e998c", 2669 | "reference": "01e9a4efac0ee33a05dfdf93b346f62e7d0e998c", 2670 | "shasum": "" 2671 | }, 2672 | "require": { 2673 | "php": ">=7.1.3" 2674 | }, 2675 | "suggest": { 2676 | "psr/event-dispatcher": "", 2677 | "symfony/event-dispatcher-implementation": "" 2678 | }, 2679 | "type": "library", 2680 | "extra": { 2681 | "branch-alias": { 2682 | "dev-main": "1.1-dev" 2683 | }, 2684 | "thanks": { 2685 | "name": "symfony/contracts", 2686 | "url": "https://github.com/symfony/contracts" 2687 | } 2688 | }, 2689 | "autoload": { 2690 | "psr-4": { 2691 | "Symfony\\Contracts\\EventDispatcher\\": "" 2692 | } 2693 | }, 2694 | "notification-url": "https://packagist.org/downloads/", 2695 | "license": [ 2696 | "MIT" 2697 | ], 2698 | "authors": [ 2699 | { 2700 | "name": "Nicolas Grekas", 2701 | "email": "p@tchwork.com" 2702 | }, 2703 | { 2704 | "name": "Symfony Community", 2705 | "homepage": "https://symfony.com/contributors" 2706 | } 2707 | ], 2708 | "description": "Generic abstractions related to dispatching event", 2709 | "homepage": "https://symfony.com", 2710 | "keywords": [ 2711 | "abstractions", 2712 | "contracts", 2713 | "decoupling", 2714 | "interfaces", 2715 | "interoperability", 2716 | "standards" 2717 | ], 2718 | "support": { 2719 | "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v1.1.11" 2720 | }, 2721 | "funding": [ 2722 | { 2723 | "url": "https://symfony.com/sponsor", 2724 | "type": "custom" 2725 | }, 2726 | { 2727 | "url": "https://github.com/fabpot", 2728 | "type": "github" 2729 | }, 2730 | { 2731 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2732 | "type": "tidelift" 2733 | } 2734 | ], 2735 | "time": "2021-03-23T15:25:38+00:00" 2736 | }, 2737 | { 2738 | "name": "symfony/filesystem", 2739 | "version": "v5.4.6", 2740 | "source": { 2741 | "type": "git", 2742 | "url": "https://github.com/symfony/filesystem.git", 2743 | "reference": "d53a45039974952af7f7ebc461ccdd4295e29440" 2744 | }, 2745 | "dist": { 2746 | "type": "zip", 2747 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/d53a45039974952af7f7ebc461ccdd4295e29440", 2748 | "reference": "d53a45039974952af7f7ebc461ccdd4295e29440", 2749 | "shasum": "" 2750 | }, 2751 | "require": { 2752 | "php": ">=7.2.5", 2753 | "symfony/polyfill-ctype": "~1.8", 2754 | "symfony/polyfill-mbstring": "~1.8", 2755 | "symfony/polyfill-php80": "^1.16" 2756 | }, 2757 | "type": "library", 2758 | "autoload": { 2759 | "psr-4": { 2760 | "Symfony\\Component\\Filesystem\\": "" 2761 | }, 2762 | "exclude-from-classmap": [ 2763 | "/Tests/" 2764 | ] 2765 | }, 2766 | "notification-url": "https://packagist.org/downloads/", 2767 | "license": [ 2768 | "MIT" 2769 | ], 2770 | "authors": [ 2771 | { 2772 | "name": "Fabien Potencier", 2773 | "email": "fabien@symfony.com" 2774 | }, 2775 | { 2776 | "name": "Symfony Community", 2777 | "homepage": "https://symfony.com/contributors" 2778 | } 2779 | ], 2780 | "description": "Provides basic utilities for the filesystem", 2781 | "homepage": "https://symfony.com", 2782 | "support": { 2783 | "source": "https://github.com/symfony/filesystem/tree/v5.4.6" 2784 | }, 2785 | "funding": [ 2786 | { 2787 | "url": "https://symfony.com/sponsor", 2788 | "type": "custom" 2789 | }, 2790 | { 2791 | "url": "https://github.com/fabpot", 2792 | "type": "github" 2793 | }, 2794 | { 2795 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2796 | "type": "tidelift" 2797 | } 2798 | ], 2799 | "time": "2022-03-02T12:42:23+00:00" 2800 | }, 2801 | { 2802 | "name": "symfony/finder", 2803 | "version": "v5.4.3", 2804 | "source": { 2805 | "type": "git", 2806 | "url": "https://github.com/symfony/finder.git", 2807 | "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d" 2808 | }, 2809 | "dist": { 2810 | "type": "zip", 2811 | "url": "https://api.github.com/repos/symfony/finder/zipball/231313534dded84c7ecaa79d14bc5da4ccb69b7d", 2812 | "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d", 2813 | "shasum": "" 2814 | }, 2815 | "require": { 2816 | "php": ">=7.2.5", 2817 | "symfony/deprecation-contracts": "^2.1|^3", 2818 | "symfony/polyfill-php80": "^1.16" 2819 | }, 2820 | "type": "library", 2821 | "autoload": { 2822 | "psr-4": { 2823 | "Symfony\\Component\\Finder\\": "" 2824 | }, 2825 | "exclude-from-classmap": [ 2826 | "/Tests/" 2827 | ] 2828 | }, 2829 | "notification-url": "https://packagist.org/downloads/", 2830 | "license": [ 2831 | "MIT" 2832 | ], 2833 | "authors": [ 2834 | { 2835 | "name": "Fabien Potencier", 2836 | "email": "fabien@symfony.com" 2837 | }, 2838 | { 2839 | "name": "Symfony Community", 2840 | "homepage": "https://symfony.com/contributors" 2841 | } 2842 | ], 2843 | "description": "Finds files and directories via an intuitive fluent interface", 2844 | "homepage": "https://symfony.com", 2845 | "support": { 2846 | "source": "https://github.com/symfony/finder/tree/v5.4.3" 2847 | }, 2848 | "funding": [ 2849 | { 2850 | "url": "https://symfony.com/sponsor", 2851 | "type": "custom" 2852 | }, 2853 | { 2854 | "url": "https://github.com/fabpot", 2855 | "type": "github" 2856 | }, 2857 | { 2858 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2859 | "type": "tidelift" 2860 | } 2861 | ], 2862 | "time": "2022-01-26T16:34:36+00:00" 2863 | }, 2864 | { 2865 | "name": "symfony/options-resolver", 2866 | "version": "v5.4.3", 2867 | "source": { 2868 | "type": "git", 2869 | "url": "https://github.com/symfony/options-resolver.git", 2870 | "reference": "cc1147cb11af1b43f503ac18f31aa3bec213aba8" 2871 | }, 2872 | "dist": { 2873 | "type": "zip", 2874 | "url": "https://api.github.com/repos/symfony/options-resolver/zipball/cc1147cb11af1b43f503ac18f31aa3bec213aba8", 2875 | "reference": "cc1147cb11af1b43f503ac18f31aa3bec213aba8", 2876 | "shasum": "" 2877 | }, 2878 | "require": { 2879 | "php": ">=7.2.5", 2880 | "symfony/deprecation-contracts": "^2.1|^3", 2881 | "symfony/polyfill-php73": "~1.0", 2882 | "symfony/polyfill-php80": "^1.16" 2883 | }, 2884 | "type": "library", 2885 | "autoload": { 2886 | "psr-4": { 2887 | "Symfony\\Component\\OptionsResolver\\": "" 2888 | }, 2889 | "exclude-from-classmap": [ 2890 | "/Tests/" 2891 | ] 2892 | }, 2893 | "notification-url": "https://packagist.org/downloads/", 2894 | "license": [ 2895 | "MIT" 2896 | ], 2897 | "authors": [ 2898 | { 2899 | "name": "Fabien Potencier", 2900 | "email": "fabien@symfony.com" 2901 | }, 2902 | { 2903 | "name": "Symfony Community", 2904 | "homepage": "https://symfony.com/contributors" 2905 | } 2906 | ], 2907 | "description": "Provides an improved replacement for the array_replace PHP function", 2908 | "homepage": "https://symfony.com", 2909 | "keywords": [ 2910 | "config", 2911 | "configuration", 2912 | "options" 2913 | ], 2914 | "support": { 2915 | "source": "https://github.com/symfony/options-resolver/tree/v5.4.3" 2916 | }, 2917 | "funding": [ 2918 | { 2919 | "url": "https://symfony.com/sponsor", 2920 | "type": "custom" 2921 | }, 2922 | { 2923 | "url": "https://github.com/fabpot", 2924 | "type": "github" 2925 | }, 2926 | { 2927 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 2928 | "type": "tidelift" 2929 | } 2930 | ], 2931 | "time": "2022-01-02T09:53:40+00:00" 2932 | }, 2933 | { 2934 | "name": "symfony/polyfill-ctype", 2935 | "version": "v1.25.0", 2936 | "source": { 2937 | "type": "git", 2938 | "url": "https://github.com/symfony/polyfill-ctype.git", 2939 | "reference": "30885182c981ab175d4d034db0f6f469898070ab" 2940 | }, 2941 | "dist": { 2942 | "type": "zip", 2943 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", 2944 | "reference": "30885182c981ab175d4d034db0f6f469898070ab", 2945 | "shasum": "" 2946 | }, 2947 | "require": { 2948 | "php": ">=7.1" 2949 | }, 2950 | "provide": { 2951 | "ext-ctype": "*" 2952 | }, 2953 | "suggest": { 2954 | "ext-ctype": "For best performance" 2955 | }, 2956 | "type": "library", 2957 | "extra": { 2958 | "branch-alias": { 2959 | "dev-main": "1.23-dev" 2960 | }, 2961 | "thanks": { 2962 | "name": "symfony/polyfill", 2963 | "url": "https://github.com/symfony/polyfill" 2964 | } 2965 | }, 2966 | "autoload": { 2967 | "files": [ 2968 | "bootstrap.php" 2969 | ], 2970 | "psr-4": { 2971 | "Symfony\\Polyfill\\Ctype\\": "" 2972 | } 2973 | }, 2974 | "notification-url": "https://packagist.org/downloads/", 2975 | "license": [ 2976 | "MIT" 2977 | ], 2978 | "authors": [ 2979 | { 2980 | "name": "Gert de Pagter", 2981 | "email": "BackEndTea@gmail.com" 2982 | }, 2983 | { 2984 | "name": "Symfony Community", 2985 | "homepage": "https://symfony.com/contributors" 2986 | } 2987 | ], 2988 | "description": "Symfony polyfill for ctype functions", 2989 | "homepage": "https://symfony.com", 2990 | "keywords": [ 2991 | "compatibility", 2992 | "ctype", 2993 | "polyfill", 2994 | "portable" 2995 | ], 2996 | "support": { 2997 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0" 2998 | }, 2999 | "funding": [ 3000 | { 3001 | "url": "https://symfony.com/sponsor", 3002 | "type": "custom" 3003 | }, 3004 | { 3005 | "url": "https://github.com/fabpot", 3006 | "type": "github" 3007 | }, 3008 | { 3009 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3010 | "type": "tidelift" 3011 | } 3012 | ], 3013 | "time": "2021-10-20T20:35:02+00:00" 3014 | }, 3015 | { 3016 | "name": "symfony/polyfill-mbstring", 3017 | "version": "v1.25.0", 3018 | "source": { 3019 | "type": "git", 3020 | "url": "https://github.com/symfony/polyfill-mbstring.git", 3021 | "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" 3022 | }, 3023 | "dist": { 3024 | "type": "zip", 3025 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", 3026 | "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", 3027 | "shasum": "" 3028 | }, 3029 | "require": { 3030 | "php": ">=7.1" 3031 | }, 3032 | "provide": { 3033 | "ext-mbstring": "*" 3034 | }, 3035 | "suggest": { 3036 | "ext-mbstring": "For best performance" 3037 | }, 3038 | "type": "library", 3039 | "extra": { 3040 | "branch-alias": { 3041 | "dev-main": "1.23-dev" 3042 | }, 3043 | "thanks": { 3044 | "name": "symfony/polyfill", 3045 | "url": "https://github.com/symfony/polyfill" 3046 | } 3047 | }, 3048 | "autoload": { 3049 | "files": [ 3050 | "bootstrap.php" 3051 | ], 3052 | "psr-4": { 3053 | "Symfony\\Polyfill\\Mbstring\\": "" 3054 | } 3055 | }, 3056 | "notification-url": "https://packagist.org/downloads/", 3057 | "license": [ 3058 | "MIT" 3059 | ], 3060 | "authors": [ 3061 | { 3062 | "name": "Nicolas Grekas", 3063 | "email": "p@tchwork.com" 3064 | }, 3065 | { 3066 | "name": "Symfony Community", 3067 | "homepage": "https://symfony.com/contributors" 3068 | } 3069 | ], 3070 | "description": "Symfony polyfill for the Mbstring extension", 3071 | "homepage": "https://symfony.com", 3072 | "keywords": [ 3073 | "compatibility", 3074 | "mbstring", 3075 | "polyfill", 3076 | "portable", 3077 | "shim" 3078 | ], 3079 | "support": { 3080 | "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0" 3081 | }, 3082 | "funding": [ 3083 | { 3084 | "url": "https://symfony.com/sponsor", 3085 | "type": "custom" 3086 | }, 3087 | { 3088 | "url": "https://github.com/fabpot", 3089 | "type": "github" 3090 | }, 3091 | { 3092 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3093 | "type": "tidelift" 3094 | } 3095 | ], 3096 | "time": "2021-11-30T18:21:41+00:00" 3097 | }, 3098 | { 3099 | "name": "symfony/polyfill-php70", 3100 | "version": "v1.20.0", 3101 | "source": { 3102 | "type": "git", 3103 | "url": "https://github.com/symfony/polyfill-php70.git", 3104 | "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" 3105 | }, 3106 | "dist": { 3107 | "type": "zip", 3108 | "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", 3109 | "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", 3110 | "shasum": "" 3111 | }, 3112 | "require": { 3113 | "php": ">=7.1" 3114 | }, 3115 | "type": "metapackage", 3116 | "extra": { 3117 | "branch-alias": { 3118 | "dev-main": "1.20-dev" 3119 | }, 3120 | "thanks": { 3121 | "name": "symfony/polyfill", 3122 | "url": "https://github.com/symfony/polyfill" 3123 | } 3124 | }, 3125 | "notification-url": "https://packagist.org/downloads/", 3126 | "license": [ 3127 | "MIT" 3128 | ], 3129 | "authors": [ 3130 | { 3131 | "name": "Nicolas Grekas", 3132 | "email": "p@tchwork.com" 3133 | }, 3134 | { 3135 | "name": "Symfony Community", 3136 | "homepage": "https://symfony.com/contributors" 3137 | } 3138 | ], 3139 | "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", 3140 | "homepage": "https://symfony.com", 3141 | "keywords": [ 3142 | "compatibility", 3143 | "polyfill", 3144 | "portable", 3145 | "shim" 3146 | ], 3147 | "support": { 3148 | "source": "https://github.com/symfony/polyfill-php70/tree/v1.20.0" 3149 | }, 3150 | "funding": [ 3151 | { 3152 | "url": "https://symfony.com/sponsor", 3153 | "type": "custom" 3154 | }, 3155 | { 3156 | "url": "https://github.com/fabpot", 3157 | "type": "github" 3158 | }, 3159 | { 3160 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3161 | "type": "tidelift" 3162 | } 3163 | ], 3164 | "time": "2020-10-23T14:02:19+00:00" 3165 | }, 3166 | { 3167 | "name": "symfony/polyfill-php72", 3168 | "version": "v1.25.0", 3169 | "source": { 3170 | "type": "git", 3171 | "url": "https://github.com/symfony/polyfill-php72.git", 3172 | "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" 3173 | }, 3174 | "dist": { 3175 | "type": "zip", 3176 | "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", 3177 | "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", 3178 | "shasum": "" 3179 | }, 3180 | "require": { 3181 | "php": ">=7.1" 3182 | }, 3183 | "type": "library", 3184 | "extra": { 3185 | "branch-alias": { 3186 | "dev-main": "1.23-dev" 3187 | }, 3188 | "thanks": { 3189 | "name": "symfony/polyfill", 3190 | "url": "https://github.com/symfony/polyfill" 3191 | } 3192 | }, 3193 | "autoload": { 3194 | "files": [ 3195 | "bootstrap.php" 3196 | ], 3197 | "psr-4": { 3198 | "Symfony\\Polyfill\\Php72\\": "" 3199 | } 3200 | }, 3201 | "notification-url": "https://packagist.org/downloads/", 3202 | "license": [ 3203 | "MIT" 3204 | ], 3205 | "authors": [ 3206 | { 3207 | "name": "Nicolas Grekas", 3208 | "email": "p@tchwork.com" 3209 | }, 3210 | { 3211 | "name": "Symfony Community", 3212 | "homepage": "https://symfony.com/contributors" 3213 | } 3214 | ], 3215 | "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", 3216 | "homepage": "https://symfony.com", 3217 | "keywords": [ 3218 | "compatibility", 3219 | "polyfill", 3220 | "portable", 3221 | "shim" 3222 | ], 3223 | "support": { 3224 | "source": "https://github.com/symfony/polyfill-php72/tree/v1.25.0" 3225 | }, 3226 | "funding": [ 3227 | { 3228 | "url": "https://symfony.com/sponsor", 3229 | "type": "custom" 3230 | }, 3231 | { 3232 | "url": "https://github.com/fabpot", 3233 | "type": "github" 3234 | }, 3235 | { 3236 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3237 | "type": "tidelift" 3238 | } 3239 | ], 3240 | "time": "2021-05-27T09:17:38+00:00" 3241 | }, 3242 | { 3243 | "name": "symfony/polyfill-php73", 3244 | "version": "v1.25.0", 3245 | "source": { 3246 | "type": "git", 3247 | "url": "https://github.com/symfony/polyfill-php73.git", 3248 | "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" 3249 | }, 3250 | "dist": { 3251 | "type": "zip", 3252 | "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", 3253 | "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", 3254 | "shasum": "" 3255 | }, 3256 | "require": { 3257 | "php": ">=7.1" 3258 | }, 3259 | "type": "library", 3260 | "extra": { 3261 | "branch-alias": { 3262 | "dev-main": "1.23-dev" 3263 | }, 3264 | "thanks": { 3265 | "name": "symfony/polyfill", 3266 | "url": "https://github.com/symfony/polyfill" 3267 | } 3268 | }, 3269 | "autoload": { 3270 | "files": [ 3271 | "bootstrap.php" 3272 | ], 3273 | "psr-4": { 3274 | "Symfony\\Polyfill\\Php73\\": "" 3275 | }, 3276 | "classmap": [ 3277 | "Resources/stubs" 3278 | ] 3279 | }, 3280 | "notification-url": "https://packagist.org/downloads/", 3281 | "license": [ 3282 | "MIT" 3283 | ], 3284 | "authors": [ 3285 | { 3286 | "name": "Nicolas Grekas", 3287 | "email": "p@tchwork.com" 3288 | }, 3289 | { 3290 | "name": "Symfony Community", 3291 | "homepage": "https://symfony.com/contributors" 3292 | } 3293 | ], 3294 | "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", 3295 | "homepage": "https://symfony.com", 3296 | "keywords": [ 3297 | "compatibility", 3298 | "polyfill", 3299 | "portable", 3300 | "shim" 3301 | ], 3302 | "support": { 3303 | "source": "https://github.com/symfony/polyfill-php73/tree/v1.25.0" 3304 | }, 3305 | "funding": [ 3306 | { 3307 | "url": "https://symfony.com/sponsor", 3308 | "type": "custom" 3309 | }, 3310 | { 3311 | "url": "https://github.com/fabpot", 3312 | "type": "github" 3313 | }, 3314 | { 3315 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3316 | "type": "tidelift" 3317 | } 3318 | ], 3319 | "time": "2021-06-05T21:20:04+00:00" 3320 | }, 3321 | { 3322 | "name": "symfony/polyfill-php80", 3323 | "version": "v1.25.0", 3324 | "source": { 3325 | "type": "git", 3326 | "url": "https://github.com/symfony/polyfill-php80.git", 3327 | "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" 3328 | }, 3329 | "dist": { 3330 | "type": "zip", 3331 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", 3332 | "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", 3333 | "shasum": "" 3334 | }, 3335 | "require": { 3336 | "php": ">=7.1" 3337 | }, 3338 | "type": "library", 3339 | "extra": { 3340 | "branch-alias": { 3341 | "dev-main": "1.23-dev" 3342 | }, 3343 | "thanks": { 3344 | "name": "symfony/polyfill", 3345 | "url": "https://github.com/symfony/polyfill" 3346 | } 3347 | }, 3348 | "autoload": { 3349 | "files": [ 3350 | "bootstrap.php" 3351 | ], 3352 | "psr-4": { 3353 | "Symfony\\Polyfill\\Php80\\": "" 3354 | }, 3355 | "classmap": [ 3356 | "Resources/stubs" 3357 | ] 3358 | }, 3359 | "notification-url": "https://packagist.org/downloads/", 3360 | "license": [ 3361 | "MIT" 3362 | ], 3363 | "authors": [ 3364 | { 3365 | "name": "Ion Bazan", 3366 | "email": "ion.bazan@gmail.com" 3367 | }, 3368 | { 3369 | "name": "Nicolas Grekas", 3370 | "email": "p@tchwork.com" 3371 | }, 3372 | { 3373 | "name": "Symfony Community", 3374 | "homepage": "https://symfony.com/contributors" 3375 | } 3376 | ], 3377 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 3378 | "homepage": "https://symfony.com", 3379 | "keywords": [ 3380 | "compatibility", 3381 | "polyfill", 3382 | "portable", 3383 | "shim" 3384 | ], 3385 | "support": { 3386 | "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0" 3387 | }, 3388 | "funding": [ 3389 | { 3390 | "url": "https://symfony.com/sponsor", 3391 | "type": "custom" 3392 | }, 3393 | { 3394 | "url": "https://github.com/fabpot", 3395 | "type": "github" 3396 | }, 3397 | { 3398 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3399 | "type": "tidelift" 3400 | } 3401 | ], 3402 | "time": "2022-03-04T08:16:47+00:00" 3403 | }, 3404 | { 3405 | "name": "symfony/process", 3406 | "version": "v5.4.5", 3407 | "source": { 3408 | "type": "git", 3409 | "url": "https://github.com/symfony/process.git", 3410 | "reference": "95440409896f90a5f85db07a32b517ecec17fa4c" 3411 | }, 3412 | "dist": { 3413 | "type": "zip", 3414 | "url": "https://api.github.com/repos/symfony/process/zipball/95440409896f90a5f85db07a32b517ecec17fa4c", 3415 | "reference": "95440409896f90a5f85db07a32b517ecec17fa4c", 3416 | "shasum": "" 3417 | }, 3418 | "require": { 3419 | "php": ">=7.2.5", 3420 | "symfony/polyfill-php80": "^1.16" 3421 | }, 3422 | "type": "library", 3423 | "autoload": { 3424 | "psr-4": { 3425 | "Symfony\\Component\\Process\\": "" 3426 | }, 3427 | "exclude-from-classmap": [ 3428 | "/Tests/" 3429 | ] 3430 | }, 3431 | "notification-url": "https://packagist.org/downloads/", 3432 | "license": [ 3433 | "MIT" 3434 | ], 3435 | "authors": [ 3436 | { 3437 | "name": "Fabien Potencier", 3438 | "email": "fabien@symfony.com" 3439 | }, 3440 | { 3441 | "name": "Symfony Community", 3442 | "homepage": "https://symfony.com/contributors" 3443 | } 3444 | ], 3445 | "description": "Executes commands in sub-processes", 3446 | "homepage": "https://symfony.com", 3447 | "support": { 3448 | "source": "https://github.com/symfony/process/tree/v5.4.5" 3449 | }, 3450 | "funding": [ 3451 | { 3452 | "url": "https://symfony.com/sponsor", 3453 | "type": "custom" 3454 | }, 3455 | { 3456 | "url": "https://github.com/fabpot", 3457 | "type": "github" 3458 | }, 3459 | { 3460 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3461 | "type": "tidelift" 3462 | } 3463 | ], 3464 | "time": "2022-01-30T18:16:22+00:00" 3465 | }, 3466 | { 3467 | "name": "symfony/service-contracts", 3468 | "version": "v2.5.0", 3469 | "source": { 3470 | "type": "git", 3471 | "url": "https://github.com/symfony/service-contracts.git", 3472 | "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" 3473 | }, 3474 | "dist": { 3475 | "type": "zip", 3476 | "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", 3477 | "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", 3478 | "shasum": "" 3479 | }, 3480 | "require": { 3481 | "php": ">=7.2.5", 3482 | "psr/container": "^1.1", 3483 | "symfony/deprecation-contracts": "^2.1" 3484 | }, 3485 | "conflict": { 3486 | "ext-psr": "<1.1|>=2" 3487 | }, 3488 | "suggest": { 3489 | "symfony/service-implementation": "" 3490 | }, 3491 | "type": "library", 3492 | "extra": { 3493 | "branch-alias": { 3494 | "dev-main": "2.5-dev" 3495 | }, 3496 | "thanks": { 3497 | "name": "symfony/contracts", 3498 | "url": "https://github.com/symfony/contracts" 3499 | } 3500 | }, 3501 | "autoload": { 3502 | "psr-4": { 3503 | "Symfony\\Contracts\\Service\\": "" 3504 | } 3505 | }, 3506 | "notification-url": "https://packagist.org/downloads/", 3507 | "license": [ 3508 | "MIT" 3509 | ], 3510 | "authors": [ 3511 | { 3512 | "name": "Nicolas Grekas", 3513 | "email": "p@tchwork.com" 3514 | }, 3515 | { 3516 | "name": "Symfony Community", 3517 | "homepage": "https://symfony.com/contributors" 3518 | } 3519 | ], 3520 | "description": "Generic abstractions related to writing services", 3521 | "homepage": "https://symfony.com", 3522 | "keywords": [ 3523 | "abstractions", 3524 | "contracts", 3525 | "decoupling", 3526 | "interfaces", 3527 | "interoperability", 3528 | "standards" 3529 | ], 3530 | "support": { 3531 | "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" 3532 | }, 3533 | "funding": [ 3534 | { 3535 | "url": "https://symfony.com/sponsor", 3536 | "type": "custom" 3537 | }, 3538 | { 3539 | "url": "https://github.com/fabpot", 3540 | "type": "github" 3541 | }, 3542 | { 3543 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3544 | "type": "tidelift" 3545 | } 3546 | ], 3547 | "time": "2021-11-04T16:48:04+00:00" 3548 | }, 3549 | { 3550 | "name": "symfony/stopwatch", 3551 | "version": "v5.4.5", 3552 | "source": { 3553 | "type": "git", 3554 | "url": "https://github.com/symfony/stopwatch.git", 3555 | "reference": "4d04b5c24f3c9a1a168a131f6cbe297155bc0d30" 3556 | }, 3557 | "dist": { 3558 | "type": "zip", 3559 | "url": "https://api.github.com/repos/symfony/stopwatch/zipball/4d04b5c24f3c9a1a168a131f6cbe297155bc0d30", 3560 | "reference": "4d04b5c24f3c9a1a168a131f6cbe297155bc0d30", 3561 | "shasum": "" 3562 | }, 3563 | "require": { 3564 | "php": ">=7.2.5", 3565 | "symfony/service-contracts": "^1|^2|^3" 3566 | }, 3567 | "type": "library", 3568 | "autoload": { 3569 | "psr-4": { 3570 | "Symfony\\Component\\Stopwatch\\": "" 3571 | }, 3572 | "exclude-from-classmap": [ 3573 | "/Tests/" 3574 | ] 3575 | }, 3576 | "notification-url": "https://packagist.org/downloads/", 3577 | "license": [ 3578 | "MIT" 3579 | ], 3580 | "authors": [ 3581 | { 3582 | "name": "Fabien Potencier", 3583 | "email": "fabien@symfony.com" 3584 | }, 3585 | { 3586 | "name": "Symfony Community", 3587 | "homepage": "https://symfony.com/contributors" 3588 | } 3589 | ], 3590 | "description": "Provides a way to profile code", 3591 | "homepage": "https://symfony.com", 3592 | "support": { 3593 | "source": "https://github.com/symfony/stopwatch/tree/v5.4.5" 3594 | }, 3595 | "funding": [ 3596 | { 3597 | "url": "https://symfony.com/sponsor", 3598 | "type": "custom" 3599 | }, 3600 | { 3601 | "url": "https://github.com/fabpot", 3602 | "type": "github" 3603 | }, 3604 | { 3605 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 3606 | "type": "tidelift" 3607 | } 3608 | ], 3609 | "time": "2022-02-18T16:06:09+00:00" 3610 | }, 3611 | { 3612 | "name": "theseer/tokenizer", 3613 | "version": "1.2.1", 3614 | "source": { 3615 | "type": "git", 3616 | "url": "https://github.com/theseer/tokenizer.git", 3617 | "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" 3618 | }, 3619 | "dist": { 3620 | "type": "zip", 3621 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", 3622 | "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", 3623 | "shasum": "" 3624 | }, 3625 | "require": { 3626 | "ext-dom": "*", 3627 | "ext-tokenizer": "*", 3628 | "ext-xmlwriter": "*", 3629 | "php": "^7.2 || ^8.0" 3630 | }, 3631 | "type": "library", 3632 | "autoload": { 3633 | "classmap": [ 3634 | "src/" 3635 | ] 3636 | }, 3637 | "notification-url": "https://packagist.org/downloads/", 3638 | "license": [ 3639 | "BSD-3-Clause" 3640 | ], 3641 | "authors": [ 3642 | { 3643 | "name": "Arne Blankerts", 3644 | "email": "arne@blankerts.de", 3645 | "role": "Developer" 3646 | } 3647 | ], 3648 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", 3649 | "support": { 3650 | "issues": "https://github.com/theseer/tokenizer/issues", 3651 | "source": "https://github.com/theseer/tokenizer/tree/1.2.1" 3652 | }, 3653 | "funding": [ 3654 | { 3655 | "url": "https://github.com/theseer", 3656 | "type": "github" 3657 | } 3658 | ], 3659 | "time": "2021-07-28T10:34:58+00:00" 3660 | } 3661 | ], 3662 | "aliases": [ 3663 | { 3664 | "package": "peridot-php/leo", 3665 | "version": "dev-php-8", 3666 | "alias": "1.999.999", 3667 | "alias_normalized": "1.999.999.0" 3668 | }, 3669 | { 3670 | "package": "peridot-php/peridot", 3671 | "version": "dev-php-8", 3672 | "alias": "1.999.999", 3673 | "alias_normalized": "1.999.999.0" 3674 | }, 3675 | { 3676 | "package": "peridot-php/peridot-code-coverage-reporters", 3677 | "version": "dev-php-8", 3678 | "alias": "2.999.999", 3679 | "alias_normalized": "2.999.999.0" 3680 | } 3681 | ], 3682 | "minimum-stability": "stable", 3683 | "stability-flags": { 3684 | "peridot-php/leo": 20, 3685 | "peridot-php/peridot": 20, 3686 | "peridot-php/peridot-code-coverage-reporters": 20 3687 | }, 3688 | "prefer-stable": false, 3689 | "prefer-lowest": false, 3690 | "platform": { 3691 | "php": "^7.4" 3692 | }, 3693 | "platform-dev": [], 3694 | "platform-overrides": { 3695 | "php": "7.4" 3696 | }, 3697 | "plugin-api-version": "2.2.0" 3698 | } 3699 | -------------------------------------------------------------------------------- /examples/dns: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | resolve($name); 25 | echo 'Resolved "' . $name . '" to ' . $ip . PHP_EOL; 26 | } catch (Exception $e) { 27 | echo 'Failed to resolve "' . $name . '" - ' . $e->getMessage() . PHP_EOL; 28 | } 29 | } 30 | 31 | // ----------------------------------------------------------------------------- 32 | 33 | ReactKernel::start(function () { 34 | $resolver = (new React\Dns\Resolver\Factory)->create( 35 | '8.8.8.8', 36 | yield Recoil::eventLoop() 37 | ); 38 | 39 | // Yielding an array of coroutines executes them in parallel and waits 40 | // until all have returned a value. 41 | yield [ 42 | resolveDomainName('recoil.io', $resolver), 43 | resolveDomainName('php.net', $resolver), 44 | resolveDomainName('probably-wont-resolve', $resolver), 45 | ]; 46 | 47 | echo 'Done.' . PHP_EOL; 48 | }); 49 | -------------------------------------------------------------------------------- /examples/dns-react: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | resolve($name) 21 | ->then( 22 | function ($ip) use ($name) { 23 | echo 'Resolved "' . $name . '" to ' . $ip . PHP_EOL; 24 | }, 25 | function ($e) use ($name) { 26 | echo 'Failed to resolve "' . $name . '" - ' . $e->getMessage() . PHP_EOL; 27 | } 28 | ); 29 | } 30 | 31 | // ----------------------------------------------------------------------------- 32 | 33 | $loop = \React\EventLoop\Factory::create(); 34 | 35 | $resolver = (new React\Dns\Resolver\Factory)->create( 36 | '8.8.8.8', 37 | $loop 38 | ); 39 | 40 | \React\Promise\all([ 41 | resolveDomainName('recoil.io', $resolver), 42 | resolveDomainName('reactphp.org', $resolver), 43 | resolveDomainName('probably-wont-resolve', $resolver), 44 | ])->then( 45 | function () { 46 | echo 'Done' . PHP_EOL; 47 | } 48 | ); 49 | 50 | $loop->run(); 51 | -------------------------------------------------------------------------------- /examples/exceptions: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | send('The strand was resumed!'); 29 | }); 30 | 31 | echo $value . PHP_EOL; 32 | }); 33 | -------------------------------------------------------------------------------- /examples/stream-raw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | \n\n"; 22 | yield Recoil::write($fp, $buffer); 23 | 24 | fseek($fp, 0); 25 | 26 | while (!feof($fp)) { 27 | echo yield Recoil::read($fp); 28 | } 29 | 30 | fclose($fp); 31 | }); 32 | -------------------------------------------------------------------------------- /peridot.php: -------------------------------------------------------------------------------- 1 | register(); 16 | 17 | Plugin::install($emitter, function () { 18 | return ReferenceKernel::create(); 19 | }); 20 | 21 | $emitter->on('peridot.start', function (Environment $environment) { 22 | $environment->getDefinition()->getArgument('path')->setDefault('test/suite'); 23 | }); 24 | 25 | $emitter->on('code-coverage.start', function (AbstractCodeCoverageReporter $reporter) { 26 | $reporter->addDirectoryToWhitelist(__DIR__ . '/src'); 27 | }); 28 | }; 29 | -------------------------------------------------------------------------------- /src/Event.php: -------------------------------------------------------------------------------- 1 | time = $time; 35 | $this->fn = $fn; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/EventQueue.php: -------------------------------------------------------------------------------- 1 | queue = new SplPriorityQueue(); 23 | } 24 | 25 | /** 26 | * Schedule an event for execution. 27 | * 28 | * Any events scheduled from within an event action function are 29 | * guaranteed not to be executed during the current tick. 30 | * 31 | * @param float $delay The delay before execution, in seconds. 32 | * @param callable $fn The action to perform after the delay. 33 | * 34 | * @return callable A function used to cancel the event. 35 | */ 36 | public function schedule(float $delay, callable $fn): callable 37 | { 38 | $time = \microtime(true) + $delay; 39 | $event = new Event($time, $fn); 40 | 41 | $this->queue->insert($event, -$time); 42 | ++$this->queueSize; 43 | ++$this->pendingEvents; 44 | 45 | if ($this->queueSize === 1 || $time < $this->nextTime) { 46 | $this->nextTime = $time; 47 | } 48 | 49 | return function () use ($event) { 50 | if ($event->fn !== null) { 51 | $event->fn = null; 52 | --$this->pendingEvents; 53 | } 54 | }; 55 | } 56 | 57 | /** 58 | * Execute any pending events and remove them from the queue. 59 | * 60 | * @return int|null The number if microseconds until the next event (null = none). 61 | */ 62 | public function tick() 63 | { 64 | $time = \microtime(true); 65 | 66 | $pendingEvents = $this->pendingEvents; 67 | 68 | try { 69 | while ( 70 | $pendingEvents > 0 && 71 | $this->nextTime <= $time 72 | ) { 73 | $event = $this->queue->extract(); 74 | --$this->queueSize; 75 | 76 | if ($event->fn) { 77 | $fn = $event->fn; 78 | $event->fn = null; 79 | --$pendingEvents; 80 | --$this->pendingEvents; 81 | $fn(); 82 | } 83 | } 84 | } finally { 85 | if ($this->pendingEvents === 0) { 86 | if ($this->queueSize !== 0) { 87 | $this->queue = new SplPriorityQueue(); 88 | $this->queueSize = 0; 89 | } 90 | 91 | return null; 92 | } 93 | 94 | $nextEvent = $this->queue->top(); 95 | $this->nextTime = $nextEvent->time; 96 | } 97 | 98 | $delta = $this->nextTime - \microtime(true); 99 | 100 | if ($delta <= 0) { 101 | return 0; 102 | } 103 | 104 | return (int) ($delta * 1000000); 105 | } 106 | 107 | /** 108 | * @var SplPriorityQueue 109 | */ 110 | private $queue; 111 | 112 | /** 113 | * @var int The number of events in the queue. 114 | */ 115 | private $queueSize = 0; 116 | 117 | /** 118 | * @var int The number of active (uncancelled) events in the queue. 119 | */ 120 | private $pendingEvents = 0; 121 | 122 | /** 123 | * @var float The execution time of the next event in the queue. 124 | */ 125 | private $nextTime = 0; 126 | } 127 | -------------------------------------------------------------------------------- /src/IO.php: -------------------------------------------------------------------------------- 1 | $read 29 | * @param array $write 30 | * @param callable $fn 31 | */ 32 | public function select( 33 | array $read, 34 | array $write, 35 | callable $fn 36 | ): callable { 37 | $select = new IOSelect( 38 | ++$this->nextId, 39 | $read, 40 | $write, 41 | $fn 42 | ); 43 | 44 | $this->selects[$select->id] = $select; 45 | 46 | foreach ($select->read as $fd => $stream) { 47 | $this->readStreams[$fd] = $stream; 48 | $this->readQueue[$fd][$select->id] = $select; 49 | } 50 | 51 | foreach ($select->write as $fd => $stream) { 52 | $this->writeStreams[$fd] = $stream; 53 | $this->writeQueue[$fd][$select->id] = $select; 54 | } 55 | 56 | return function () use ($select) { 57 | unset($this->selects[$select->id]); 58 | 59 | foreach ($select->read as $fd => $stream) { 60 | $queue = &$this->readQueue[$fd]; 61 | 62 | unset($queue[$select->id]); 63 | 64 | if (empty($queue)) { 65 | unset( 66 | $this->readStreams[$fd], 67 | $this->readQueue[$fd] 68 | ); 69 | } 70 | } 71 | 72 | foreach ($select->write as $fd => $stream) { 73 | $queue = &$this->writeQueue[$fd]; 74 | 75 | unset($queue[$select->id]); 76 | 77 | if (empty($queue)) { 78 | unset( 79 | $this->writeStreams[$fd], 80 | $this->writeQueue[$fd] 81 | ); 82 | } 83 | } 84 | }; 85 | } 86 | 87 | /** 88 | * Wait for streams to become ready for reading and/or writing. 89 | * 90 | * @param int|null The maximum time to wait for IO, in microseconds (null = forever). 91 | 92 | * @return int One of the ACTIVE, INACTIVE or INTERRUPTED constants. 93 | */ 94 | public function tick(int $timeout = null): int 95 | { 96 | if ( 97 | empty($this->readStreams) && 98 | empty($this->writeStreams) 99 | ) { 100 | if ($timeout !== null) { 101 | \usleep($timeout); 102 | } 103 | 104 | return self::INACTIVE; 105 | } 106 | 107 | $readStreams = $this->readStreams; 108 | $writeStreams = $this->writeStreams; 109 | $exceptStreams = null; 110 | 111 | $count = @\stream_select( 112 | $readStreams, 113 | $writeStreams, 114 | $exceptStreams, 115 | $timeout === null ? null : 0, 116 | $timeout ?: 0 117 | ); 118 | 119 | // @codeCoverageIgnoreStart 120 | if ($count === false) { 121 | $error = \error_get_last(); 122 | 123 | if ($error === null) { 124 | // Handle cases where stream_select() returns false, but there 125 | // is no error information. This seems to occur when in-memory 126 | // streams are selected, but we can't guarantee that's the 127 | // actual reason ... 128 | throw new RuntimeException( 129 | 'An unknown error occurred while waiting for stream activity.' 130 | ); 131 | } 132 | 133 | if (\stripos($error['message'], 'interrupted system call') === false) { 134 | throw new ErrorException( 135 | $error['message'], 136 | $error['type'], 137 | 1, // severity 138 | $error['file'], 139 | $error['line'] 140 | ); 141 | } 142 | 143 | return self::INTERRUPT; 144 | } 145 | // @codeCoverageIgnoreEnd 146 | 147 | $ready = []; 148 | $readyForRead = []; 149 | $readyForWrite = []; 150 | 151 | foreach ($readStreams as $stream) { 152 | $fd = (int) $stream; 153 | $queue = $this->readQueue[$fd] ?? []; 154 | 155 | foreach ($queue as $select) { 156 | $ready[$select->id] = $select; 157 | $readyForRead[$select->id][] = $stream; 158 | break; 159 | } 160 | } 161 | 162 | foreach ($writeStreams as $stream) { 163 | $fd = (int) $stream; 164 | $queue = $this->writeQueue[$fd] ?? []; 165 | 166 | foreach ($queue as $select) { 167 | $ready[$select->id] = $select; 168 | $readyForWrite[$select->id][] = $stream; 169 | break; 170 | } 171 | } 172 | 173 | foreach ($ready as $select) { 174 | ($select->callback)( 175 | $readyForRead[$select->id] ?? [], 176 | $readyForWrite[$select->id] ?? [] 177 | ); 178 | } 179 | 180 | if ( 181 | empty($this->readStreams) && 182 | empty($this->writeStreams) 183 | ) { 184 | return self::INACTIVE; 185 | } 186 | 187 | return self::ACTIVE; 188 | } 189 | 190 | /** 191 | * @var int A sequence of IDs used to identify registered callbacks. 192 | */ 193 | private $nextId = 0; 194 | 195 | /** 196 | * @var array A map of select ID to IOSelect object. 197 | */ 198 | private $selects = []; 199 | 200 | /** 201 | * @var array A map of resource ID to stream for reading. 202 | */ 203 | private $readStreams = []; 204 | 205 | /** 206 | * @var array> A map of resource ID to a queue 207 | * of IOSelect objects for that stream. 208 | */ 209 | private $readQueue = []; 210 | 211 | /** 212 | * @var array A map of resource ID to stream for writing. 213 | */ 214 | private $writeStreams = []; 215 | 216 | /** 217 | * @var array> A map of resource ID to a queue 218 | * of IOSelect objects for that stream. 219 | */ 220 | private $writeQueue = []; 221 | } 222 | -------------------------------------------------------------------------------- /src/IOSelect.php: -------------------------------------------------------------------------------- 1 | id = $id; 29 | $this->callback = $fn; 30 | 31 | $this->read = []; 32 | foreach ($read as $stream) { 33 | assert(is_resource($stream)); 34 | $this->read[(int) $stream] = $stream; 35 | } 36 | 37 | $this->write = []; 38 | foreach ($write as $stream) { 39 | assert(is_resource($stream)); 40 | $this->write[(int) $stream] = $stream; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/ReferenceApi.php: -------------------------------------------------------------------------------- 1 | events = $events; 29 | $this->io = $io; 30 | } 31 | 32 | /** 33 | * Force the current strand to cooperate. 34 | * 35 | * @see Recoil::cooperate() for the full specification. 36 | * 37 | * @param SystemStrand $strand The strand executing the API call. 38 | * 39 | * @return Generator|null 40 | */ 41 | public function cooperate(SystemStrand $strand) 42 | { 43 | $strand->setTerminator( 44 | $this->events->schedule( 45 | 0, 46 | function () use ($strand) { 47 | $strand->send(); 48 | } 49 | ) 50 | ); 51 | } 52 | 53 | /** 54 | * Suspend the current strand for a fixed interval. 55 | * 56 | * @see Recoil::sleep() for the full specification. 57 | * 58 | * @param SystemStrand $strand The strand executing the API call. 59 | * @param float $interval The interval to wait, in seconds. 60 | * 61 | * @return Generator|null 62 | */ 63 | public function sleep(SystemStrand $strand, float $interval) 64 | { 65 | $strand->setTerminator( 66 | $this->events->schedule( 67 | $interval, 68 | function () use ($strand) { 69 | $strand->send(); 70 | } 71 | ) 72 | ); 73 | } 74 | 75 | /** 76 | * Execute a coroutine with a cap on execution time. 77 | * 78 | * @see Recoil::timeout() for the full specification. 79 | * 80 | * @param SystemStrand $strand The strand executing the API call. 81 | * @param float $timeout The interval to allow for execution, in seconds. 82 | * @param mixed $coroutine The coroutine to execute. 83 | * 84 | * @return Generator|null 85 | */ 86 | public function timeout(SystemStrand $strand, float $timeout, $coroutine) 87 | { 88 | $substrand = $strand->kernel()->execute($coroutine); 89 | 90 | assert($substrand instanceof SystemStrand); 91 | 92 | $awaitable = new StrandTimeout( 93 | $this->events, 94 | $timeout, 95 | $substrand 96 | ); 97 | 98 | $awaitable->await($strand); 99 | } 100 | 101 | /** 102 | * Read data from a stream. 103 | * 104 | * @see Recoil::read() for the full specification. 105 | * 106 | * @param SystemStrand $strand The strand executing the API call. 107 | * @param resource $stream A readable stream resource. 108 | * @param int $minLength The minimum number of bytes to read. 109 | * @param int $maxLength The maximum number of bytes to read. 110 | * 111 | * @return Generator|null 112 | */ 113 | public function read( 114 | SystemStrand $strand, 115 | $stream, 116 | int $minLength, 117 | int $maxLength 118 | ) { 119 | assert($minLength >= 1, 'minimum length must be at least one'); 120 | assert($minLength <= $maxLength, 'minimum length must not exceed maximum length'); 121 | 122 | $buffer = ''; 123 | $done = null; 124 | $done = $this->io->select( 125 | [$stream], 126 | [], 127 | function () use ( 128 | $stream, 129 | $strand, 130 | &$minLength, 131 | &$maxLength, 132 | &$done, 133 | &$buffer 134 | ) { 135 | $chunk = @\fread( 136 | $stream, 137 | $maxLength < self::MAX_READ_LENGTH 138 | ? $maxLength 139 | : self::MAX_READ_LENGTH 140 | ); 141 | 142 | if ($chunk === false) { 143 | // @codeCoverageIgnoreStart 144 | $done(); 145 | $error = \error_get_last(); 146 | $strand->throw( 147 | new ErrorException( 148 | $error['message'], 149 | $error['type'], 150 | 1, // severity 151 | $error['file'], 152 | $error['line'] 153 | ) 154 | ); 155 | // @codeCoverageIgnoreEnd 156 | } elseif ($chunk === '') { 157 | $done(); 158 | $strand->send($buffer); 159 | } else { 160 | $buffer .= $chunk; 161 | $length = \strlen($chunk); 162 | 163 | if ($length >= $minLength || $length === $maxLength) { 164 | $done(); 165 | $strand->send($buffer); 166 | } else { 167 | $minLength -= $length; 168 | $maxLength -= $length; 169 | } 170 | } 171 | } 172 | ); 173 | 174 | $strand->setTerminator($done); 175 | } 176 | 177 | /** 178 | * Write data to a stream. 179 | * 180 | * @see Recoil::write() for the full specification. 181 | * 182 | * @param SystemStrand $strand The strand executing the API call. 183 | * @param resource $stream A writable stream resource. 184 | * @param string $buffer The data to write to the stream. 185 | * @param int $length The maximum number of bytes to write. 186 | * 187 | * @return Generator|null 188 | */ 189 | public function write( 190 | SystemStrand $strand, 191 | $stream, 192 | string $buffer, 193 | int $length 194 | ) { 195 | $bufferLength = \strlen($buffer); 196 | 197 | if ($bufferLength < $length) { 198 | $length = $bufferLength; 199 | } 200 | 201 | if ($length == 0) { 202 | $strand->send(); 203 | 204 | return; 205 | } 206 | 207 | $done = null; 208 | $done = $this->io->select( 209 | [], 210 | [$stream], 211 | function () use ( 212 | $stream, 213 | $strand, 214 | &$done, 215 | &$buffer, 216 | &$length 217 | ) { 218 | $bytes = @\fwrite($stream, $buffer, $length); 219 | 220 | // zero and false both indicate an error 221 | // http://php.net/manual/en/function.fwrite.php#96951 222 | if ($bytes === 0 || $bytes === false) { 223 | // @codeCoverageIgnoreStart 224 | $done(); 225 | $error = \error_get_last(); 226 | $strand->throw( 227 | new ErrorException( 228 | $error['message'], 229 | $error['type'], 230 | 1, // severity 231 | $error['file'], 232 | $error['line'] 233 | ) 234 | ); 235 | // @codeCoverageIgnoreEnd 236 | } elseif ($bytes === $length) { 237 | $done(); 238 | $strand->send(); 239 | } else { 240 | $length -= $bytes; 241 | $buffer = \substr($buffer, $bytes); 242 | } 243 | } 244 | ); 245 | 246 | $strand->setTerminator($done); 247 | } 248 | 249 | /** 250 | * Wait for one or more streams to become readable or writable. 251 | * 252 | * @see Recoil::select() for the full specification. 253 | * 254 | * @param SystemStrand $strand The strand executing the API call. 255 | * @param array $read The set of readable streams. 256 | * @param array $read The set of writable streams. 257 | * 258 | * @return Generator|null 259 | */ 260 | public function select(SystemStrand $strand, array $read, array $write) 261 | { 262 | $done = null; 263 | $done = $this->io->select( 264 | $read, 265 | $write, 266 | function ($read, $write) use ($strand, &$done) { 267 | $done(); 268 | $strand->send([$read, $write]); 269 | } 270 | ); 271 | 272 | $strand->setTerminator($done); 273 | } 274 | 275 | use ApiTrait; 276 | 277 | /** 278 | * The maximum number of bytes to read from a stream in a single call to 279 | * fread(). 280 | */ 281 | const MAX_READ_LENGTH = 32768; 282 | 283 | /** 284 | * @var EventQueue The queue used to schedule events. 285 | */ 286 | private $events; 287 | 288 | /** 289 | * @var IO The object used to perform IO. 290 | */ 291 | private $io; 292 | } 293 | -------------------------------------------------------------------------------- /src/ReferenceKernel.php: -------------------------------------------------------------------------------- 1 | api, 43 | $this->nextId++, 44 | $coroutine 45 | ); 46 | 47 | $strand->setTerminator( 48 | $this->events->schedule( 49 | 0, 50 | function () use ($strand) { 51 | $strand->start(); 52 | } 53 | ) 54 | ); 55 | 56 | return $strand; 57 | } 58 | 59 | /** 60 | * Please note that this code is not part of the public API. It may be 61 | * changed or removed at any time without notice. 62 | * 63 | * @access private 64 | * 65 | * This constructor is public so that it may be used by auto-wiring 66 | * dependency injection containers. If you are explicitly constructing an 67 | * instance please use one of the static factory methods listed below. 68 | * 69 | * @see ReferenceKernel::create() 70 | * 71 | * @param EventQueue $events The queue used to schedule events. 72 | * @param IO $io The object used to perform IO. 73 | * @param Api $api The kernel API exposed to strands. 74 | */ 75 | public function __construct(EventQueue $events, IO $io, Api $api) 76 | { 77 | $this->events = $events; 78 | $this->io = $io; 79 | $this->api = $api; 80 | } 81 | 82 | /** 83 | * The kernel's main event loop. Invoked inside the run() method. 84 | * 85 | * Loop must return when $this->state is KernelState::STOPPING. 86 | * 87 | * @return null 88 | */ 89 | protected function loop() 90 | { 91 | do { 92 | $timeout = $this->events->tick(); 93 | 94 | if ($this->state !== KernelState::RUNNING) { 95 | return; 96 | } 97 | 98 | $io = $this->io->tick($timeout); 99 | 100 | if ($this->state !== KernelState::RUNNING) { 101 | return; 102 | } 103 | } while ($timeout !== null || $io !== IO::INACTIVE); 104 | } 105 | 106 | use KernelTrait; 107 | 108 | /** 109 | * @var EventQueue The queue used to schedule events. 110 | */ 111 | private $events; 112 | 113 | /** 114 | * @var IO The object used to perform IO. 115 | */ 116 | private $io; 117 | 118 | /** 119 | * @var Api The kernel API exposed to strands. 120 | */ 121 | private $api; 122 | 123 | /** 124 | * @var int The next strand ID. 125 | */ 126 | private $nextId = 1; 127 | } 128 | -------------------------------------------------------------------------------- /src/ReferenceStrand.php: -------------------------------------------------------------------------------- 1 | events = $events; 37 | $this->timeout = $timeout; 38 | $this->substrand = $substrand; 39 | } 40 | 41 | /** 42 | * Attach a listener to this object. 43 | * 44 | * @param Listener $listener The object to resume when the work is complete. 45 | */ 46 | public function await(Listener $listener) 47 | { 48 | $this->cancel = $this->events->schedule( 49 | $this->timeout, 50 | function () { 51 | if ($this->substrand) { 52 | $this->substrand->clearPrimaryListener(); 53 | $this->substrand->terminate(); 54 | 55 | $this->listener->throw(TimeoutException::create($this->timeout)); 56 | } 57 | } 58 | ); 59 | 60 | if ($listener instanceof Strand) { 61 | $listener->setTerminator(function () { 62 | if ($this->substrand) { 63 | ($this->cancel)(); 64 | $this->substrand->clearPrimaryListener(); 65 | $this->substrand->terminate(); 66 | } 67 | }); 68 | } 69 | 70 | $this->listener = $listener; 71 | 72 | $this->substrand->setPrimaryListener($this); 73 | } 74 | 75 | /** 76 | * Send the result of a successful operation. 77 | * 78 | * @param mixed $value The operation result. 79 | * @param Strand|null $strand The strand that produced this result upon exit, if any. 80 | */ 81 | public function send($value = null, Strand $strand = null) 82 | { 83 | assert($this->substrand === $strand, 'unknown strand'); 84 | 85 | $this->substrand = null; 86 | ($this->cancel)(); 87 | $this->listener->send($value); 88 | } 89 | 90 | /** 91 | * Send the result of an unsuccessful operation. 92 | * 93 | * @param Throwable $exception The operation result. 94 | * @param Strand|null $strand The strand that produced this exception upon exit, if any. 95 | */ 96 | public function throw(Throwable $exception, Strand $strand = null) 97 | { 98 | assert($this->substrand === $strand, 'unknown strand'); 99 | 100 | $this->substrand = null; 101 | ($this->cancel)(); 102 | $this->listener->throw($exception); 103 | } 104 | 105 | /** 106 | * @var EventQueue The event queue used to schedule the timeout event. 107 | */ 108 | private $events; 109 | 110 | /** 111 | * @var callable|null The function to call to cancel the timeout event. 112 | */ 113 | private $cancel; 114 | 115 | /** 116 | * @var float The timeout, in seconds. 117 | */ 118 | private $timeout; 119 | 120 | /** 121 | * @var Listener|null The object to notify upon completion. 122 | */ 123 | private $listener; 124 | 125 | /** 126 | * @var Strand|null The strand to wait for. 127 | */ 128 | private $substrand; 129 | } 130 | --------------------------------------------------------------------------------