@plurnk/plurnk-schemes-http 1.19.3 → 1.21.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/SPEC.md CHANGED
@@ -339,7 +339,8 @@ Direct HTTP operations and WebSocket connections are refused with 403
339
339
  admitted hosts is cancelled with the same refusal. Automatic acquisition checks
340
340
  the target and every redirect hop, and a final URL outside the policy is the
341
341
  ordinary unavailable `null`. The policy is operator configuration, alias-free and
342
- not model teaching; an isolated benchmark sets `[]`.
342
+ not model teaching; an isolated benchmark sets `[]` as its network boundary and denies the
343
+ `web` trait ({§capability-admission}) as the model's.
343
344
 
344
345
  ### §automatic-fetch-check Automatic acquisition URL check
345
346
 
package/docs/https.md CHANGED
@@ -1,13 +1,12 @@
1
1
  # https://
2
2
 
3
- Plain `http://` is also accepted for the endpoint that requires it — a local
4
- service, an interior tool. Prefer `https://` everywhere else.
3
+ Plain `http://` is accepted as well, for an endpoint that requires it.
5
4
 
6
5
  ## Summary
7
6
 
8
7
  Read and modify web resources through addressable HTTP(S) entries.
9
8
 
10
- Use a web URL as an addressable entry. Every exact READ acquires or refreshes a
9
+ A web URL is an addressable entry. Every exact READ acquires or refreshes a
11
10
  complete representation when needed, then core selects the channel and applies
12
11
  the requested text/byte scope. An HTML page's `body` is the server source; its
13
12
  readable Markdown (a materializer's or the local reader's) is `#readable`, and
@@ -18,17 +17,17 @@ every READ names the page's other channels with their tokens.
18
17
  | `READ (https://…) <scope?>` | GET if needed | Acquire/reuse the complete response, then return the selected scoped text |
19
18
  | `FIND (https://…) [{"pattern": …}]` | GET if needed | Return matching text regions for a scoped READ |
20
19
  | `SEND (https://…)` with body | POST | Submit the body and stream the response |
21
- | `EDIT (https://…)` with body | PUT | Replace the whole remote resource; do not use a line scope |
20
+ | `EDIT (https://…)` with body | PUT | Replace the whole remote resource; a line scope does not apply |
22
21
  | `KILL (https://…)` | none | Cancel a live acquisition of the address, or forget its stored response |
23
22
  | `KILL (https://…) [{"remote": true}]` | DELETE | Delete the remote resource and stream the response |
24
23
 
25
24
  A path-pattern FIND searches only web entries already materialized in the
26
25
  workspace; a pattern cannot discover the remote web. For matched content, READ
27
26
  the returned `#channel` using the `region` as
28
- `<startLine,startColumn,endLine,endColumn>`. Structural matches may include the
29
- enclosing property; a locator without a region does not supply text coordinates.
27
+ `<startLine,startColumn,endLine,endColumn>`. Caller cancellation of an exact
28
+ acquisition returns `499 cancelled`.
30
29
 
31
- Caller cancellation of an exact acquisition returns `499 cancelled`.
30
+ ## Channels
32
31
 
33
32
  | Response | `body` | Other channel |
34
33
  | ------------------------------------ | --------------------------------------------------- | ---------------------------------------------- |
@@ -40,100 +39,56 @@ Caller cancellation of an exact acquisition returns `499 cancelled`.
40
39
  | Binary with a readable projection | Original bytes, shown as hex | Facts/text in `#readable`; evidence in `#header` |
41
40
  | Binary without a readable projection | Original bytes, shown as hex | Evidence in `#header`; no invented facts |
42
41
 
43
- Generic public HTML uses the selected materializer as its `#readable` producer. A recoverable
44
- timeout, transport error, `429`, `5xx`, or per-URL extraction failure uses the
45
- local HTML reader and records terminal `#readable` status `203`. Authentication,
46
- provider rejection, and malformed provider responses are hard failures and do
47
- not silently switch producers. Any authored request metadata makes HTML use the
48
- local reader directly. Origin Markdown always wins without the materializer.
49
-
50
- Projection presence is structural: a returned projection is accepted even
51
- when its content is empty. `422 no-readable-projection` on `#readable` means the
52
- local route produced no readable text. An internal projection exception returns
53
- non-retryable `500 projection-failed`.
54
-
55
- A binary response retains its original bytes in `body`; READ shows their hex
56
- and, on a supporting model, attaches the complete native media. `#readable`
57
- holds facts/text when a reader exists and attaches the same native source.
58
- `#bytes` explicitly selects the hex view; scope never clips native media.
59
- Unknown formats remain byte-readable. Input above the configured byte ceiling
60
- returns `413 projection-input-limit`. Failed mutation responses retain lifecycle
61
- evidence in `#header`; do not retry a mutation solely to retrieve its body.
62
-
63
- `#header` contains origin and package acquisition evidence. A materializer attempt
64
- adds its route, status, timing, any reported request ID and credits, and bounded
65
- failure evidence. `body`, `header`, and `readable` carry independent durable
66
- producer outcomes; the selected channel determines success. Thus `#readable` or
67
- `#header` can remain readable after a source failure, while a materializer's
68
- Markdown can succeed without fabricating unavailable server HTML. A READ of the
69
- source names `#readable` and its tokens, so the curated page is one fragment away. A SEND signal is never the
70
- remote HTTP status. A direct non-success origin response is still materialized:
71
- origin-backed channels carry its exact durable `http-response-status` Problem,
72
- while independently produced materializer content and acquisition headers retain
73
- their own outcomes.
74
-
75
- For SSE, the response and persisted `#header` establish acquisition. READ then
76
- returns `102` while events continue. Origin close settles the subscription at
77
- `200`; later cancellation or transfer failure settles it at `499` or `502`
78
- without rewriting the initial READ.
79
-
80
- Re-reading an exact URL can reuse only a complete GET acquired without
81
- explicit request metadata whose response had no `Vary` field. Plurnk keeps one
82
- representation per URL, so any request metadata or `Vary` response bypasses both
83
- the freshness shortcut and old validators instead of creating a variant store.
84
- Reuse also requires a cacheable status or explicit origin permission; partial
85
- `206` responses are retained but never reused as a complete GET.
86
- Workspace reuse follows shared-cache rules. Eligible content is served directly
87
- only while both the operator TTL and origin lifetime remain live: `s-maxage`
88
- overrides `max-age`, which overrides `Expires`. `no-cache` requires origin
89
- validation; `private` and `no-store` evidence remains available but supplies
90
- neither content nor validators to a later request. Only singular, syntactically valid stored
91
- validators are sent. A 304 restores a non-page representation only when its
92
- ETag or Last-Modified value identifies the nominated representation. A strong
93
- response ETag requires the same stored strong tag; a weak response ETag may
94
- match either strength. Otherwise, one unconditional GET reacquires the content;
95
- another 304 fails without serving the stored body. Responses to POST, PUT, and
96
- DELETE are not reused as later GET representations. A projected GET is reused
97
- only while the installed reader has the same projection identity. Page bodies
98
- likewise require the same origin-Markdown, local, materializer-id, or
99
- local-fallback route. Once stale, a page composite is fully reacquired without
100
- old validators; an origin 304 cannot certify provider or auxiliary material.
101
-
102
- Scope never suppresses acquisition or refresh. The HTTP producer cannot see the
103
- fragment or text coordinates; after preparation, the fragment (or `body` by
104
- default) selects a durable channel and core applies the range. Cold and warm
105
- forms therefore have identical selection and scope semantics.
106
- An unavailable channel returns `404 channel-not-found` with the available
107
- channels; it does not mean that the containing URL is missing.
42
+ `#header` holds origin and acquisition evidence, including a materializer's
43
+ route, status and timing. `body`, `#header` and `#readable` carry independent
44
+ outcomes: `#readable` or `#header` can remain readable after a source failure,
45
+ and a direct non-success origin response is still materialized, its
46
+ origin-backed channels carrying the exact `http-response-status` Problem. A
47
+ READ of the source names `#readable` and its tokens. `422
48
+ no-readable-projection` on `#readable` means the local route produced no
49
+ readable text; `413 projection-input-limit` is input above the configured byte
50
+ ceiling; `404 channel-not-found` lists the available channels and does not
51
+ mean the URL is missing. A binary response keeps its original bytes in `body`;
52
+ READ shows their hex and, on a supporting model, attaches the native media;
53
+ `#bytes` selects the hex view explicitly. A SEND signal is never the remote
54
+ HTTP status; a failed mutation's response evidence is in `#header`, and a
55
+ retry re-executes the mutation.
56
+
57
+ For SSE, READ returns `102` while events continue; origin close settles the
58
+ subscription at `200`, and later cancellation or transfer failure settles it
59
+ at `499` or `502` without rewriting the initial READ. Re-reading an exact URL
60
+ reuses a complete GET while the operator TTL and the origin's own lifetime
61
+ allow; request metadata, a `Vary` response, a partial `206`, or a POST, PUT or
62
+ DELETE response is never reused as a later GET. Scope never suppresses
63
+ acquisition or refresh.
64
+
65
+ ## Request headers
108
66
 
109
67
  Request headers share one `[{"Key": "value", ...}]` metadata block after the
110
- target and any scope:
68
+ target and any scope; option objects in the array merge left to right, and
69
+ metadata stays on one line.
111
70
 
112
- ````READ (https://api.example.com/v1/me) [{"Authorization": "Bearer TOKEN", "Accept": "application/json"}]
113
- ````
71
+ ```READ (https://api.example.com/v1/me) [{"Accept": "application/json"}]
72
+ ```
114
73
 
115
- ````EDIT (https://api.example.com/v1/thing/42) [{"Authorization": "Bearer TOKEN", "Content-Type": "application/json"}]
74
+ ```EDIT (https://api.example.com/v1/thing/42) [{"Content-Type": "application/json"}]
116
75
  {"done":true}
117
- ````
76
+ ```
118
77
 
119
- ````SEND (https://api.example.com/v1/search) [{"Content-Type": "application/json"}]
78
+ ```SEND (https://api.example.com/v1/search) [{"Content-Type": "application/json"}]
120
79
  {"query":"plurnk"}
121
- ````
80
+ ```
122
81
 
123
- Metadata stays on one line; option objects in the array merge left to right.
124
- An exact FIND forwards these headers when it must acquire the URL, but the
125
- result remains intentionally ineligible for later cache reuse. Request headers
126
- are never forwarded to the materializer, so HTML requests carrying any explicit
127
- metadata use the local HTML-reader projection. Executor-supplied HTML also
128
- stays local; only generic web acquisition grants materializer authority.
82
+ A request with explicit metadata is ineligible for later cache reuse, and its
83
+ HTML uses the local reader projection: request headers never reach the
84
+ materializer. GET acquisition of a GitHub `…/blob/…` URL uses its
85
+ `raw.githubusercontent.com` source; the addressed URL remains entry identity,
86
+ and POST, PUT and DELETE never use that rewrite.
129
87
 
130
- GET acquisition of a GitHub `…/blob/…` URL uses its
131
- `raw.githubusercontent.com` source. The addressed GitHub URL remains entry
132
- identity. POST, PUT, and DELETE never use that rewrite.
88
+ A `KILL` of an https:// address never reaches the remote unless it carries
89
+ `[{"remote": true}]`: while an acquisition is in flight it cancels that
90
+ acquisition, otherwise it forgets the stored response so the next READ must
91
+ acquire it again. With `[{"remote": true}]`, the other options in that block
92
+ are the DELETE request's headers.
133
93
 
134
- A `KILL` of an https:// address never reaches the remote unless it carries the `[{"remote": true}]`
135
- block: while an acquisition is in flight it cancels that acquisition, otherwise it forgets
136
- the stored response so the next READ must acquire it again. With `[{"remote": true}]`, the other
137
- options in that same block are the DELETE request's headers.
138
-
139
- For a persistent bidirectional connection, use `wss://`.
94
+ For a persistent bidirectional connection, `wss://` (`wss.md`).
package/docs/wss.md CHANGED
@@ -34,27 +34,22 @@ EDIT and directed SEND share the same outbound-frame behavior. Both can follow
34
34
  the opening READ in one turn: operations execute in authored order. Only the
35
35
  turn's disposition operation is deferred until the other operations have run.
36
36
 
37
- ````READ (wss://api.example.com/feed)
38
- ````
37
+ ```READ (wss://api.example.com/feed)
38
+ ```
39
39
 
40
- ````EDIT (wss://api.example.com/feed)
40
+ ```EDIT (wss://api.example.com/feed)
41
41
  {"type":"subscribe","channel":"updates"}
42
- ````
42
+ ```
43
43
 
44
- ````SEND (wss://api.example.com/feed)
44
+ ```SEND (wss://api.example.com/feed)
45
45
  {"type":"ping"}
46
- ````
46
+ ```
47
47
 
48
48
  Connection identity includes the workspace, exact `ws`/`wss` protocol, host,
49
49
  non-default port, path, and ordered query. A fragment does not change socket
50
50
  identity; `messages` is the only current channel. An unavailable channel returns
51
51
  `404 channel-not-found`, listing available channels without replacing the socket.
52
52
 
53
- | Current transport boundary | Behavior |
54
- | -------------------------- | ----------------------------------------------------------------------- |
55
- | Inbound payload | String event data only; no coercion or binary projection |
56
- | Inbound order | Native event order; one durable write completes before the next begins |
57
- | Binary inbound payload | Keep the text prefix, prune the suffix, settle `415`, and close with private-use code `4003` |
58
- | Persistence failure | Keep the successful prefix; prune queued and later frames; settle `500` |
59
- | Reconnection | None; READ again after terminal cleanup |
60
- | Handshake metadata | `[metadata]` is unsupported |
53
+ The transport carries text frames only, in native order, one durable write at a
54
+ time; a binary inbound frame settles `415` and closes the socket; there is no
55
+ reconnection (READ again after terminal cleanup) and no handshake metadata.
package/package.json CHANGED
@@ -1,84 +1,82 @@
1
1
  {
2
- "name": "@plurnk/plurnk-schemes-http",
3
- "version": "1.19.3",
4
- "description": "HTTP(S) request/response and WebSocket scheme handlers for the plurnk agent runtime.",
5
- "keywords": [
6
- "plurnk",
7
- "scheme",
8
- "uri",
9
- "http",
10
- "https",
11
- "websocket",
12
- "ws",
13
- "wss"
14
- ],
15
- "homepage": "https://github.com/plurnk/plurnk-service/tree/main/plurnk-schemes-http#readme",
16
- "bugs": {
17
- "url": "https://repo.possumtech.com/plurnk/plurnk-service/issues"
2
+ "name": "@plurnk/plurnk-schemes-http",
3
+ "version": "1.21.0",
4
+ "description": "HTTP(S) request/response and WebSocket scheme handlers for the plurnk agent runtime.",
5
+ "keywords": [
6
+ "plurnk",
7
+ "scheme",
8
+ "uri",
9
+ "http",
10
+ "https",
11
+ "websocket",
12
+ "ws",
13
+ "wss"
14
+ ],
15
+ "homepage": "https://github.com/plurnk/plurnk-service/tree/main/plurnk-schemes-http#readme",
16
+ "bugs": {
17
+ "url": "https://repo.possumtech.com/plurnk/plurnk-service/issues"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/plurnk/plurnk-service.git",
22
+ "directory": "plurnk-schemes-http"
23
+ },
24
+ "engines": {
25
+ "node": ">=26"
26
+ },
27
+ "license": "MIT",
28
+ "author": "@wikitopian",
29
+ "type": "module",
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "plurnk": {
34
+ "kind": "scheme",
35
+ "schemes": [
36
+ {
37
+ "name": "https",
38
+ "export": "default"
39
+ },
40
+ {
41
+ "name": "wss",
42
+ "export": "Ws"
43
+ }
44
+ ]
45
+ },
46
+ "exports": {
47
+ ".": {
48
+ "types": "./dist/index.d.ts",
49
+ "default": "./dist/index.js"
18
50
  },
19
- "repository": {
20
- "type": "git",
21
- "url": "git+https://github.com/plurnk/plurnk-service.git",
22
- "directory": "plurnk-schemes-http"
51
+ "./materializer": {
52
+ "types": "./dist/Materializer.d.ts",
53
+ "default": "./dist/Materializer.js"
23
54
  },
24
- "engines": {
25
- "node": ">=26"
26
- },
27
- "license": "MIT",
28
- "author": "@wikitopian",
29
- "type": "module",
30
- "publishConfig": {
31
- "access": "public"
32
- },
33
- "plurnk": {
34
- "kind": "scheme",
35
- "schemes": [
36
- {
37
- "name": "https",
38
- "export": "default"
39
- },
40
- {
41
- "name": "wss",
42
- "export": "Ws"
43
- }
44
- ]
45
- },
46
- "exports": {
47
- ".": {
48
- "plurnk-dev": "./src/index.ts",
49
- "types": "./dist/index.d.ts",
50
- "default": "./dist/index.js"
51
- },
52
- "./materializer": {
53
- "plurnk-dev": "./src/Materializer.ts",
54
- "types": "./dist/Materializer.d.ts",
55
- "default": "./dist/Materializer.js"
56
- },
57
- "./package.json": "./package.json"
58
- },
59
- "files": [
60
- "dist/**/*",
61
- ".env.defaults",
62
- "docs/**/*",
63
- "README.md",
64
- "SPEC.md"
65
- ],
66
- "scripts": {
67
- "test:lint": "tsc --noEmit",
68
- "test:unit": "node --conditions=plurnk-dev --test --env-file=.env.defaults src/**/*.test.ts",
69
- "test": "npm run test:lint && npm run test:unit",
70
- "build:clean": "rm -rf dist",
71
- "build:dist": "tsc -p tsconfig.build.json",
72
- "build": "npm run build:clean && npm run build:dist",
73
- "prepublishOnly": "npm audit --audit-level=moderate && npm test",
74
- "prepack": "npm run build"
75
- },
76
- "peerDependencies": {
77
- "@plurnk/plurnk-schemes": "^1.19.3"
78
- },
79
- "dependencies": {
80
- "@plurnk/plurnk-contracts": "1.19.3",
81
- "@plurnk/plurnk-meta": "1.19.3",
82
- "eventsource-parser": "^4.0.0"
83
- }
55
+ "./package.json": "./package.json"
56
+ },
57
+ "files": [
58
+ "dist/**/*",
59
+ ".env.defaults",
60
+ "docs/**/*",
61
+ "README.md",
62
+ "SPEC.md"
63
+ ],
64
+ "scripts": {
65
+ "test:lint": "tsc --noEmit",
66
+ "test:unit": "node --conditions=plurnk-dev --test --env-file=.env.defaults src/**/*.test.ts",
67
+ "test": "npm run test:lint && npm run test:unit",
68
+ "build:clean": "rm -rf dist",
69
+ "build:dist": "tsc -p tsconfig.build.json",
70
+ "build": "npm run build:clean && npm run build:dist",
71
+ "prepublishOnly": "npm audit --audit-level=moderate && npm test",
72
+ "prepack": "npm run build"
73
+ },
74
+ "peerDependencies": {
75
+ "@plurnk/plurnk-schemes": "^1.21.0"
76
+ },
77
+ "dependencies": {
78
+ "@plurnk/plurnk-contracts": "1.21.0",
79
+ "@plurnk/plurnk-meta": "1.21.0",
80
+ "eventsource-parser": "^4.0.0"
81
+ }
84
82
  }