@kehto/paja 0.6.3 → 0.9.0
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 +132 -16
- package/dist/browser-host.js +15590 -11208
- package/dist/browser-host.js.map +1 -1
- package/dist/{chunk-ADMLM2LH.js → chunk-OWVINAW7.js} +531 -35
- package/dist/chunk-OWVINAW7.js.map +1 -0
- package/dist/cli.d.ts +18 -1
- package/dist/cli.js +10 -6
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +280 -5
- package/dist/index.js +11 -1
- package/dist/{server-qAXYczds.d.ts → server-efRTBcMR.d.ts} +132 -7
- package/package.json +12 -12
- package/dist/chunk-ADMLM2LH.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# @kehto/paja
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Development runtime for local napplet authoring and static pointer-loaded
|
|
4
|
+
napplet testing.
|
|
4
5
|
|
|
5
6
|
The runtime is designed to be used from a napplet package script:
|
|
6
7
|
|
|
@@ -14,29 +15,110 @@ The runtime is designed to be used from a napplet package script:
|
|
|
14
15
|
|
|
15
16
|
The target URL is explicit on purpose. Kehto can spawn any framework command and
|
|
16
17
|
wait for that URL, but it does not guess which URL the framework chose. Loading
|
|
17
|
-
that URL
|
|
18
|
-
|
|
18
|
+
that URL through Paja as injected `srcdoc` lets Kehto install mandatory
|
|
19
|
+
`window.napplet.shell` plus enabled optional domains before app code runs. The
|
|
20
|
+
Kehto host-owned shell prelude completes `shell.ready` / `shell.init` and caches
|
|
21
|
+
capability queries,
|
|
22
|
+
while a `<base>` tag keeps the
|
|
23
|
+
app's own assets and HMR pointed at the target dev server without Vite, Svelte,
|
|
24
|
+
React, or any other framework lock-in.
|
|
19
25
|
|
|
20
26
|
The package provides the typed option model, CLI parser, runtime server, host
|
|
21
|
-
page, and host config surface.
|
|
22
|
-
reload loop and a development console wired through a real
|
|
23
|
-
`ShellBridge`, `@kehto/runtime`, and
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
page, and host config surface. Local target-url mode keeps one target iframe
|
|
28
|
+
with a reload loop and a development console wired through a real
|
|
29
|
+
`ShellBridge`, `@kehto/runtime`, and service adapters for the current web NAP
|
|
30
|
+
surface: relay/outbox, storage, identity, keys, config, resource, theme, notify,
|
|
31
|
+
media, upload, intent, cvm, and inc. Relay/outbox defaults to live public relays
|
|
32
|
+
and uses NIP-65 relay-list bootstrap plus kind `3` contact-list reads for
|
|
33
|
+
identity flows; `--relay-mode memory` is the explicit deterministic fixture
|
|
34
|
+
mode. `shell` is the mandatory, non-toggleable handshake domain; the deprecated legacy package
|
|
35
|
+
path remains an upstream compatibility alias to `inc`. The upstream `dm` domain
|
|
36
|
+
is not advertised until Paja wires a deterministic development DM backend.
|
|
37
|
+
|
|
38
|
+
## Dev-server CORS requirement
|
|
39
|
+
|
|
40
|
+
The target iframe is sandboxed without `allow-same-origin`, so the napplet
|
|
41
|
+
document has an opaque origin and requests its own assets with `Origin: null`.
|
|
42
|
+
`<script type="module">` is always fetched in CORS mode, so a dev server that
|
|
43
|
+
does not allow that origin blocks the napplet's entry module and the frame
|
|
44
|
+
renders blank. Vite's default `server.cors` allowlist covers only `localhost`,
|
|
45
|
+
`127.0.0.1`, and `[::1]` origins, so it rejects `null`:
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
// vite.config.js
|
|
49
|
+
export default {
|
|
50
|
+
server: { cors: { origin: '*' } },
|
|
51
|
+
};
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Any dev server works as long as it answers `Origin: null` with
|
|
55
|
+
`Access-Control-Allow-Origin: *` or `null`. Paja probes the target on startup
|
|
56
|
+
and logs a `paja.target.cors.error` entry in the message log, plus a console
|
|
57
|
+
warning, when the target would block the sandboxed frame.
|
|
29
58
|
|
|
30
59
|
The console shows supported interfaces with per-domain injection toggles,
|
|
31
60
|
runtime ACL controls, signer controls, and a filterable message log with visible
|
|
32
|
-
error details. Paja
|
|
33
|
-
can
|
|
34
|
-
|
|
35
|
-
no bypass
|
|
61
|
+
error details. Paja auto-connects a browser NIP-07 signer when `window.nostr` is
|
|
62
|
+
available, can connect to a bunker/NIP-46 URI, and only uses the generated local
|
|
63
|
+
development signer when the Dev signer button is selected. Every signing or
|
|
64
|
+
publish operation still uses a browser confirmation prompt. There is no bypass
|
|
65
|
+
list. A denied prompt or a live publish with no accepting relay returns a
|
|
66
|
+
canonical failure and is not added to Paja's in-memory relay view. Paja's
|
|
67
|
+
scoped-relay hook likewise waits for the backend result and returns `false`
|
|
68
|
+
after denial or transport failure.
|
|
36
69
|
|
|
37
70
|
The static Paja Runtime build is served at `/web/paja/` in the GitHub Pages
|
|
38
71
|
artifact. It uses the same browser host and service adapters, but loads verified
|
|
39
|
-
napplet HTML from
|
|
72
|
+
napplet HTML from pasted `naddr` or `nevent` pointers with `hmr: none`. Each
|
|
73
|
+
loaded pointer becomes a closeable header tab; loading an already-running
|
|
74
|
+
napplet opens a choice to load another instance, switch to the existing tab, or
|
|
75
|
+
cancel. Each tab includes a share control that copies a `/web/paja/?naddr=...`
|
|
76
|
+
or `/web/paja/?nevent=...` link for that pointer, and the browser remembers open
|
|
77
|
+
runtime tabs in local storage so returning to `/web/paja/` restores the previous
|
|
78
|
+
pointer set. An explicit pointer in the URL still takes precedence over restored
|
|
79
|
+
tabs.
|
|
80
|
+
|
|
81
|
+
## Installed intent handlers and delivery
|
|
82
|
+
|
|
83
|
+
Paja keeps resolver-verified pointer and manifest facts in an installed catalog,
|
|
84
|
+
separate from the live tab/controller map. A verified install inserts or replaces
|
|
85
|
+
the catalog record; an explicit artifact removal removes it. Closing, reloading,
|
|
86
|
+
or replacing a frame never makes an installed handler unavailable, so a cold
|
|
87
|
+
target can still be selected and started later.
|
|
88
|
+
|
|
89
|
+
Intent selection considers only exact compatible contracts from that catalog.
|
|
90
|
+
Paja can use a compatible user default, ask its host chooser when more than one
|
|
91
|
+
candidate is available, or reject an ambiguity. An explicit handler d-tag is
|
|
92
|
+
accepted only when it is an installed compatible handler and the invoking sender
|
|
93
|
+
has been explicitly authorized for it. It is not a request to deliver to an
|
|
94
|
+
arbitrary running frame.
|
|
95
|
+
|
|
96
|
+
When Paja accepts an invocation, it first retains an immutable target delivery,
|
|
97
|
+
then returns the accepted result. Only after that result can it reuse a current
|
|
98
|
+
target or start a cold target. The controller waits for the target generation's
|
|
99
|
+
registered `MessageEvent.source` to establish its real `shell.ready` session;
|
|
100
|
+
it checks that generation is still current and sends one target-only
|
|
101
|
+
`intent.deliver`. The invoking source may be torn down after acceptance without
|
|
102
|
+
changing that responsibility. A superseded target/source, failed open/readiness,
|
|
103
|
+
or terminal send is handled by the controller's replacement/retry/terminal
|
|
104
|
+
policy; it never turns into an INC carrier or a delivery acknowledgement.
|
|
105
|
+
|
|
106
|
+
`@napplet/shim@0.27.0` supplies no generic shell API. Kehto deliberately keeps
|
|
107
|
+
its host-owned mandatory `window.napplet.shell` prelude: it installs the live
|
|
108
|
+
receiver before the one bare `shell.ready`, caches the first `shell.init`, and
|
|
109
|
+
provides local `ready()`, `supports()`, read-only `services`, and one-shot
|
|
110
|
+
`onReady()`. This is the documented upstream-package-drift exception, not a
|
|
111
|
+
shim capability.
|
|
112
|
+
|
|
113
|
+
Before Paja assigns a verified runtime-pointer document to `srcdoc`, it inserts
|
|
114
|
+
Kehto's local Class-1 CSP before the host-owned namespace prelude. The policy
|
|
115
|
+
denies all defaults; permits inline script/style, `data:`/`blob:` images, and
|
|
116
|
+
`data:` fonts; grants `connect-src` only to the resolved relay and Blossom
|
|
117
|
+
origins; explicitly denies worker, child, frame, media, object, manifest,
|
|
118
|
+
prefetch, base, and form capabilities; and ends with `frame-ancestors 'self'`.
|
|
119
|
+
The NIP-5D verified-srcdoc and opaque-sandbox rules do not mandate this CSP;
|
|
120
|
+
it is Kehto policy. Local target-URL authoring mode is intentionally outside
|
|
121
|
+
this verified-artifact policy path.
|
|
40
122
|
|
|
41
123
|
Environment simulation can be supplied through CLI flags or a JSON config file:
|
|
42
124
|
|
|
@@ -68,6 +150,40 @@ kehto paja \
|
|
|
68
150
|
}
|
|
69
151
|
```
|
|
70
152
|
|
|
153
|
+
## NAP-UPLOAD modes
|
|
154
|
+
|
|
155
|
+
Paja keeps `memory` as the default upload simulator. It returns deterministic
|
|
156
|
+
`kehto-dev://` results and does not store bytes. Opt into real Blossom storage
|
|
157
|
+
with a shell-owned server and an active Dev, NIP-07, or NIP-46 signer:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
kehto paja \
|
|
161
|
+
--target-url http://127.0.0.1:5173 \
|
|
162
|
+
--upload-mode blossom \
|
|
163
|
+
--upload-server https://blossom.example \
|
|
164
|
+
-- pnpm vite --host 127.0.0.1
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Paja prompts with the napplet identity, file details, selected server, and a
|
|
168
|
+
public/durable warning before it signs or sends bytes. Production servers must
|
|
169
|
+
use HTTPS; plain HTTP is accepted only for loopback development hosts. The
|
|
170
|
+
server must allow Paja's browser origin, `PUT` and `OPTIONS`, plus the
|
|
171
|
+
`Authorization` and `Content-Type` CORS headers.
|
|
172
|
+
|
|
173
|
+
Explicit servers win. With no explicit server, Paja may use an independently
|
|
174
|
+
warmed snapshot of the active signer's newest BUD-03 kind `10063` `server`
|
|
175
|
+
tags. `upload.info` and `upload.upload` never initiate that discovery. Pointer
|
|
176
|
+
loader Blossom hints are artifact sources, not upload policy. The current path
|
|
177
|
+
uses the first server only, returns its direct HTTP(S) URL, and does not mirror
|
|
178
|
+
or construct BUD-10 URLs.
|
|
179
|
+
|
|
180
|
+
Completion requires the server descriptor to confirm the exact local SHA-256
|
|
181
|
+
and byte size as a non-negative safe integer. Missing or mismatched proof is a
|
|
182
|
+
failed result even after an HTTP success. The configured identity, provider,
|
|
183
|
+
signer, discovery author, and signed authorization pubkeys must agree; a fixed
|
|
184
|
+
pubkey without `signEvent` is read-only. This implements the draft
|
|
185
|
+
[NAP-UPLOAD at `a7cc174`](https://github.com/napplet/naps/blob/a7cc17463cbf5d9cb87884b31071bc4fc826034c/naps/NAP-UPLOAD.md).
|
|
186
|
+
|
|
71
187
|
Full package docs: [`docs/packages/paja.md`](../../docs/packages/paja.md).
|
|
72
188
|
Getting started: [`docs/how-tos/paja-getting-started.md`](../../docs/how-tos/paja-getting-started.md).
|
|
73
189
|
Local authoring how-to: [`docs/how-tos/paja-local-authoring.md`](../../docs/how-tos/paja-local-authoring.md).
|