@pulse-compute/runtime 1.0.0-beta.2 → 1.0.0-beta.4

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 CHANGED
@@ -7,9 +7,9 @@
7
7
  > **Supported entry points:** `@pulse-compute/runtime`<br>
8
8
  > **Stability:** Supported application authoring and execution contract.<br>
9
9
  > **npm:** [`@pulse-compute/runtime`](https://www.npmjs.com/package/@pulse-compute/runtime)<br>
10
- > **Canonical documentation:** [Package guide](https://pulsecompute.io/v1.0.0-beta.2/packages/runtime/)
10
+ > **Canonical documentation:** [Package guide](https://pulsecompute.io/v1.0.0-beta.4/packages/runtime/)
11
11
  >
12
- > This release-status block is generated from the synchronized `Pulse 1.0.0-beta.2` package policy.
12
+ > This release-status block is generated from the synchronized `Pulse 1.0.0-beta.4` package policy.
13
13
  <!-- pulse-package-status:end -->
14
14
 
15
15
  `@pulse-compute/runtime` is the low-level, provider-neutral Pulse application contract.
package/docs/API.md CHANGED
@@ -1,11 +1,11 @@
1
1
  # Pulse runtime contract
2
2
 
3
3
  For source eligibility, use [Managed handler TypeScript and
4
- JavaScript](https://pulsecompute.io/v1.0.0-beta.2/reference/handler-authoring/). For provider and target
4
+ JavaScript](https://pulsecompute.io/v1.0.0-beta.4/reference/handler-authoring/). For provider and target
5
5
  differences, use the [compatibility
6
- matrix](https://pulsecompute.io/v1.0.0-beta.2/reference/compatibility-matrix/). For CLI and runtime failures,
6
+ matrix](https://pulsecompute.io/v1.0.0-beta.4/reference/compatibility-matrix/). For CLI and runtime failures,
7
7
  use the stable codes in the [diagnostics
8
- reference](https://pulsecompute.io/v1.0.0-beta.2/reference/diagnostics/).
8
+ reference](https://pulsecompute.io/v1.0.0-beta.4/reference/diagnostics/).
9
9
 
10
10
  This document describes the provider-neutral TypeScript application contract compiled by Pulse. Low-level authoring types and the static `Router` come from `@pulse-compute/runtime`. The public `@pulse-compute/pulse` package owns the conventional `Pulse` application root, deferred project configuration, and schema declarations, while `@pulse-compute/cli` owns workspace orchestration.
11
11
 
@@ -27,6 +27,7 @@ process, provider SDK, or global network surface behind it.
27
27
  | [`ctx.state`](#ctxstate) | HTTP and event handlers | Invocation-local string state shared across one execution. |
28
28
  | [`ctx.fetch`](#ctxfetch) | HTTP and event handlers | Explicit outbound HTTP effect and structured or opaque response ownership. |
29
29
  | [`ctx.parallel`](#ctxparallel) | HTTP and event handlers | Statically keyed concurrent Pulse effects. |
30
+ | [`ctx.encodeJson`](#ctxencodejson) | HTTP and event handlers | Synchronous schema-bound, size-limited JSON text. |
30
31
  | [`ctx.emit`](#ctxemit) | HTTP and event handlers | One-way, schema-bound event acceptance effect. |
31
32
  | [`ctx.log`](#ctxlog) | HTTP and event handlers | Synchronous thresholded logging. |
32
33
  | [`ctx.config`, `ctx.secret`](#config-and-secrets) | HTTP and event handlers | Explicit configured binding reads. |
@@ -49,7 +50,7 @@ Every managed handler is async-shaped:
49
50
  type Handler = (ctx: PulseContext) => Promise<PulseResult | PulseFetchResponse>
50
51
  ```
51
52
 
52
- For native targets the compiler erases the async wrapper. Awaited Pulse effects lower into the existing explicit effect and continuation state machine; no Promise runtime or Asyncify transform is linked. Awaiting a proven synchronous `ctx` expression is redundant and may warn, while arbitrary non-Pulse awaits mark the native eligibility boundary. The canonical [handler authoring reference](https://pulsecompute.io/v1.0.0-beta.2/reference/handler-authoring/) defines the static language subset; the [compatibility matrix](https://pulsecompute.io/v1.0.0-beta.2/reference/compatibility-matrix/) owns the tested four-mode claims.
53
+ For native targets the compiler erases the async wrapper. Awaited Pulse effects lower into the existing explicit effect and continuation state machine; no Promise runtime or Asyncify transform is linked. Awaiting a proven synchronous `ctx` expression is redundant and may warn, while arbitrary non-Pulse awaits mark the native eligibility boundary. The canonical [handler authoring reference](https://pulsecompute.io/v1.0.0-beta.4/reference/handler-authoring/) defines the static language subset; the [compatibility matrix](https://pulsecompute.io/v1.0.0-beta.4/reference/compatibility-matrix/) owns the tested four-mode claims.
53
54
 
54
55
  ## Static `Router`
55
56
 
@@ -137,9 +138,9 @@ eligibility. Fastly targets fail closed because no event ingress/emit adapter is
137
138
  claimed. There is no public event injection command, no event-aware development
138
139
  listener, no HTTP/GRIP translation, and no automatic target fallback.
139
140
 
140
- The [static events guide](https://pulsecompute.io/v1.0.0-beta.2/guides/events/) owns the complete frame,
141
+ The [static events guide](https://pulsecompute.io/v1.0.0-beta.4/guides/events/) owns the complete frame,
141
142
  queue, target-eligibility, diagnostic, and Native-extension contract. The
142
- source-bound [event example](https://pulsecompute.io/v1.0.0-beta.2/examples/11-events/) runs the same mixed project
143
+ source-bound [event example](https://pulsecompute.io/v1.0.0-beta.4/examples/11-events/) runs the same mixed project
143
144
  on Node JavaScript and Node Native.
144
145
 
145
146
  ## `ctx.req`
@@ -441,6 +442,19 @@ incomplete capability mapping and does not define or block
441
442
  Pulse's contract. Conditional wire values use the strict
442
443
  `{"__pulseKv":1,"value":...}` envelope; legacy raw JSON requires explicit migration.
443
444
 
445
+ ## `ctx.encodeJson`
446
+
447
+ ```ts
448
+ const text = ctx.encodeJson(candidate, 'app.Candidate')
449
+ ```
450
+
451
+ Requires a literal registered schema even in non-strict mode. Validates and
452
+ projects the value, then returns detached JSON text bounded by `schemas.maxBytes`
453
+ in UTF-8 bytes. It does not create a response or dispatch an effect. Invalid
454
+ values and oversized text fail before subsequent writes. Declaration order and
455
+ array order are preserved; cross-target parity is semantic, not a universal
456
+ canonical-byte format. See [application-owned encoding](https://pulsecompute.io/v1.0.0-beta.4/guides/json-schemas/#encode-application-owned-text).
457
+
444
458
  ## Explicit JSON schemas
445
459
 
446
460
  <!-- pulse-doc-source: examples/02-request-schema/.pulse/config.ts -->
@@ -482,12 +496,12 @@ forms lower into canonical package operations; JavaScript targets execute the
482
496
  real package implementation.
483
497
 
484
498
  Older `/pulsewasm` imports are compatibility-only and are isolated in the
485
- [migration guide](https://pulsecompute.io/v1.0.0-beta.2/guides/compatibility-imports/). See the
486
- [GRIP package guide](https://pulsecompute.io/v1.0.0-beta.2/packages/grip/) for the complete current surface.
499
+ [migration guide](https://pulsecompute.io/v1.0.0-beta.4/guides/compatibility-imports/). See the
500
+ [GRIP package guide](https://pulsecompute.io/v1.0.0-beta.4/packages/grip/) for the complete current surface.
487
501
 
488
502
  ## Entities API
489
503
 
490
- `@pulse-compute/entities` is part of the synchronized `1.0.0-beta.2` package
504
+ `@pulse-compute/entities` is part of the synchronized `1.0.0-beta.4` package
491
505
  set. The application surface has two runtime values:
492
506
 
493
507
  ```ts
@@ -549,9 +563,9 @@ Registrations and the terminal binding must use the supported static form. The
549
563
  first-party JSON-RPC adapter accepts bounded JSON-RPC 2.0 request objects and
550
564
  named params, validates declared schemas, uses stable error framing, and
551
565
  acknowledges notifications with HTTP `204`. See the [package
552
- guide](https://pulsecompute.io/v1.0.0-beta.2/packages/entities/), [entity/adapter
553
- model](https://pulsecompute.io/v1.0.0-beta.2/concepts/entities-and-adapters/), and [executable
554
- example](https://pulsecompute.io/v1.0.0-beta.2/examples/10-entities-tools/).
566
+ guide](https://pulsecompute.io/v1.0.0-beta.4/packages/entities/), [entity/adapter
567
+ model](https://pulsecompute.io/v1.0.0-beta.4/concepts/entities-and-adapters/), and [executable
568
+ example](https://pulsecompute.io/v1.0.0-beta.4/examples/10-entities-tools/).
555
569
 
556
570
  ## Project workflow
557
571
 
@@ -568,5 +582,5 @@ selected profile, handler entry, schema declarations, provider bindings, and
568
582
  output directory through `.pulse/config.ts`. `pulse inspect` is optional
569
583
  observability, and `pulse compile` is the advanced provider-neutral Native
570
584
  artifact command; neither is required before `pulse build`. See the [project
571
- lifecycle guide](https://pulsecompute.io/v1.0.0-beta.2/guides/project-lifecycle/) and [CLI
572
- reference](https://pulsecompute.io/v1.0.0-beta.2/reference/cli/).
585
+ lifecycle guide](https://pulsecompute.io/v1.0.0-beta.4/guides/project-lifecycle/) and [CLI
586
+ reference](https://pulsecompute.io/v1.0.0-beta.4/reference/cli/).
@@ -1,6 +1,6 @@
1
1
  # Static Router authoring
2
2
 
3
- Use `Router` when an application has several method/path entry points or needs compile-time middleware. It is a static authoring marker from `@pulse-compute/runtime`, not a JavaScript runtime dispatcher. The shared async/static restrictions are defined in [Managed handler TypeScript and JavaScript](https://pulsecompute.io/v1.0.0-beta.2/reference/handler-authoring/); target claims live in the [compatibility matrix](https://pulsecompute.io/v1.0.0-beta.2/reference/compatibility-matrix/).
3
+ Use `Router` when an application has several method/path entry points or needs compile-time middleware. It is a static authoring marker from `@pulse-compute/runtime`, not a JavaScript runtime dispatcher. The shared async/static restrictions are defined in [Managed handler TypeScript and JavaScript](https://pulsecompute.io/v1.0.0-beta.4/reference/handler-authoring/); target claims live in the [compatibility matrix](https://pulsecompute.io/v1.0.0-beta.4/reference/compatibility-matrix/).
4
4
 
5
5
  <!-- pulse-doc-source: examples/09-router-lowering/src/index.ts -->
6
6
  ```ts
@@ -1,6 +1,6 @@
1
1
  # Beta scope
2
2
 
3
- Pulse `1.0.0-beta.2` is a Beta of one provider-neutral application contract
3
+ Pulse `1.0.0-beta.4` is a Beta of one provider-neutral application contract
4
4
  with explicit Native and JavaScript execution targets. The intended 1.0
5
5
  surface is present, but deliberate corrections may still occur before the
6
6
  stable `1.0.0` release.
@@ -106,13 +106,13 @@ JavaScript-selected project into a Native one.
106
106
  ## Compatibility authority
107
107
 
108
108
  The single source-form, provider-binding, artifact, and deployment-boundary
109
- table is [Provider and target compatibility](https://pulsecompute.io/v1.0.0-beta.2/reference/compatibility-matrix/).
109
+ table is [Provider and target compatibility](https://pulsecompute.io/v1.0.0-beta.4/reference/compatibility-matrix/).
110
110
  It uses one public target order—Node JavaScript, Fastly JavaScript, Node Native,
111
111
  and Fastly Native—and links every row to a focused proof or canonical contract.
112
112
 
113
113
  The exact portable language subset and the JavaScript-only Native eligibility
114
114
  boundaries are defined in
115
- [Managed handler TypeScript and JavaScript](https://pulsecompute.io/v1.0.0-beta.2/reference/handler-authoring/).
115
+ [Managed handler TypeScript and JavaScript](https://pulsecompute.io/v1.0.0-beta.4/reference/handler-authoring/).
116
116
 
117
117
  ## Body model
118
118
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pulse-compute/runtime",
3
- "version": "1.0.0-beta.2",
3
+ "version": "1.0.0-beta.4",
4
4
  "license": "Apache-2.0",
5
5
  "engines": {
6
6
  "node": "^22.14.0 || ^24.0.0"
@@ -41,7 +41,7 @@
41
41
  "url": "git+https://github.com/pulse-compute/pulse.git",
42
42
  "directory": "packages/runtime"
43
43
  },
44
- "homepage": "https://pulsecompute.io/v1.0.0-beta.2/packages/runtime/",
44
+ "homepage": "https://pulsecompute.io/v1.0.0-beta.4/packages/runtime/",
45
45
  "bugs": {
46
46
  "url": "https://github.com/pulse-compute/pulse/issues"
47
47
  }
package/src/index.d.ts CHANGED
@@ -135,6 +135,8 @@ export type PulseEmitEvent<Payload = unknown> =
135
135
 
136
136
  /** Plane-neutral authority shared by one isolated HTTP request or event invocation. */
137
137
  export interface PulseExecutionContext {
138
+ /** Validate/project a value through a literal registered schema and return bounded JSON text. */
139
+ encodeJson(value: unknown, schemaId: string): string;
138
140
  readonly state: PulseState;
139
141
  readonly log: PulseLogger;
140
142
  fetch(url: string, init?: PulseFetchInit): PulseFetchOperation;
@@ -2,7 +2,7 @@
2
2
 
3
3
  const { createStructuredBodyReader, normalizeBodyLimit } = require('./body.js');
4
4
  const { normalizeFetchRequest } = require('./fetch.js');
5
- const { decodeSchemaText, strictSchemaPolicy } = require('./schema.js');
5
+ const { decodeSchemaText, encodeSchemaValue, requireExplicitSchemaId, strictSchemaPolicy } = require('./schema.js');
6
6
  const {
7
7
  cloneKvValue,
8
8
  normalizeBindingName,
@@ -157,6 +157,10 @@ function createContext(frame) {
157
157
 
158
158
  const eventContext = frame.event !== undefined;
159
159
  const ctx = {
160
+ encodeJson(value, schemaId) {
161
+ const id = requireExplicitSchemaId(schemaId, options, 'application-value');
162
+ return encodeSchemaValue(id, value, options, { source: 'application-value' }).text;
163
+ },
160
164
  ...(eventContext ? {} : { req }),
161
165
  state,
162
166
  log,
@@ -247,9 +247,10 @@ function encodeSchemaValue(schemaId, value, options = {}, context = {}) {
247
247
  const codecs = requireSchemaCodecs(options, id, source);
248
248
  try {
249
249
  const text = codecs.encodeJsonText(id, value, source);
250
+ if (source === 'application-value') assertSchemaBodySize(options, text, id, source);
250
251
  const normalized = codecs.decodeJsonText(id, text, `${source}-trace`);
251
252
  emitSchemaTrace(options, {
252
- kind: source === 'fetch-request' ? 'json.encode.fetch' : 'json.encode.response',
253
+ kind: source === 'application-value' ? 'json.encode.value' : source === 'fetch-request' ? 'json.encode.fetch' : 'json.encode.response',
253
254
  boundary: source,
254
255
  schemaId: id,
255
256
  responseCaseId: context.responseCaseId || null,