create-prisma-php-app 5.1.0-alpha.23 → 5.1.0-alpha.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -2
- package/dist/.github/copilot-instructions.md +21 -1
- package/dist/AGENTS.md +36 -20
- package/dist/bootstrap.php +205 -187
- package/dist/index.js +1 -1
- package/dist/settings/bs-config.ts +44 -1
- package/dist/settings/run-tests.ts +35 -0
- package/dist/src/Lib/Auth/Auth.php +12 -25
- package/dist/src/Lib/Websocket/ConnectionManager.php +500 -47
- package/dist/src/Lib/Websocket/Socket.php +170 -0
- package/dist/src/Lib/Websocket/SocketPool.php +50 -0
- package/dist/src/Lib/Websocket/SocketRegistry.php +88 -0
- package/dist/src/Lib/Websocket/sockets.php +50 -0
- package/dist/src/Lib/Websocket/websocket-server.php +10 -3
- package/dist/tests/AuthTest.php +59 -0
- package/dist/tests/ConnectionManagerTest.php +277 -0
- package/dist/tests/CsrfTest.php +119 -0
- package/dist/tests/FeaturesTest.php +41 -0
- package/dist/tests/README.md +118 -0
- package/dist/tests/RpcWireContractTest.php +101 -0
- package/dist/tests/SocketPoolTest.php +69 -0
- package/dist/tests/SocketRegistryTest.php +77 -0
- package/dist/tests/SocketTest.php +124 -0
- package/dist/tests/SocketsRegistrationTest.php +40 -0
- package/dist/tests/Support/FakeConnection.php +62 -0
- package/dist/tests/Support/Features.php +38 -0
- package/dist/tests/Support/RequiresFeature.php +26 -0
- package/dist/tests/bootstrap.php +44 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,10 +36,14 @@ If you are using XAMPP on Windows, enabling `extension=zip` in `php.ini` is reco
|
|
|
36
36
|
Prisma PHP brings together the core pieces needed to build full-stack PHP apps:
|
|
37
37
|
|
|
38
38
|
- **Native PHP + modern reactivity** with PulsePoint
|
|
39
|
+
- **Direct RPC from the frontend** with `pp.rpc(...)` calling `#[Exposed]` PHP functions — JSON in, JSON out, SSE streaming when the function yields, and framework failures reported as real HTTP statuses
|
|
40
|
+
- **Named sockets for realtime** with `pp.socket(...)` — long-lived bidirectional messaging (chat, presence, live feeds) served by a Ratchet-based socket server with per-socket auth, origin checks, and rate limits
|
|
39
41
|
- **PHPX component system** for reusable UI composition
|
|
40
42
|
- **Prisma PHP ORM** for schema-first, type-safe database access
|
|
41
43
|
- **Built-in authentication patterns** for sessions, route protection, RBAC, credentials auth, and provider login
|
|
44
|
+
- **Hardened request pipeline** with double-submit CSRF (`pp_csrf` cookie family), origin validation, content-type checks, and per-function rate limiting
|
|
42
45
|
- **File-based routing** with clear route file conventions
|
|
46
|
+
- **App-level test suite** with PHPUnit in a root `tests/` directory, run with `npm run test`, feature-aware via `prisma-php.json`
|
|
43
47
|
- **CLI scaffolding** for new apps, starter kits, and optional features
|
|
44
48
|
- **Flexible deployment options** for local development and production workflows
|
|
45
49
|
|
|
@@ -117,7 +121,10 @@ Use these docs as the main entry points for common work:
|
|
|
117
121
|
- `project-structure.md` for project structure, route placement, and file conventions
|
|
118
122
|
- `layouts-and-pages.md` for pages, layouts, nested routes, and dynamic routes
|
|
119
123
|
- `components.md` for PHPX components, props, children, fragments, icons, buttons, and composition
|
|
120
|
-
- `fetching-data.md` for `pp.
|
|
124
|
+
- `fetching-data.md` for `pp.rpc(...)`, `#[Exposed]`, streaming, and the RPC error contract
|
|
125
|
+
- `websocket.md` for named sockets, `pp.socket(...)`, `SocketRegistry`, and the realtime wire contract
|
|
126
|
+
- `bootstrap-runtime.md` for the runtime init order, PulsePoint wire headers, and the `pp_csrf` CSRF contract
|
|
127
|
+
- `testing.md` for the root `tests/` directory, `npm run test`, and feature-gated tests
|
|
121
128
|
- `prisma-php-orm.md` for Prisma ORM, `schema.prisma`, migrations, and generated PHP classes
|
|
122
129
|
- `authentication.md` for auth strategy, sessions, RBAC, credentials auth, and provider flows
|
|
123
130
|
- `file-manager.md` for uploads, `multipart/form-data`, `$_FILES`, and `PP\FileManager\UploadFile`
|
|
@@ -152,13 +159,15 @@ For task-specific route decision rules and framework generation rules, read `AGE
|
|
|
152
159
|
|
|
153
160
|
## PulsePoint and Frontend Reactivity
|
|
154
161
|
|
|
155
|
-
Prisma PHP uses PulsePoint for browser-side reactivity.
|
|
162
|
+
Prisma PHP uses PulsePoint for browser-side reactivity and as the wire between the page and PHP.
|
|
156
163
|
|
|
157
164
|
When working with runtime features such as:
|
|
158
165
|
|
|
159
166
|
- `pp.state`
|
|
160
167
|
- `pp.effect`
|
|
161
168
|
- `pp.ref`
|
|
169
|
+
- `pp.rpc` for frontend-to-PHP calls (with streaming, uploads, and redirects)
|
|
170
|
+
- `pp.socket` for named-socket realtime messaging
|
|
162
171
|
- `pp-for`
|
|
163
172
|
- `pp-spread`
|
|
164
173
|
- `pp-ref`
|
|
@@ -179,11 +188,23 @@ prisma-php-project/
|
|
|
179
188
|
├── public/ # public entry point and assets
|
|
180
189
|
├── settings/ # project configuration
|
|
181
190
|
├── src/ # application source code
|
|
191
|
+
├── tests/ # app-level PHPUnit tests (npm run test)
|
|
182
192
|
├── package.json # frontend/dev scripts
|
|
183
193
|
├── composer.json # PHP dependencies
|
|
194
|
+
├── phpunit.xml # test suite configuration
|
|
184
195
|
└── prisma-php.json # Prisma PHP project capability manifest
|
|
185
196
|
```
|
|
186
197
|
|
|
198
|
+
## Testing
|
|
199
|
+
|
|
200
|
+
App tests live in the root `tests/` directory and run with:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
npm run test
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The suite runs PHPUnit on the PHP binary configured in `prisma-php.json`, uses a deterministic test environment (the real `.env` is never loaded), and is feature-aware: tests for optional features such as WebSocket skip cleanly when the feature is disabled in `prisma-php.json`. Read `testing.md` in the installed docs and the project's `tests/README.md` for the full contract.
|
|
207
|
+
|
|
187
208
|
## Updating Existing Projects
|
|
188
209
|
|
|
189
210
|
When enabling features or syncing framework-managed project files:
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
## PulsePoint-First Frontend Rules
|
|
103
103
|
|
|
104
104
|
- In full-stack Prisma PHP apps, treat PulsePoint as the primary JavaScript authoring model for frontend behavior.
|
|
105
|
-
- For page-local interactivity, prefer `index.php` or nested `layout.php` with a plain inline `<script>` that contains PulsePoint state and functions directly, and use `pp.
|
|
105
|
+
- For page-local interactivity, prefer `index.php` or nested `layout.php` with a plain inline `<script>` that contains PulsePoint state and functions directly, and use `pp.rpc(...)` for backend calls.
|
|
106
106
|
- Do not wrap inline PulsePoint code in `DOMContentLoaded`, IIFEs, manual `pp.mount()` calls, or custom scoping/bootstrap helpers. Prisma PHP scopes the component boundary and runs the script for you.
|
|
107
107
|
- Reserve plain browser JavaScript or TypeScript modules for reusable helpers in `ts/`, third-party libraries, low-level browser APIs, or behavior that does not belong inside a PulsePoint component boundary.
|
|
108
108
|
- Do not treat app-registered helpers such as `twMerge(...)` as PulsePoint built-ins; only use them after the relevant Prisma PHP feature flag and entry-file docs confirm they exist.
|
|
@@ -111,6 +111,16 @@
|
|
|
111
111
|
- Use `pp.ref(...)`, `pp-ref`, `pp.portal(...)`, `pp.createContext(...)`, `Context.Provider`, and `pp.context(...)` according to `pulsepoint.md`.
|
|
112
112
|
- Use `value`, `defaultvalue`, and `defaultchecked` form bindings according to `pulsepoint.md`; do not author internal `data-pp-*` runtime attributes.
|
|
113
113
|
|
|
114
|
+
## Runtime Wire Contract
|
|
115
|
+
|
|
116
|
+
- `pp.rpc(functionName, data?, optionsOrAbort?)` is the frontend-to-PHP call API. The former `pp.fetchFunction(...)` no longer exists in the runtime; never generate or document it.
|
|
117
|
+
- Every function called through `pp.rpc(...)` must be marked `#[Exposed]` on the PHP side.
|
|
118
|
+
- Framework-level RPC failures (unknown function, auth, roles, CSRF, origin, content type, rate limit, server error) arrive as HTTP error statuses with an `{"error": "..."}` JSON body and reject the `pp.rpc(...)` promise; wrap calls in `try/catch` when the UI reacts to failures. Return routine validation feedback as structured data instead of throwing. Throwing `InvalidArgumentException` in an exposed function is the sanctioned validation crossover: its message reaches the caller as a 400.
|
|
119
|
+
- Streamed responses: an exposed function that yields streams SSE `data:` lines; consume them with `onStream`, `onStreamError`, and `onStreamComplete`.
|
|
120
|
+
- CSRF: the runtime reads the `pp_csrf` cookie family (`pp_csrf_<port>` in development, `pp_csrf` otherwise), managed server-side by `PP\Security\Csrf` and signed with `FUNCTION_CALL_SECRET`. Do not document or generate the removed `prisma_php_csrf` cookie.
|
|
121
|
+
- Realtime: use `pp.socket(name, args, handlers)` (named sockets) for long-lived bidirectional flows. Server handlers are registered with `SocketRegistry::register(...)` in `src/Lib/Websocket/sockets.php`; the wire is one endpoint (`/__pulsepoint/ws?name=...`), arguments as the first JSON frame, JSON frames both ways, and `{"error": "..."}` reserved for failures. Do not generate raw `new WebSocket(...)` wiring for app realtime work.
|
|
122
|
+
- Read `node_modules/prisma-php/dist/docs/fetching-data.md`, `bootstrap-runtime.md`, and `websocket.md` for the full contracts.
|
|
123
|
+
|
|
114
124
|
## Route File Conventions
|
|
115
125
|
|
|
116
126
|
- For PulsePoint-aware `index.php` and nested `layout.php`, keep file order as PHP first, then one parent HTML element as the route boundary, then the visible route content inside that boundary, and keep the PulsePoint `<script>` as the last child of that boundary root.
|
|
@@ -140,6 +150,15 @@
|
|
|
140
150
|
- Return structured validation results for expected failures instead of treating routine invalid input as an uncaught exception.
|
|
141
151
|
- When internals matter, inspect `vendor/tsnc/prisma-php/src/Validator.php` and `vendor/tsnc/prisma-php/src/Rule.php`.
|
|
142
152
|
|
|
153
|
+
## Testing Rules
|
|
154
|
+
|
|
155
|
+
- App tests live in the root `tests/` directory and run with `npm run test` (PHPUnit via `settings/run-tests.ts`, using the PHP binary from `prisma-php.json`). Narrow runs with `npm run test -- --filter <NameOrMethod>`.
|
|
156
|
+
- When adding or changing app behavior with logic worth protecting (exposed-function validation, socket handlers, auth rules, `src/Lib` helpers), add or update the matching `tests/*Test.php` in the same change and run `npm run test` before declaring the work done.
|
|
157
|
+
- Tests cover app-level code and the wire contracts the app depends on; do not test Prisma PHP framework internals from the app suite.
|
|
158
|
+
- Tests of optional features (`websocket`, `mcp`, `swaggerDocs`, `prisma`, ...) must guard on the `prisma-php.json` flag via the `Tests\Support\RequiresFeature` trait (`$this->requireFeature('websocket')` as the first line of `setUp()`), so a disabled feature skips cleanly instead of fataling on missing scaffold classes. Core surfaces (CSRF, wire headers, auth) are never gated.
|
|
159
|
+
- `tests/bootstrap.php` sets a deterministic env (no real `.env`); shared fakes live in `tests/Support` (`Tests\Support\...`). Socket wire tests use `Tests\Support\FakeConnection` and assert frames plus close codes.
|
|
160
|
+
- Read `node_modules/prisma-php/dist/docs/testing.md` and the project's `tests/README.md` before writing tests.
|
|
161
|
+
|
|
143
162
|
## Relevant Docs
|
|
144
163
|
|
|
145
164
|
- Project structure and feature placement: `node_modules/prisma-php/dist/docs/project-structure.md`
|
|
@@ -168,3 +187,4 @@
|
|
|
168
187
|
- Metadata and icons: `node_modules/prisma-php/dist/docs/metadata-and-og-images.md`
|
|
169
188
|
- API-style handlers and webhooks: `node_modules/prisma-php/dist/docs/route-handlers.md`
|
|
170
189
|
- Swagger/OpenAPI generation and `swaggerDocs`: `node_modules/prisma-php/dist/docs/swagger-docs.md`
|
|
190
|
+
- App test suite, `tests/` layout, and `npm run test`: `node_modules/prisma-php/dist/docs/testing.md`
|
package/dist/AGENTS.md
CHANGED
|
@@ -49,7 +49,8 @@ Use this map only after `prisma-php.json`, matching workspace instructions, inst
|
|
|
49
49
|
| imported PHP partial execution, one-root enforcement, prop serialization, imported `#[Exposed]` functions | `vendor/tsnc/prisma-php/src/ImportComponent.php` |
|
|
50
50
|
| metadata, custom head tags, dynamic head/footer scripts | `vendor/tsnc/prisma-php/src/MainLayout.php` |
|
|
51
51
|
| route and component maps | `vendor/tsnc/prisma-php/src/PrismaPHPSettings.php`, `settings/files-list.json`, `settings/component-map.json` |
|
|
52
|
-
| request data, dynamic params, redirects,
|
|
52
|
+
| request data, dynamic params, redirects, RPC/navigation wire detection (`$isRpc`, `$isNavigation`, `$isWire`) | `vendor/tsnc/prisma-php/src/Request.php` |
|
|
53
|
+
| CSRF cookie family (`pp_csrf`, `pp_csrf_<port>`), token issuing and validation | `vendor/tsnc/prisma-php/src/Security/Csrf.php` |
|
|
53
54
|
| exposed functions | `vendor/tsnc/prisma-php/src/Attributes/Exposed.php`, `vendor/tsnc/prisma-php/src/Attributes/ExposedRegistry.php` |
|
|
54
55
|
| validation | `vendor/tsnc/prisma-php/src/Validator.php`, `vendor/tsnc/prisma-php/src/Rule.php` |
|
|
55
56
|
| env values | `vendor/tsnc/prisma-php/src/Env.php` |
|
|
@@ -124,7 +125,7 @@ Use the docs router to learn how Prisma PHP implements a task. Use `./prisma-php
|
|
|
124
125
|
- **TypeScript frontend tooling, the `typescript` feature flag, the root `ts/` directory, `ts/main.ts`, npm packages, or registered browser helpers used from template expressions and PulsePoint scripts**
|
|
125
126
|
Read `typescript.md`, then use `pulsepoint.md`, `layouts-and-pages.md`, or `components.md` for the affected component boundary
|
|
126
127
|
|
|
127
|
-
- **Loading data, calling backend logic from the frontend, `pp.
|
|
128
|
+
- **Loading data, calling backend logic from the frontend, `pp.rpc(...)`, `#[Exposed]`, route-local mutations, streaming responses, or interactive backend validation**
|
|
128
129
|
Read `fetching-data.md`
|
|
129
130
|
|
|
130
131
|
- **AI integration, provider SDKs, chat UIs, streamed assistant output, or deciding between page-local assistant UI, websocket, and MCP tools**
|
|
@@ -139,7 +140,7 @@ Use the docs router to learn how Prisma PHP implements a task. Use `./prisma-php
|
|
|
139
140
|
- **Environment variables, `.env`, `PP\Env`, `Env::get`, `Env::string`, `Env::bool`, `Env::int`, feature flags, host and port config, or runtime bootstrap settings**
|
|
140
141
|
Read `env.md`, then verify the official env docs at `env` and `env-file`
|
|
141
142
|
|
|
142
|
-
- **Bootstrap flow, request initialization, `FUNCTION_CALL_SECRET`, `
|
|
143
|
+
- **Bootstrap flow, request initialization, `FUNCTION_CALL_SECRET`, `pp_csrf`, route resolution, or runtime init order**
|
|
143
144
|
Read `bootstrap-runtime.md`, then use `env.md`, `fetching-data.md`, or `error-handling.md` as needed
|
|
144
145
|
|
|
145
146
|
- **File uploads, `multipart/form-data`, `$_FILES`, `PP\FileManager\UploadFile`, rename flows, replace flows, delete flows, allowed file types, upload size rules, or file manager UI behavior**
|
|
@@ -148,7 +149,7 @@ Use the docs router to learn how Prisma PHP implements a task. Use `./prisma-php
|
|
|
148
149
|
- **SMTP setup, `.env` mail variables, `PP\PHPMailer\Mailer`, HTML bodies, plain-text bodies, recipients, reply-to, CC, BCC, or attachments**
|
|
149
150
|
Read `email.md`, then verify the official email docs at `email-get-started`
|
|
150
151
|
|
|
151
|
-
- **
|
|
152
|
+
- **Named sockets, `pp.socket(...)`, `SocketRegistry`, `Socket`, `SocketPool`, the Ratchet socket server, or realtime route behavior**
|
|
152
153
|
Read `websocket.md`, then verify the official websocket docs in this order: `websocket-get-started`, `websocket-chat-app`
|
|
153
154
|
|
|
154
155
|
- **MCP support, `#[McpTool]`, `#[Schema]`, `PhpMcp\Server\Server`, `StreamableHttpServerTransport`, AI tool endpoints, or `src/Lib/MCP/mcp-server.php`**
|
|
@@ -175,6 +176,9 @@ Use the docs router to learn how Prisma PHP implements a task. Use `./prisma-php
|
|
|
175
176
|
- **Swagger or OpenAPI generation, `swaggerDocs`, `pphp-swagger.json`, `create-swagger-docs`, or `settings/prisma-schema-config.json`**
|
|
176
177
|
Read `swagger-docs.md`
|
|
177
178
|
|
|
179
|
+
- **Writing or running app tests, PHPUnit, the root `tests/` directory, `npm run test`, or verifying a change with the test suite**
|
|
180
|
+
Read `testing.md`, then the project's `tests/README.md`
|
|
181
|
+
|
|
178
182
|
- **Upgrading Prisma PHP, enabling features, syncing framework-managed project files, or running project updates**
|
|
179
183
|
Read `upgrading.md`
|
|
180
184
|
|
|
@@ -207,6 +211,7 @@ The current Prisma PHP docs shipped here include:
|
|
|
207
211
|
- `pulsepoint.md`
|
|
208
212
|
- `route-handlers.md`
|
|
209
213
|
- `swagger-docs.md`
|
|
214
|
+
- `testing.md`
|
|
210
215
|
- `typescript.md`
|
|
211
216
|
- `upgrading.md`
|
|
212
217
|
- `validator.md`
|
|
@@ -216,7 +221,7 @@ This inventory exists to help AI find the right Prisma PHP guidance quickly. It
|
|
|
216
221
|
|
|
217
222
|
When a task depends on optional capabilities such as `backendOnly`, `swaggerDocs`, `typescript`, `websocket`, or `mcp`, inspect `./prisma-php.json` before assuming the generated scaffold exists.
|
|
218
223
|
|
|
219
|
-
When adding or reviewing AI guidance, do not stop at older docs only. Make sure the guidance also covers `backend-only.md`, `email.md`, `env.md`, `get-started-ia.md`, `mcp.md`, `swagger-docs.md`, `typescript.md`, and `websocket.md`, plus newer behavior documented in `fetching-data.md
|
|
224
|
+
When adding or reviewing AI guidance, do not stop at older docs only. Make sure the guidance also covers `backend-only.md`, `email.md`, `env.md`, `get-started-ia.md`, `mcp.md`, `swagger-docs.md`, `typescript.md`, and `websocket.md`, plus newer behavior documented in `fetching-data.md`, `metadata-and-og-images.md`, and `testing.md`.
|
|
220
225
|
|
|
221
226
|
## Framework-generated files
|
|
222
227
|
|
|
@@ -313,15 +318,18 @@ When a task involves Prisma PHP CLI usage, keep the command guidance aligned wit
|
|
|
313
318
|
|
|
314
319
|
For normal full-stack Prisma PHP work, assume the user wants the PulsePoint-first approach unless they explicitly ask otherwise.
|
|
315
320
|
|
|
316
|
-
PulsePoint is the primary JavaScript authoring model for frontend work in Prisma PHP. For normal page behavior, keep the client logic inside a plain inline `<script>` within the route or imported-partial root, let Prisma PHP scope and execute it, and prefer `pp.
|
|
321
|
+
PulsePoint is the primary JavaScript authoring model for frontend work in Prisma PHP. For normal page behavior, keep the client logic inside a plain inline `<script>` within the route or imported-partial root, let Prisma PHP scope and execute it, and prefer `pp.rpc(...)` over ad hoc endpoints.
|
|
317
322
|
|
|
318
323
|
Default interaction stack:
|
|
319
324
|
|
|
320
325
|
1. render route UI with `index.php`
|
|
321
326
|
2. keep browser-side interactivity in PulsePoint
|
|
322
|
-
3. call backend PHP from the frontend with `pp.
|
|
327
|
+
3. call backend PHP from the frontend with `pp.rpc(...)`
|
|
323
328
|
4. mark callable PHP functions or methods with `#[Exposed]`
|
|
324
329
|
5. validate and normalize input on the PHP side with `PP\Validator`
|
|
330
|
+
6. use `pp.socket(...)` (named sockets) only when the flow is genuinely long-lived and bidirectional — chat, presence, live feeds
|
|
331
|
+
|
|
332
|
+
`pp.rpc(...)` is the current runtime API. The former `pp.fetchFunction(...)` does not exist any more — never generate or document it. Framework-level RPC failures (unknown function, auth, roles, CSRF, origin, rate limit, server error) arrive as HTTP error statuses with an `{"error": "..."}` body and **reject** the `pp.rpc(...)` promise, so wrap calls in `try/catch` when the UI reacts to failures. Routine, expected validation feedback should still be returned as structured data (`success`, `errors`, normalized values), not thrown.
|
|
325
333
|
|
|
326
334
|
Treat this as the default for:
|
|
327
335
|
|
|
@@ -343,7 +351,7 @@ Do **not** default to:
|
|
|
343
351
|
- a PHP-only interaction style
|
|
344
352
|
- plain browser-DOM wiring when PulsePoint state, bindings, and native `on*` handlers already fit the task
|
|
345
353
|
- ad hoc `fetch('/api/...')` patterns
|
|
346
|
-
- extra `route.php` files for page-local interactions that already fit `pp.
|
|
354
|
+
- extra `route.php` files for page-local interactions that already fit `pp.rpc(...)`
|
|
347
355
|
- a separate Node realtime or tool server when the documented Prisma PHP runtime already fits the task
|
|
348
356
|
|
|
349
357
|
Choose a more PHP-only or handler-only pattern only when:
|
|
@@ -447,19 +455,19 @@ Important metadata rules:
|
|
|
447
455
|
|
|
448
456
|
## Streaming and SSE rules
|
|
449
457
|
|
|
450
|
-
Prisma PHP supports streaming through `pp.
|
|
458
|
+
Prisma PHP supports streaming through `pp.rpc(...)` when an exposed function yields values.
|
|
451
459
|
|
|
452
460
|
Default streaming rules:
|
|
453
461
|
|
|
454
462
|
- prefer an exposed generator that simply yields strings or arrays
|
|
455
|
-
- let Prisma PHP handle the SSE response automatically for normal `pp.
|
|
463
|
+
- let Prisma PHP handle the SSE response automatically for normal `pp.rpc(...)` streaming
|
|
456
464
|
- on the client, put stream UI updates in `onStream`, `onStreamError`, and `onStreamComplete`
|
|
457
465
|
- do not wait for a final JSON payload when the response is streamed
|
|
458
466
|
|
|
459
467
|
Current parsing rules AI should know:
|
|
460
468
|
|
|
461
469
|
- Prisma PHP sends streamed payloads as SSE `data:` lines
|
|
462
|
-
- the built-in `pp.
|
|
470
|
+
- the built-in `pp.rpc(...)` stream parser currently forwards only `data:` lines to `onStream`
|
|
463
471
|
- `event:`, `id:`, and `retry:` may be emitted by low-level SSE helpers, but the built-in stream callback currently ignores them
|
|
464
472
|
- prefer JSON values or single-line strings for streamed chunks instead of multi-line text blobs
|
|
465
473
|
|
|
@@ -488,7 +496,7 @@ Important: creating a route means creating or updating the correct folder and ro
|
|
|
488
496
|
- use `error.php` for route or app-level error UI
|
|
489
497
|
- use `loading.php` when the task is specifically about a loading UI state for a route subtree
|
|
490
498
|
|
|
491
|
-
For normal route-local interactivity, prefer `index.php` plus PulsePoint and `pp.
|
|
499
|
+
For normal route-local interactivity, prefer `index.php` plus PulsePoint and `pp.rpc(...)` over inventing extra handlers.
|
|
492
500
|
|
|
493
501
|
In a consumer app, also verify `backendOnly` in `prisma-php.json`:
|
|
494
502
|
|
|
@@ -617,26 +625,34 @@ Important env rules:
|
|
|
617
625
|
|
|
618
626
|
## WebSocket rules
|
|
619
627
|
|
|
620
|
-
When the task involves realtime messaging, presence, live dashboards, `
|
|
628
|
+
When the task involves realtime messaging, presence, live dashboards, chat, `pp.socket(...)`, or `Ratchet`, read `websocket.md` first.
|
|
621
629
|
|
|
622
|
-
Prisma PHP
|
|
630
|
+
Prisma PHP realtime support is built on **named sockets**: `pp.socket(name, args, handlers)` in the browser, and a Ratchet-based server under `src/Lib/Websocket` that dispatches each connection to a handler registered with `SocketRegistry`. Do not replace that default with Socket.IO, a separate Node server, raw `new WebSocket(...)` wiring, or an unrelated hosted realtime service unless the user explicitly asks for a different architecture.
|
|
623
631
|
|
|
624
632
|
Use this websocket workflow:
|
|
625
633
|
|
|
626
634
|
1. read `websocket.md`
|
|
627
635
|
2. inspect whether websocket support is enabled in `prisma-php.json` in the target app
|
|
628
|
-
3. inspect `src/Lib/Websocket`
|
|
629
|
-
4. inspect the route
|
|
636
|
+
3. inspect `src/Lib/Websocket`, especially `sockets.php` for the registered socket names
|
|
637
|
+
4. inspect the route script that calls `pp.socket(...)`
|
|
630
638
|
5. inspect `settings/restart-websocket.ts` when local restart behavior matters
|
|
631
639
|
6. inspect framework internals only when the docs do not answer the task
|
|
632
640
|
|
|
633
641
|
Important websocket rules:
|
|
634
642
|
|
|
643
|
+
- connect from the browser with `pp.socket(name, args, handlers)`; do **not** generate raw `new WebSocket(...)` wiring for app realtime work
|
|
644
|
+
- register server handlers with `SocketRegistry::register(...)` in `src/Lib/Websocket/sockets.php`; socket names are unique application-wide
|
|
645
|
+
- do not put socket handlers in route files — route files are not loaded by the socket server process
|
|
646
|
+
- keep the wire contract intact: one endpoint (`/__pulsepoint/ws`), the function named in the `name` query parameter, arguments as the connection's first JSON frame, one JSON value per frame in either direction, and `{"error": "..."}` (that key alone) reserved for failures
|
|
635
647
|
- use `src/Lib/Websocket/websocket-server.php` as the source of truth for startup behavior
|
|
636
|
-
- use `src/Lib/Websocket/ConnectionManager.php` as the lifecycle boundary
|
|
637
|
-
-
|
|
648
|
+
- use `src/Lib/Websocket/ConnectionManager.php` as the wire and lifecycle boundary (handshake security, argument frame, dispatch, limits)
|
|
649
|
+
- use `SocketPool` for broadcasts; keep authenticated and guest traffic in separate pools
|
|
650
|
+
- declare auth with `requireAuth` / `allowedRoles` at registration; the handshake is verified against the JWT auth cookie before the handler runs
|
|
651
|
+
- a `Socket::send(...)` that returns `false` means the browser is gone — stop sending, it is not an error
|
|
652
|
+
- preserve documented env vars and defaults: `WS_NAME`, `WS_VERSION`, `WS_HOST`, `WS_PORT`, `WS_VERBOSE`, `APP_TIMEZONE`, `MAX_WEBSOCKET_CONNECTIONS`, `MAX_WEBSOCKET_MESSAGE_BYTES`, `MAX_WEBSOCKET_MESSAGES_PER_WINDOW`, `WEBSOCKET_RATE_WINDOW_SECONDS`, `WEBSOCKET_IDLE_TIMEOUT_SECONDS`, `WEBSOCKET_ALLOWED_ORIGINS`
|
|
638
653
|
- preserve CLI overrides through `--host=...`, `--port=...`, and `--verbose=...`
|
|
639
654
|
- preserve the documented casing `src/Lib/Websocket`
|
|
655
|
+
- in development, `settings/bs-config.ts` proxies `/__pulsepoint/ws` from the BrowserSync origin to the Ratchet server, so `pp.socket(...)` needs no `url` option; pass `url` only outside that proxy
|
|
640
656
|
- for existing apps, enable `websocket` in `prisma-php.json` and run `npx pp update project -y` before inventing manual scaffolding
|
|
641
657
|
|
|
642
658
|
## MCP rules
|
|
@@ -688,7 +704,7 @@ Important ORM rules:
|
|
|
688
704
|
|
|
689
705
|
## Validation rules
|
|
690
706
|
|
|
691
|
-
When a task involves user input, form handling, search params, JSON payloads, `pp.
|
|
707
|
+
When a task involves user input, form handling, search params, JSON payloads, `pp.rpc(...)`, `route.php` bodies, or tool parameters, do not trust raw values.
|
|
692
708
|
|
|
693
709
|
Default Prisma PHP validation rules:
|
|
694
710
|
|
|
@@ -717,7 +733,7 @@ Also follow these rules:
|
|
|
717
733
|
|
|
718
734
|
- treat PulsePoint as the primary JavaScript authoring model for normal full-stack frontend work
|
|
719
735
|
- keep page and imported-partial client logic inside the boundary's plain `<script>` tag instead of building extra DOM-ready or self-executing wrappers
|
|
720
|
-
- prefer `pp.
|
|
736
|
+
- prefer `pp.rpc(...)` over ad hoc `fetch('/api/...')` calls for page-local PHP interactions
|
|
721
737
|
- reserve plain browser JavaScript outside PulsePoint for external libraries, low-level browser APIs, and reusable helpers in `ts/`
|
|
722
738
|
- do not invent undocumented PulsePoint helpers or directives
|
|
723
739
|
- do not write React, Vue, Alpine, or Livewire syntax and call it PulsePoint
|