Download the PHP package hamzi/portflow without Composer
On this page you can find all versions of the php package hamzi/portflow. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package portflow
PortFlow
Neural bridge for Laravel × Hardware. Connect thermal printers, IoT sensors, RS-232 scales, barcode scanners, and any serial device to your Laravel application — all through a clean, driver-based architecture and the browser's Web Serial API.
Contents
- What is PortFlow?
- Architecture
- Requirements
- Installation
- Quick Start
- Available Drivers
- RAW / JSON (ESP32, Arduino, IoT)
- Barcode Line Driver (USB/TTL Scanners)
- RFID ASCII Driver (STX/ETX Readers)
- Fingerprint Packet Driver (Binary UART)
- ESC/POS (Thermal Printers)
- RS-232 (Scales, Legacy Devices)
- Creating a Custom Driver
- Web Serial Integration
- Backend Direct Serial Mode
- Auto-Reconnect
- Browser Compatibility
- Hardware → Events & Eloquent
- Queue-Based Routing
- Thermal Printing Engine
- IoT Frame Buffering
- Buffer Persistence Across Requests
- Blade & Livewire Components
- Security
- Configuration Reference
- Testing
- Contributing
- License
What is PortFlow?
Most Laravel packages live entirely in software. PortFlow does not.
It bridges physical hardware (printers, scales, sensors, microcontrollers) with Laravel's event system and database, translating raw serial bytes into typed, routable SerialFrame DTOs that your application can consume like any other event.
Architecture
PortFlow follows Clean Architecture — domain logic is completely isolated from infrastructure:
Requirements
| Dependency | Version | Notes |
|---|---|---|
| PHP | ^8.2 |
PHP 8.3+ recommended for Laravel 13 |
| Laravel | ^11.0 \| ^12.0 \| ^13.0 |
All actively supported versions |
| Livewire | ^3.0 |
Browser support for Web Serial API: Chrome 89+, Edge 89+. Not supported in Firefox or Safari.
Installation
Publish the config file:
Publish the JavaScript bridge (optional):
Publish driver stubs (optional — for customising the make:driver template):
Quick Start
1. Add the JS bridge to your layout:
2. Drop in the Livewire connector component:
The connector now bootstraps sensible defaults from config/portflow.php automatically, including the ingest URL, default driver, and baud rate. Override them from Blade when needed instead of rendering a select box for the end user.
If :baud-rate is explicitly passed in Blade, PortFlow gives it priority over remembered localStorage values.
Useful Blade props:
When auto-connect-on-load is enabled, PortFlow asks the browser for already-authorized serial devices with navigator.serial.getPorts() and reconnects automatically after reload when permission still exists.
3. Listen for hardware events in your application:
Register the listener in AppServiceProvider::boot():
Available Drivers
RAW / JSON Driver
Use case: ESP32, Arduino, MQTT-to-serial bridges, custom IoT sensors.
The driver accumulates bytes into an IoTFrameBuffer and emits complete JSON frames when a newline delimiter is detected. Invalid JSON is forwarded as { "raw": "..." } so data is never silently dropped.
Inbound frame from an ESP32:
Mapping it to a Laravel event:
ESC/POS Driver
Use case: Thermal receipt printers and USB barcode scanners (which behave like keyboards).
The ESC/POS driver handles both directions:
- Inbound — scanner sends a barcode string that becomes a
SerialFrame. - Outbound —
PortFlow::encode('escpos', ['text' => $line])returns bytes to send to the printer.
Printing a Blade template:
Building ESC/POS bytes manually:
Available EscPosBuilder methods:
| Method | ESC/POS Command | Description |
|---|---|---|
text(string $value) |
— | Append a line of text |
bold(bool $on = true) |
ESC E n |
Toggle bold |
underline(bool $on = true) |
ESC - n |
Toggle underline |
align(string) |
ESC a n |
'left', 'center', 'right' |
divider(int $width = 48) |
— | Print a dash line separator |
feed(int $lines = 1) |
LF |
Feed blank lines |
cut(bool $partial = false) |
GS V |
Cut paper (full or partial) |
bytes() |
— | Return accumulated byte string |
RS-232 Driver
Use case: Industrial scales, label printers, and legacy serial devices using semicolon-delimited records.
Example record:
Parsed into:
Encoding outbound commands:
Creating a Custom Driver
Using the Artisan Generator
Then register it in your config:
Manually Implementing the Interface
Implement Hamzi\PortFlow\Domain\Contracts\SerialDriver and, for type safety, also implement SerialEvent on any event classes you create:
Register in AppServiceProvider or config:
Defining a Typed Domain Event
Events that do not implement
SerialEventwill still be dispatched, but aLog::warningwill be emitted to encourage type safety.
Web Serial Integration
portflow-serial.js provides a thin wrapper around the Web Serial API that POSTs incoming chunks to Laravel automatically.
Constructor options:
| Option | Type | Default | Description |
|---|---|---|---|
baudRate |
number |
9600 |
Serial baud rate |
autoConnectOnLoad |
boolean |
true |
Reconnect automatically after reload when the browser already trusts the port |
driver |
string |
'raw-json' |
PortFlow driver name |
ingestUrl |
string |
'/portflow/ingest' |
Backend endpoint |
csrfToken |
string |
auto-detected | CSRF token for POST |
rememberBaudRate |
boolean |
true |
Persist the last selected baud rate in localStorage |
filters |
array |
[] |
Web Serial port filters used by requestPort() |
browserChunkEvent |
string |
'portflow-frame-received' |
Browser event name emitted for received chunks |
livewireChunkEvent |
string |
'portflow-frame-received' |
Livewire event name emitted for received chunks |
livewireStatusEvent |
string |
'portflow-status-updated' |
Livewire event name emitted for connection status |
livewireErrorEvent |
string |
'portflow-error' |
Livewire event name emitted for bridge errors |
autoReconnect |
boolean |
true |
Auto-reconnect on disconnect |
maxRetries |
number |
5 |
Max reconnect attempts |
retryDelay |
number |
2000 |
Base delay in ms (exponential back-off) |
Window events:
Auto-Reconnect
When a serial connection drops unexpectedly, the bridge automatically attempts to reconnect using exponential back-off (2 s, 4 s, 8 s, …) up to maxRetries attempts. This is enabled by default and requires no configuration.
Backend Direct Serial Mode
Some devices are easier or safer to integrate from the backend (Linux service, kiosk daemon, headless station) rather than browser Web Serial. PortFlow includes an Artisan listener:
Windows example:
Advanced UART parameters:
Show incoming serial payloads in the console while still ingesting frames:
Data preview options:
--show-data=1enables payload preview logs.--show-data-format=auto|raw|plain|json|hex|base64controls rendering format.--show-data-max=512limits displayed bytes per chunk to keep logs readable.
Security and hardening notes:
- Device path validation supports
/dev/*on Linux/macOS andCOMx/\\.\COMxon Windows. - Use
portflow.backend.allowed_devicesto allowlist exact/glob device paths. - Listener configures serial parameters with platform-native tooling (
sttyon POSIX,modeon Windows). - Ingest now validates decoded base64 chunk size against
max_chunk_bytes.
config/portflow.php backend section:
To disable:
Alpine.js integration (built-in):
Browser Compatibility
The Web Serial API is only available in Chromium-based browsers (Chrome 89+ / Edge 89+). Firefox and Safari do not support it.
Check support in JavaScript:
Check support in Blade (no Alpine required):
The component renders a yellow warning banner with a "Download Chrome" link in Firefox/Safari, and leaves the content untouched in supported browsers.
Customise the message and hide the download link:
| Browser | Web Serial | Status |
|---|---|---|
| Chrome 89+ | ✅ | Supported |
| Edge 89+ | ✅ | Supported |
| Firefox | ❌ | Not supported (flag-only, no stable release) |
| Safari / iOS | ❌ | Not supported |
| Opera (Chromium) | ✅ | Supported |
Hardware → Events & Eloquent
The mappings config key lets you automatically route frames to Laravel events or Eloquent models without writing controller code.
If a mapping's event or model throws an exception, it is caught and written to Log::error so one bad handler never breaks other mappings or the HTTP response.
Queue-Based Routing
For high-throughput or slow listeners, route frames asynchronously via the queue:
Or in .env:
When enabled, each SerialFrame is dispatched as a RouteSerialFrameJob (3 retries by default) on the configured queue connection. The HTTP response is returned immediately.
Thermal Printing Engine
PortFlow ships a Blade-to-ESC/POS renderer so you can design receipts in familiar Blade syntax:
resources/views/receipts/order.blade.php
In a controller or job:
IoT Frame Buffering
IoTFrameBuffer is a standalone utility that accumulates streaming bytes and emits complete frames when a delimiter is found. Use it independently for any stream protocol:
Buffer Persistence Across Requests
IoT devices may split a JSON packet across multiple HTTP requests. Pass a session_id in the request context and the RawJsonDriver will automatically persist the buffer state in the Laravel cache between requests (5-minute TTL):
JavaScript (add session_id to the context):
Or POST directly from firmware:
A subsequent request with the same session_id will complete and emit the frame:
The backend will emit one complete SerialFrame with { "sensor": "temp", "value": 22.5 }.
Requires a cache driver other than
arrayin production (e.g.,redis,database).
Blade & Livewire Components
Blade
portflow-browser-check wraps any slot content and injects a styled warning banner when the browser does not support the Web Serial API. See the Browser Compatibility section for full options.
Livewire
The PortFlowStatus component listens for the portflow-status-updated browser event dispatched by the JS bridge automatically.
Security
| Protection | Detail |
|---|---|
| Rate limiting | 60 requests / minute per IP by default. Configurable via portflow.ingest_rate_limit or PORTFLOW_RATE_LIMIT env. Returns 429 when exceeded. |
| Chunk size limit | Inbound chunk field capped at 16 384 bytes (configurable). Returns 422 on violation. |
| CSRF | Ingest endpoint inherits the web middleware group (CSRF enforced). Switch to ['api'] if using token auth. |
| Event type safety | Events used in mappings should implement SerialEvent. A Log::warning is emitted for non-conforming classes. |
Configuration Reference
Barcode Line Driver
Use case: common 1D/2D barcode scanners in serial mode (USB CDC, TTL UART, RS-232 adapters).
Most scanners send ASCII text followed by a line terminator (\r, \n, or both). barcode-line normalizes this into:
Recommended config:
RFID ASCII Driver
Use case: 125kHz serial readers (for example ID-12/ID-20 family) that send framed ASCII.
A common frame format is:
STX (0x02)- ASCII tag bytes
CR+LFETX (0x03)
rfid-ascii parses this safely and emits payload like:
Recommended config:
Fingerprint Packet Driver
Use case: optical/capacitive UART fingerprint modules that speak binary packet protocol (common start code 0xEF01).
Unlike barcode/RFID text streams, fingerprint sensors are binary. PortFlow now supports binary chunks over web ingest using chunk_encoding: base64 automatically in the JS bridge.
fingerprint-packet validates checksums and emits parsed packet metadata:
Recommended config:
Device Patterns Supported Out-of-the-box
| Device Type | Common Serial Pattern | Recommended Driver |
|---|---|---|
| Barcode scanners | ASCII + CR/LF terminator | barcode-line |
| RFID serial readers | STX + TAG + CRLF + ETX |
rfid-ascii |
| Fingerprint sensors | Binary framed packets (EF01 ... checksum) |
fingerprint-packet |
Testing
Run with coverage:
Lint & style:
Static analysis:
Contributing
Contributions are welcome. Please:
- Fork the repository and create a feature branch.
- Write tests for all new behaviour.
- Run
composer formatandcomposer analysebefore submitting. - Open a Pull Request with a clear description of the change.
See CONTRIBUTING.md for full guidelines.
License
The MIT License. See LICENSE for details.
All versions of portflow with dependencies
illuminate/bus Version ^11.0|^12.0|^13.0
illuminate/cache Version ^11.0|^12.0|^13.0
illuminate/contracts Version ^11.0|^12.0|^13.0
illuminate/database Version ^11.0|^12.0|^13.0
illuminate/events Version ^11.0|^12.0|^13.0
illuminate/http Version ^11.0|^12.0|^13.0
illuminate/queue Version ^11.0|^12.0|^13.0
illuminate/routing Version ^11.0|^12.0|^13.0
illuminate/support Version ^11.0|^12.0|^13.0
livewire/livewire Version ^3.0