• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

dakujem / peat / 16455680342

22 Jul 2025 09:14PM UTC coverage: 80.42%. Remained the same
16455680342

push

github

dakujem
naming and tweaks

0 of 1 new or added line in 1 file covered. (0.0%)

115 of 143 relevant lines covered (80.42%)

5.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.22
/src/ViteBridge.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Dakujem\Peat;
6

7
use LogicException;
8
use RuntimeException;
9

10
/**
11
 * A factory service providing Vite entry locators.
12
 * Also provides an ability to populate a PHP cache file for performance improvement.
13
 *
14
 * @author Andrej Rypak <xrypak@gmail.com>
15
 */
16
final class ViteBridge
17
{
18
    private string $manifestFile;
19
    private ?string $cacheFile;
20
    private string $assetPathPrefix;
21
    private ?string $devServerUrl;
22
    private bool $strict;
23

24
    /**
25
     * The $assetPath can be used to force absolute paths or set the base path. Ignored by the dev server.
26
     *
27
     * @param string $manifestFile Path to the Vite-generated manifest json file.
28
     * @param string|null $cacheFile This is where this locator stores (and reads from) its cache file. Must be writable.
29
     * @param string $assetPathPrefix This will typically be relative path from the public dir to the dir with assets, or empty string ''.
30
     * @param ?string $devServerUrl Vite's dev server URL (development only).
31
     * @param bool $strict Locators throw exceptions in strict mode, silently fail in lax mode.
32
     */
33
    public function __construct(
34
        string $manifestFile,
35
        ?string $cacheFile = null,
36
        string $assetPathPrefix = '',
37
        ?string $devServerUrl = null,
38
        bool $strict = false
39
    ) {
40
        $this->manifestFile = $manifestFile;
7✔
41
        $this->cacheFile = $cacheFile;
7✔
42
        $this->assetPathPrefix = $assetPathPrefix;
7✔
43
        $this->devServerUrl = $devServerUrl;
7✔
44
        $this->strict = $strict;
7✔
45
    }
7✔
46

47
    // TODO create a separate friction reducer
48
    public static function populateEntryLocator(
49
        bool $detectDevelopmentServer,
50
        string $devServerTellFile,
51
        string $manifestFile,
52
        ?string $cacheFile = null,
53
        string $assetPathPrefix = '',
54
        ?string $devServerUrl = null,
55
        bool $strict = false
56
    ): ViteLocatorContract {
57
        $locators = [];
×
58

59
        // The detection should not run in production.
60
        if ($detectDevelopmentServer) {
×
61
            $locators[] = new TellFileDevelopmentLocator(
×
62
                $devServerTellFile,
63
                $devServerUrl,
64
            );
65
        }
66

67
        // The bundle locator is always active and is the default.
68
        // When the dev server detection is off, the assets are served from a bundle (build).
69
        $locators[] = new ViteBuildLocator(
×
70
            $manifestFile,
71
            $cacheFile,
72
            $assetPathPrefix,
73
            $strict,
74
        );
75

76
        if ($strict) {
×
77
            // In strict mode, the final step is to throw an exception.
78
            $locators[] = function (string $name) {
×
79
                throw new RuntimeException('Not found: ' . $name);
×
80
            };
81
        }
82

83
        // This is a micro optimization: When there is only a single detector (the `ViteBuildLocator`), return it directly.
84
        if (count($locators) === 1) {
×
85
            return $locators[0];
×
86
        }
87

88
        return new CollectiveLocator(...$locators);
×
89
    }
90

91
    /**
92
     * Returns a preconfigured Vite asset entry locator.
93
     * The method attempts to tell if a dev server is running by detecting the presence of a "tell" file.
94
     * Vite should be configured to create such a file when starting the dev server.
95
     *
96
     * In other cases use the `makePassiveEntryLocator` to manually switch between server and bundles.
97
     *
98
     * @param bool $detectServer Set this to `false` in production or when the assets should always be located from a bundle.
99
     * @param string $tellFileName The location of the "tell" file.
100
     */
101
    public function makeEntryLocator(
102
        bool $detectServer,
103
        string $tellFileName
104
    ): ViteLocatorContract {
NEW
105
        return self::populateEntryLocator(
×
106
            $detectServer,
×
107
            $tellFileName,
×
108
            $this->manifestFile,
×
109
            $this->assetPathPrefix,
×
110
            $this->devServerUrl,
×
111
            $this->cacheFile,
×
112
            $this->strict,
×
113
        );
114
    }
115

116
    /**
117
     * Returns a preconfigured asset entry locator.
118
     * This call does not detect whether the dev server is actually running or not (hence "passive").
119
     * Use the `$useDevServer` parameter to switch between Vite development server and bundle.
120
     *
121
     * If the `$useDevServer` is `true`, links to Vite dev server are returned by the locator.
122
     * Otherwise, the returned locator reads the manifest file (or cache file) and serves asset objects.
123
     *
124
     * @param bool $useDevServer Set this to `false` in production and when the assets should be located from a bundle. Set to `true` to use the development server.
125
     */
126
    public function makePassiveEntryLocator(
127
        bool $useDevServer = false
128
    ): ViteLocatorContract {
129
        // If the dev server is used, it serves all the assets.
130
        if ($useDevServer) {
7✔
131
            return $this->makeDevServerEntryLocator();
7✔
132
        }
133
        // Otherwise, the assets are served from a bundle (build).
134
        return $this->makeBundleEntryLocator();
7✔
135
    }
136

137
    /**
138
     * Returns a preconfigured asset entry locator for development.
139
     * The locator returns entries pointing to the Vite development server for any asset being resolved.
140
     */
141
    public function makeDevServerEntryLocator(?string $devServerUrl = null): ViteLocatorContract
142
    {
143
        $devServerUrl ??= $this->devServerUrl;
7✔
144
        if ($devServerUrl === null) {
7✔
145
            throw new LogicException('The development server URL has not been provided.');
7✔
146
        }
147

148
        return new ViteServerLocator($devServerUrl);
7✔
149
    }
150

151
    /**
152
     * Returns a preconfigured asset entry locator for production builds.
153
     * The locator reads the manifest file (or cache file) and serves asset objects.
154
     */
155
    public function makeBundleEntryLocator(): ViteLocatorContract
156
    {
157
        $bundleLocator = new ViteBuildLocator(
7✔
158
            $this->manifestFile,
7✔
159
            $this->cacheFile,
7✔
160
            $this->assetPathPrefix,
7✔
161
            $this->strict,
7✔
162
        );
163
        if (!$this->strict) {
7✔
164
            return $bundleLocator;
7✔
165
        }
166
        // In strict mode, the final step is to throw an exception.
167
        return new CollectiveLocator(
7✔
168
            $bundleLocator,
169
            function (string $name) {
7✔
170
                throw new RuntimeException('Not found: ' . $name);
×
171
            },
7✔
172
        );
173
    }
174

175
    /**
176
     * Populates a cache file to be included instead of parsing the Vite bundle's JSON manifest file.
177
     * Should be called during the deployment/CI process as one of the build steps.
178
     */
179
    public function populateCache(): void
180
    {
181
        (new ViteBuildLocator(
7✔
182
            $this->manifestFile,
7✔
183
            $this->cacheFile,
7✔
184
            $this->assetPathPrefix,
7✔
185
            $this->strict,
7✔
186
        ))
187
            ->populateCache();
7✔
188
    }
7✔
189
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc