Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion .github/scripts/schema_guard.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,32 @@
"""

import sys
import json
import re
import pathlib
import yaml

# Every lerd since the package layer fetches each entry of the index's
# `packages` on `lerd update` and refuses a name composer could not publish, so
# an entry that is not a composer name fails a refresh on every install. Other
# package kinds take an index key of their own, which those versions never read.
COMPOSER_NAME = re.compile(r"^[a-z0-9][a-z0-9._-]*/[a-z0-9][a-z0-9._-]*$")


def index_failures(candidate_dir):
path = pathlib.Path(candidate_dir) / "frameworks" / "index.json"
try:
index = json.loads(path.read_text(encoding="utf-8"))
except (OSError, ValueError):
return []
return [
f"frameworks/index.json: `{entry.get('name')}` under `packages` is not a composer name; "
"every lerd since the package layer fetches each entry there on update and refuses it. "
"List other package kinds under their own key, such as `npm_packages`"
for entry in index.get("packages", [])
if not COMPOSER_NAME.match(str(entry.get("name", "")))
]

# A key whose published values number no more than this across the whole store
# is treated as a closed set, so a value outside it is worth a second look.
CLOSED_SET_MAX = 8
Expand Down Expand Up @@ -97,7 +120,7 @@ def main():
candidate = profile(candidate_dir, pattern)
enums = closed_sets(published)

failures, warnings = [], []
failures, warnings = index_failures(candidate_dir), []

for rel, entry in published.items():
if rel not in candidate:
Expand Down
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,11 @@ list meaning every framework. The package wins a name collision with the version
file, which is what lets an entry move here without being shadowed by the copy
it left behind. List the package under `packages` in `frameworks/index.json` as
`{"name": "vendor/package"}`, which is where lerd reads the set from; a file
nothing lists is never fetched.
nothing lists is never fetched. Only composer names belong there: every lerd
since the package layer fetches each entry of `packages` on `lerd update` and
refuses a name composer could not publish, so anything else, an npm package
say, gets an index key of its own that those versions never read. The schema
guard refuses a non-composer name under `packages`.

A capture seam names a method the Debug window should report, for a library
whose own call is the event rather than the start of one. It belongs to the
Expand Down Expand Up @@ -263,6 +267,33 @@ removes:
doctor: [horizon_supervisor]
```

#### Browser events

A frontend library reports what goes wrong through DOM events of its own, which
lerd's browser capture records once it knows their names. The package that ships
the library declares them in a `browser:` block, and lerd offers them as a preset
for any project that requires the package:

```yaml
package: "@inertiajs/vue3"
type: npm # optional: composer (the default) or npm
browser:
preset: inertia # packages sharing a preset are offered as one
label: Inertia.js
events:
- event: inertia:invalid
label: Inertia invalid response
message: detail.response # where in the event the message is
```

An npm package lives in `packages/npm-<scope>-<name>.yaml`, its scope's `@`
dropped (`npm-inertiajs-vue3.yaml`, `npm-vite.yaml`), and is listed in the index
under `npm_packages` rather than `packages`: a lerd that predates npm packages
fetches every entry of `packages` on `lerd update` and would count an npm name
as a failure, while it never reads a key it does not know. It also reads a
composer package's file without the keys it does not know, so a `browser:`
block reaches only the versions that use it.

The copies a package was lifted out of stay in the version files that already
shipped them: an install whose binary predates the package layer still reads
those, and deleting them would take the worker away from it. The package file is
Expand Down
11 changes: 11 additions & 0 deletions frameworks/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,21 @@
{"name": "symfony/panther"},
{"name": "symfony/redis-messenger"},
{"name": "symfony/scheduler"},
{"name": "symfony/ux-turbo"},
{"name": "tempest/command-bus"},
{"name": "tempest/database"},
{"name": "typesense/typesense-php"},
{"name": "typo3/cms-scheduler"},
{"name": "vladimir-yuldashev/laravel-queue-rabbitmq"}
],
"npm_packages": [
{"name": "@hotwired/turbo"},
{"name": "@hotwired/turbo-rails"},
{"name": "@inertiajs/inertia"},
{"name": "@inertiajs/react"},
{"name": "@inertiajs/svelte"},
{"name": "@inertiajs/vue3"},
{"name": "htmx.org"},
{"name": "vite"}
]
}
11 changes: 11 additions & 0 deletions packages/inertiajs-inertia-laravel.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,14 @@ workers:
# exists once someone has run it.
check:
file: bootstrap/ssr/ssr.js

browser:
preset: inertia
label: Inertia.js
events:
- event: inertia:invalid
label: Inertia invalid response
message: detail.response
- event: inertia:exception
label: Inertia exception
message: detail.exception.message
13 changes: 13 additions & 0 deletions packages/npm-hotwired-turbo-rails.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package: "@hotwired/turbo-rails"
type: npm

browser:
preset: turbo
label: Hotwire Turbo
events:
- event: turbo:fetch-request-error
label: Turbo request failed
message: detail.error.message
- event: turbo:frame-missing
label: Turbo frame missing
message: detail.response.status
13 changes: 13 additions & 0 deletions packages/npm-hotwired-turbo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package: "@hotwired/turbo"
type: npm

browser:
preset: turbo
label: Hotwire Turbo
events:
- event: turbo:fetch-request-error
label: Turbo request failed
message: detail.error.message
- event: turbo:frame-missing
label: Turbo frame missing
message: detail.response.status
14 changes: 14 additions & 0 deletions packages/npm-htmx.org.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package: "htmx.org"
type: npm

browser:
preset: htmx
label: htmx
events:
- event: htmx:responseError
label: htmx error response
message: detail.xhr.status
- event: htmx:sendError
label: htmx request not sent
- event: htmx:swapError
label: htmx swap failed
13 changes: 13 additions & 0 deletions packages/npm-inertiajs-inertia.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package: "@inertiajs/inertia"
type: npm

browser:
preset: inertia
label: Inertia.js
events:
- event: inertia:invalid
label: Inertia invalid response
message: detail.response
- event: inertia:exception
label: Inertia exception
message: detail.exception.message
13 changes: 13 additions & 0 deletions packages/npm-inertiajs-react.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package: "@inertiajs/react"
type: npm

browser:
preset: inertia
label: Inertia.js
events:
- event: inertia:invalid
label: Inertia invalid response
message: detail.response
- event: inertia:exception
label: Inertia exception
message: detail.exception.message
13 changes: 13 additions & 0 deletions packages/npm-inertiajs-svelte.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package: "@inertiajs/svelte"
type: npm

browser:
preset: inertia
label: Inertia.js
events:
- event: inertia:invalid
label: Inertia invalid response
message: detail.response
- event: inertia:exception
label: Inertia exception
message: detail.exception.message
13 changes: 13 additions & 0 deletions packages/npm-inertiajs-vue3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package: "@inertiajs/vue3"
type: npm

browser:
preset: inertia
label: Inertia.js
events:
- event: inertia:invalid
label: Inertia invalid response
message: detail.response
- event: inertia:exception
label: Inertia exception
message: detail.exception.message
10 changes: 10 additions & 0 deletions packages/npm-vite.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package: "vite"
type: npm

browser:
preset: vite
label: Vite
events:
- event: vite:preloadError
label: Vite chunk failed to load
message: payload.message
12 changes: 12 additions & 0 deletions packages/symfony-ux-turbo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package: symfony/ux-turbo

browser:
preset: turbo
label: Hotwire Turbo
events:
- event: turbo:fetch-request-error
label: Turbo request failed
message: detail.error.message
- event: turbo:frame-missing
label: Turbo frame missing
message: detail.response.status
Loading