Skip to content
Documentation
1.0.0-beta.9 · exact release

Pulse-aware package authoring

Source fda16de1b352 · Published v1.0.0-beta.9

A Pulse-aware package begins as an ordinary JavaScript package with a real package-root API. Native lowering is an additional bounded realization, not a second application-facing facade and not a requirement for JavaScript use.

ordinary package API
+ real JavaScript implementation
+ bounded Native-lowerable subset
+ package contract
+ trusted compiler builder
+ provider requirements
+ cross-target conformance
GoalCurrent boundary
Provide ordinary library behavior on JavaScript targetsPublish a normal target-compatible JavaScript package API.
Add package-root Native loweringImplement the versioned trusted package-lowerer contract, including for independently released external packages.
Add a project-owned execution providerExport the versioned provider ./toolchain contract from an exact scoped package.
Load an arbitrary npm compiler plugin or lowererNot supported.
Self-register a provider by scanning dependencies or package metadataNot supported.

Provider toolchains and package lowerers are separate extension systems. A provider realizes canonical capabilities and target artifacts. A package lowerer recognizes a bounded package-root call and emits canonical package effects. Neither mechanism grants provider SDK access to handlers.

The package root owns the application API:

import { feature } from '@example/pulse-feature'

For JavaScript targets, ship a real implementation with ordinary types, runtime code, tests, and target-compatible dependencies. Pulse's Node and Fastly JavaScript packagers include reachable dependencies, but each runtime still has its own platform constraints. A Node-specific package is not automatically Fastly-compatible.

Keep authority explicit:

  • accept ctx only when the operation needs a request-owned Pulse effect;
  • keep pure framing and result adapters independent of ambient state;
  • do not read provider SDK objects, process.env, global network authority, or mutable request globals from canonical APIs;
  • document which JavaScript targets the implementation actually supports.

Independent packages may stop here. They do not need a compiler builder merely to work on an explicitly selected compatible JavaScript target.

If your package needs Native support, define a smaller static subset of the same package-root API:

  • exact package-root import and symbol identities;
  • supported call placement;
  • literal or statically bounded arguments;
  • canonical operation, payload, result, and capability vocabulary;
  • source-located diagnostics for unsupported shapes;
  • provider requirements and result ownership;
  • optional sidecar ABI symbols.

The JavaScript implementation may remain broader. Unsupported Native shapes make that project ineligible for Native selection; they do not trigger target fallback.

3. Keep contract and execution owners distinct

Section titled “3. Keep contract and execution owners distinct”
ConcernOwner
Public package-root API and JavaScript implementationFeature package
Operation, payload, result, and diagnostic vocabularyShared package contract
Native call-shape recognitionPackage-owned compiler builder
Manifest discovery and trusted builder loadingGeneric library kit
Whole-project effect and continuation compositionCanonical compiler
Capability and binding realizationSelected provider
Product support, packing, docs, and acceptanceSynchronized release

Compiler core may combine package effects but must not absorb package-specific symbol names, payload rules, or provider lowering names.

Package-root Native lowering runs as trusted build code. Declare:

  • compiler.trust: 'build-dependency' and matching product lowering.trust;
  • builder ownership equal to the npm package owner;
  • the exact supported manifest and builder protocol versions;
  • static product metadata and package-contained manifest, builder, and sidecar;
  • packed-package discovery and target conformance evidence.

The legacy compiler.trust: 'first-party' value remains accepted with the same authority. Third-party packages need no monorepo awareness, allowlist, extra pin, or equality with Pulse's release version. Graph compilation discovers the package resolved by imports, including nested dependencies. Installed package and contract identities remain part of compilation evidence.

Manifests and builders execute in the compiler's Node process with its filesystem and environment access. This is trusted execution without sandboxing or isolated failure containment. It is not a public third-party plugin API for arbitrary compiler hooks; the documented package-lowerer contract is supported.

The provider-toolchain boundary is different. A project may name an exact scoped provider package whose versioned ./toolchain export Pulse loads directly. That package also executes as trusted project build code. It does not self-register, create a public lowerer, or enter handler source.

For each claimed mode, test the layer that actually executes:

  • package-root JavaScript behavior on Node and/or Fastly;
  • positive and negative Native static shapes;
  • direct await and ctx.parallel for request-bound package effects;
  • package contract and manifest validation;
  • provider capability and binding behavior;
  • structured or opaque result ownership;
  • cross-target semantic conformance;
  • deterministic source and target packaging;
  • isolated packed dependency discovery;
  • explicit unsupported-form diagnostics.

Do not infer a support claim from a resolvable export or an SDK feature.

Assets demonstrates a package-root JavaScript implementation, Native lookup lowering, and opaque response adoption. GRIP demonstrates pure package-root framing, request-bound broadcast, provider requirements, and bounded Native lowering. Compatibility-only /pulsewasm imports remain isolated in the migration guide.

Continue with: