@pulse-compute/provider-fastly 1.0.0-beta.1 → 1.0.0-beta.11

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.
Files changed (83) hide show
  1. package/README.md +7 -6
  2. package/dist/config-schema.json +30 -0
  3. package/dist/index.d.ts +16 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +8 -0
  6. package/dist/index.js.map +1 -1
  7. package/package.json +11 -10
  8. package/src/build/canonical-target.js +41 -2
  9. package/src/build/digest-native.js +25 -0
  10. package/src/build/effect-invocations.js +51 -0
  11. package/src/build/embedded-assets.as.ts +32 -0
  12. package/src/build/entities-native.js +6 -11
  13. package/src/build/host-extensions.js +254 -0
  14. package/src/build/kv-native.as.ts +331 -0
  15. package/src/build/kv-native.js +27 -0
  16. package/src/build/lifecycle.js +50 -0
  17. package/src/build/native-application-errors.js +159 -0
  18. package/src/build/native-binary-resources.js +30 -0
  19. package/src/build/native-body-forwarding.as.ts +325 -0
  20. package/src/build/native-body-forwarding.js +73 -0
  21. package/src/build/native-dynamic-backends.as.ts +115 -0
  22. package/src/build/native-dynamic-backends.js +52 -0
  23. package/src/build/native-fetch-accounting.as.ts +133 -0
  24. package/src/build/native-fetch-accounting.js +84 -0
  25. package/src/build/native-fetch-bounds.js +47 -0
  26. package/src/build/native-fetch-cohorts.as.ts +126 -0
  27. package/src/build/native-fetch-cohorts.js +65 -0
  28. package/src/build/native-fetch-deadlines.as.ts +169 -0
  29. package/src/build/native-fetch-deadlines.js +36 -0
  30. package/src/build/native-fetch-errors.js +38 -0
  31. package/src/build/native-fetch-headers.js +52 -0
  32. package/src/build/native-fetch-outcomes.js +87 -0
  33. package/src/build/native-fetch-timing.as.ts +74 -0
  34. package/src/build/native-fetch-timing.js +50 -0
  35. package/src/build/native-forwarding-accounting.as.ts +153 -0
  36. package/src/build/native-forwarding-accounting.js +47 -0
  37. package/src/build/native-handle-ownership.js +127 -0
  38. package/src/build/native-header-lookup.js +50 -0
  39. package/src/build/native-http-effects.js +164 -35
  40. package/src/build/native-platform-capabilities.js +815 -220
  41. package/src/build/native-request-body.js +45 -0
  42. package/src/build/native-request-headers.js +93 -0
  43. package/src/build/native-send-error-detail.as.ts +12 -0
  44. package/src/build/native-stdio.js +45 -0
  45. package/src/build/native-string-values.js +143 -0
  46. package/src/build/native-transport-details.as.ts +84 -0
  47. package/src/build/native-value-budget.js +90 -0
  48. package/src/build/package-native-application.js +114 -0
  49. package/src/build/request-budget-source.js +58 -0
  50. package/src/build/request-budget.js +46 -0
  51. package/src/build/response-authority.js +56 -0
  52. package/src/build/s3-body.as.ts +97 -0
  53. package/src/build/s3-native.as.ts +228 -0
  54. package/src/build/s3-native.js +30 -0
  55. package/src/build/schema-admission.js +83 -0
  56. package/src/build/schema-nested-json.js +93 -0
  57. package/src/build/schema-scalar-record.js +41 -0
  58. package/src/build/time-native.js +49 -0
  59. package/src/build/wasm-budget.js +28 -0
  60. package/src/config-api.js +6 -0
  61. package/src/config-schema.json +30 -0
  62. package/src/index.ts +25 -0
  63. package/src/javascript/fetch-adapter.js +3 -0
  64. package/src/javascript/jwt-verifier.js +14 -4
  65. package/src/javascript/logging.js +11 -2
  66. package/src/javascript/package-effects.js +5 -2
  67. package/src/javascript/runtime-host.js +8 -3
  68. package/src/javascript/source-package.js +4 -2
  69. package/src/javascript/target-support-policy.js +20 -3
  70. package/src/javascript/target.js +17 -1
  71. package/src/javascript/test-runtime.js +1 -0
  72. package/src/provider-contract.js +23 -6
  73. package/src/runtime/canonical-api-runtime.js +6 -0
  74. package/src/testing/conditional-kv-host.js +155 -0
  75. package/src/testing/native-dynamic-backends-host.js +39 -0
  76. package/src/testing/native-http-effects-host.js +18 -1
  77. package/src/testing/native-platform-capabilities-host.js +359 -24
  78. package/src/toolchain/body-forwarding.js +25 -0
  79. package/src/toolchain/config.js +16 -0
  80. package/src/toolchain/index.js +49 -5
  81. package/src/toolchain/logging.js +18 -0
  82. package/src/toolchain/native-execution.js +83 -0
  83. package/src/toolchain/s3.js +26 -0
package/README.md CHANGED
@@ -6,9 +6,10 @@
6
6
  > **Install directly:** Yes, for Fastly projects. Node-only projects do not need to import it directly.<br>
7
7
  > **Supported entry points:** `@pulse-compute/provider-fastly`, `@pulse-compute/provider-fastly/contract`, `@pulse-compute/provider-fastly/toolchain`, `@pulse-compute/provider-fastly/config-schema`, `@pulse-compute/provider-fastly/runtime/canonical-api-runtime`, `@pulse-compute/provider-fastly/build/canonical-target`, `@pulse-compute/provider-fastly/testing/fastly-cli`<br>
8
8
  > **Stability:** The listed entry points are supported for the Beta; all other exported subpaths are implementation-only.<br>
9
- > **Canonical documentation:** [Package guide](https://pulsecompute.io/v1.0.0-beta.1/packages/provider-fastly/)
9
+ > **npm:** [`@pulse-compute/provider-fastly`](https://www.npmjs.com/package/@pulse-compute/provider-fastly)<br>
10
+ > **Canonical documentation:** [Package guide](https://pulsecompute.io/v1.0.0-beta.11/packages/provider-fastly/)
10
11
  >
11
- > This release-status block is generated from the synchronized `Pulse 1.0.0-beta.1` package policy.
12
+ > This release-status block is generated from the synchronized `Pulse 1.0.0-beta.11` package policy.
12
13
  <!-- pulse-package-status:end -->
13
14
 
14
15
  Fastly provider configuration, canonical capability lowering, local conformance execution, Compute target generation, and explicit external-tool boundaries.
@@ -48,7 +49,7 @@ trusted wall-clock authority. It does not fall back to Node execution.
48
49
 
49
50
  ## Documentation
50
51
 
51
- - [Fastly package guide](https://pulsecompute.io/v1.0.0-beta.1/packages/provider-fastly/)
52
- - [Project configuration](https://pulsecompute.io/v1.0.0-beta.1/reference/project-config/#fastly-provider-options)
53
- - [Fastly capabilities guide](https://pulsecompute.io/v1.0.0-beta.1/guides/fastly-capabilities/)
54
- - [Environment variables](https://pulsecompute.io/v1.0.0-beta.1/reference/environment/#pulse-fastly-bin)
52
+ - [Fastly package guide](https://pulsecompute.io/v1.0.0-beta.11/packages/provider-fastly/)
53
+ - [Project configuration](https://pulsecompute.io/v1.0.0-beta.11/reference/project-config/#fastly-provider-options)
54
+ - [Fastly capabilities guide](https://pulsecompute.io/v1.0.0-beta.11/guides/fastly-capabilities/)
55
+ - [Environment variables](https://pulsecompute.io/v1.0.0-beta.11/reference/environment/#pulse-fastly-bin)
@@ -1,6 +1,10 @@
1
1
  {
2
2
  "schemaVersion": "pulse.provider-fastly-config-schema.v1",
3
3
  "fields": {
4
+ "fastly.bindings.s3": {
5
+ "kind": "object",
6
+ "default": {}
7
+ },
4
8
  "fastly.configStore": {
5
9
  "kind": "string",
6
10
  "default": "pulse_config"
@@ -68,6 +72,32 @@
68
72
  "fastly.local.networkFetch": {
69
73
  "kind": "boolean",
70
74
  "default": false
75
+ },
76
+ "fastly.maxDurationMs": {
77
+ "kind": "optional-number"
78
+ },
79
+ "fastly.build.maxWasmBytes": {
80
+ "kind": "positive-safe-integer",
81
+ "default": 4194304
82
+ },
83
+ "fastly.maxWasmBytes": {
84
+ "kind": "positive-safe-integer"
85
+ },
86
+ "fastly.bodyForwarding": {
87
+ "kind": "object"
88
+ },
89
+ "fastly.bodyForwarding.requestMaxBytes": {
90
+ "kind": "integer",
91
+ "minimum": 1,
92
+ "maximum": 1048576
93
+ },
94
+ "fastly.bodyForwarding.responseMaxBytes": {
95
+ "kind": "integer",
96
+ "minimum": 1,
97
+ "maximum": 1048576
98
+ },
99
+ "fastly.logEndpoint": {
100
+ "kind": "optional-string"
71
101
  }
72
102
  }
73
103
  }
package/dist/index.d.ts CHANGED
@@ -13,7 +13,18 @@ export interface PulseFastlyGripOptions {
13
13
  export interface PulseFastlyLocalOptions {
14
14
  readonly networkFetch?: boolean;
15
15
  }
16
+ export interface PulseFastlyBodyForwardingOptions {
17
+ readonly requestMaxBytes: number;
18
+ readonly responseMaxBytes: number;
19
+ }
16
20
  export interface PulseFastlyProviderOptions {
21
+ /** Inclusive final Native Wasm byte budget; default 4 MiB. */
22
+ readonly maxWasmBytes?: number;
23
+ readonly maxDurationMs?: number;
24
+ /** Experimental Native metered pump; final close hands delivery to Fastly. */
25
+ readonly bodyForwarding?: PulseFastlyBodyForwardingOptions;
26
+ /** Named production log stream; omitted preserves stdout. */
27
+ readonly logEndpoint?: string;
17
28
  readonly configStore?: string;
18
29
  readonly secretStore?: string;
19
30
  readonly kv?: Readonly<Record<string, string>>;
@@ -26,9 +37,13 @@ export interface PulseFastlyProviderOptions {
26
37
  readonly local?: PulseFastlyLocalOptions;
27
38
  }
28
39
  export interface PulseFastlyProviderConfig {
40
+ readonly maxDurationMs?: number;
41
+ /** Experimental Native metered pump; final close hands delivery to Fastly. */
42
+ readonly bodyForwarding?: PulseFastlyBodyForwardingOptions;
29
43
  readonly kind: 'fastly';
30
44
  readonly version: typeof FASTLY_PROVIDER_API_VERSION;
31
45
  readonly bindings: {
46
+ readonly logEndpoint?: string;
32
47
  readonly configStore: string;
33
48
  readonly secretStore: string;
34
49
  readonly kv: Readonly<Record<string, string>>;
@@ -47,6 +62,7 @@ export interface PulseFastlyProviderConfig {
47
62
  readonly dynamicBackends: boolean;
48
63
  };
49
64
  readonly build: {
65
+ readonly maxWasmBytes: number;
50
66
  readonly name: string;
51
67
  readonly description: string;
52
68
  readonly authors: readonly string[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -5,6 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.FASTLY_PROVIDER_API_VERSION = void 0;
7
7
  exports.fastly = fastly;
8
+ const { normalizeFastlyLogEndpoint } = require('../src/toolchain/logging.js');
9
+ const { normalizeBodyForwarding } = require('../src/toolchain/body-forwarding.js');
10
+ const { normalizeFastlyMaxWasmBytes } = require('../src/build/wasm-budget.js');
11
+ const { normalizeRequestDuration } = require('@pulse-compute/runtime/host');
8
12
  const config_schema_json_1 = __importDefault(require("./config-schema.json"));
9
13
  const fastlySchemaFields = config_schema_json_1.default.fields;
10
14
  const fastlyDefaults = Object.freeze(Object.fromEntries(Object.entries(fastlySchemaFields).filter(([, rule]) => Object.prototype.hasOwnProperty.call(rule, 'default')).map(([key, rule]) => [key, rule.default])));
@@ -37,8 +41,11 @@ function fastly(options = {}) {
37
41
  const normalizedGrip = options.grip === undefined ? undefined : gripBindings(options.grip);
38
42
  return Object.freeze({
39
43
  kind: 'fastly',
44
+ maxDurationMs: normalizeRequestDuration(options.maxDurationMs),
45
+ bodyForwarding: normalizeBodyForwarding(options.bodyForwarding, options.maxDurationMs),
40
46
  version: exports.FASTLY_PROVIDER_API_VERSION,
41
47
  bindings: Object.freeze({
48
+ ...(options.logEndpoint === undefined ? {} : { logEndpoint: normalizeFastlyLogEndpoint(options.logEndpoint) }),
42
49
  configStore: String(options.configStore ?? fastlyDefaults['fastly.configStore']),
43
50
  secretStore: String(options.secretStore ?? fastlyDefaults['fastly.secretStore']),
44
51
  kv: stringMap(options.kv),
@@ -47,6 +54,7 @@ function fastly(options = {}) {
47
54
  dynamicBackends: options.dynamicBackends === undefined ? Boolean(fastlyDefaults['fastly.dynamicBackends']) : options.dynamicBackends === true
48
55
  }),
49
56
  build: Object.freeze({
57
+ maxWasmBytes: normalizeFastlyMaxWasmBytes(options.maxWasmBytes),
50
58
  name: String(options.name ?? fastlyDefaults['fastly.name']),
51
59
  description: String(options.description ?? fastlyDefaults['fastly.description']),
52
60
  authors: Object.freeze((options.authors ?? (Array.isArray(fastlyDefaults['fastly.authors']) ? fastlyDefaults['fastly.authors'] : [])).map(String)),
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pulse-compute/provider-fastly",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.11",
4
4
  "license": "Apache-2.0",
5
5
  "engines": {
6
6
  "node": "^22.14.0 || ^24.0.0"
@@ -59,14 +59,15 @@
59
59
  }
60
60
  },
61
61
  "dependencies": {
62
- "@pulse-compute/crypto": "1.0.0-beta.1",
63
- "@pulse-compute/jwt": "1.0.0-beta.1",
64
- "@pulse-compute/runtime": "1.0.0-beta.1",
65
- "@pulse-compute/wasm-build-support": "1.0.0-beta.1",
66
- "@pulse-compute/wasm-contracts": "1.0.0-beta.1",
67
- "@pulse-compute/wasm-guest-link": "1.0.0-beta.1",
68
- "@pulse-compute/wasm-host-runtime": "1.0.0-beta.1",
69
- "@pulse-compute/wasm-runtime-core-as": "1.0.0-beta.1",
62
+ "@pulse-compute/crypto": "1.0.0-beta.11",
63
+ "@pulse-compute/jwt": "1.0.0-beta.11",
64
+ "@pulse-compute/runtime": "1.0.0-beta.11",
65
+ "@pulse-compute/s3": "1.0.0-beta.11",
66
+ "@pulse-compute/wasm-build-support": "1.0.0-beta.11",
67
+ "@pulse-compute/wasm-contracts": "1.0.0-beta.11",
68
+ "@pulse-compute/wasm-guest-link": "1.0.0-beta.11",
69
+ "@pulse-compute/wasm-host-runtime": "1.0.0-beta.11",
70
+ "@pulse-compute/wasm-runtime-core-as": "1.0.0-beta.11",
70
71
  "esbuild": "0.28.1"
71
72
  },
72
73
  "types": "./dist/index.d.ts",
@@ -86,7 +87,7 @@
86
87
  "url": "git+https://github.com/pulse-compute/pulse.git",
87
88
  "directory": "packages/provider-fastly"
88
89
  },
89
- "homepage": "https://pulsecompute.io/v1.0.0-beta.1/packages/provider-fastly/",
90
+ "homepage": "https://pulsecompute.io/v1.0.0-beta.11/packages/provider-fastly/",
90
91
  "bugs": {
91
92
  "url": "https://github.com/pulse-compute/pulse/issues"
92
93
  },
@@ -1,12 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  const crypto = require('node:crypto');
4
+ const { normalizeFastlyMaxWasmBytes, assertFastlyWasmBudget } = require('./wasm-budget.js');
4
5
  const fs = require('node:fs');
5
6
  const path = require('node:path');
6
7
  const { CANONICAL_NATIVE_PLAN_VERSION } = require('@pulse-compute/wasm-contracts/handler/canonical-native-plan');
7
8
  const {
8
9
  FASTLY_NATIVE_PLATFORM_CAPABILITIES_VERSION,
9
10
  compileFastlyNativePlatformCapabilitiesPlan,
11
+ resolveCapabilityBindings,
10
12
  writeFastlyNativePlatformCapabilitiesModule
11
13
  } = require('./native-platform-capabilities.js');
12
14
 
@@ -80,6 +82,12 @@ function assertExactProviderNative(native) {
80
82
  }
81
83
  );
82
84
  }
85
+ if (native.manifest.hostExtensions) {
86
+ const evidence = native.manifest.hostExtensions;
87
+ if (evidence.finalWasmSha256 !== observedSha256) throw providerBuildError(
88
+ 'PULSE_HOST_EXTENSION_IMPORT', 'Terminal service evidence does not identify the packaged Wasm.', { automaticFallback: false });
89
+ require('@pulse-compute/wasm-contracts/provider/toolchain').hostExtensions.auditWasm(native.wasm, evidence.importPolicy);
90
+ }
83
91
  if (native.guestLink) {
84
92
  const audit = native.guestLink.audit;
85
93
  if (
@@ -222,6 +230,8 @@ function inspectFastlyCanonicalTarget(options = {}) {
222
230
  }
223
231
  const providerConfig = options.providerConfig || {};
224
232
  const bindings = options.bindings || providerConfig.bindings || {};
233
+ const maxWasmBytes = normalizeFastlyMaxWasmBytes(providerConfig.build?.maxWasmBytes);
234
+ if (isFastlyNativeArtifact(options.native)) assertFastlyWasmBudget(options.native.wasm.length, maxWasmBytes);
225
235
  const native = isFastlyNativeArtifact(options.native)
226
236
  ? assertExactProviderNative(options.native)
227
237
  : compileFastlyNativePlatformCapabilitiesPlan(plan, {
@@ -229,6 +239,9 @@ function inspectFastlyCanonicalTarget(options = {}) {
229
239
  projectRoot: options.projectRoot,
230
240
  profile: options.profile,
231
241
  bindings,
242
+ maxDurationMs: providerConfig.maxDurationMs,
243
+ bodyForwarding: providerConfig.bodyForwarding,
244
+ maxWasmBytes,
232
245
  requirePlatformCapability: false,
233
246
  canonicalBuild: true,
234
247
  targetDescriptor: options.targetDescriptor,
@@ -239,8 +252,30 @@ function inspectFastlyCanonicalTarget(options = {}) {
239
252
  || (options.native && options.native.guestUnits),
240
253
  nativeOptimization: options.nativeOptimization
241
254
  || (options.experimentalNativeSize === true ? 'experimental-native-size' : undefined),
255
+ elideJsonCacheArena: options.elideJsonCacheArena,
256
+ emitWat: options.emitWat,
242
257
  timeoutMs: options.compileTimeoutMs
243
258
  });
259
+ if (native.manifest.bindings?.logEndpoint !== require('../toolchain/logging.js').normalizeFastlyLogEndpoint(bindings.logEndpoint)) {
260
+ throw providerBuildError('PULSE_FASTLY_NATIVE_ARTIFACT_INVALID', 'Fastly artifact logging destination does not match the selected provider profile; rebuild the Native artifact.');
261
+ }
262
+ const duration = require('@pulse-compute/runtime/host').normalizeRequestDuration(providerConfig.maxDurationMs);
263
+ if (native.manifest.bindings?.maxDurationMs !== duration) {
264
+ throw providerBuildError('PULSE_REQUEST_DURATION_ARTIFACT_MISMATCH', 'Fastly artifact request deadline does not match the selected provider profile.');
265
+ }
266
+ const forwarding = require('../toolchain/body-forwarding.js').normalizeBodyForwarding(providerConfig.bodyForwarding, duration);
267
+ if (JSON.stringify(native.manifest.bindings?.bodyForwarding) !== JSON.stringify(forwarding)) {
268
+ throw providerBuildError('PULSE_FASTLY_BODY_FORWARDING_ARTIFACT_MISMATCH', 'Fastly artifact forwarding bounds do not match the selected provider profile.');
269
+ }
270
+ if (native.manifest.dynamicBackends || (isFastlyNativeArtifact(options.native) && bindings.dynamicBackends === true)) {
271
+ const dynamic = require('./native-dynamic-backends.js');
272
+ const expected = resolveCapabilityBindings(plan, { bindings, maxDurationMs: duration, bodyForwarding: forwarding });
273
+ const expectedPolicy = dynamic.active(expected) ? dynamic.describe(bindings.backends) : undefined;
274
+ if (JSON.stringify(native.manifest.dynamicBackends) !== JSON.stringify(expectedPolicy)
275
+ || JSON.stringify(native.manifest.backends) !== JSON.stringify(expected.backends)) {
276
+ throw providerBuildError('PULSE_FASTLY_NATIVE_ARTIFACT_INVALID', 'Fastly artifact backend selection does not match the selected provider profile; rebuild the Native artifact.');
277
+ }
278
+ }
244
279
  return Object.freeze({
245
280
  target: FASTLY_CANONICAL_TARGET,
246
281
  provider: 'fastly',
@@ -287,6 +322,8 @@ function writeFastlyCanonicalTarget(options = {}) {
287
322
  fs.mkdirSync(binDir, { recursive: true });
288
323
 
289
324
  let native;
325
+ const maxWasmBytes = normalizeFastlyMaxWasmBytes(providerConfig.build?.maxWasmBytes);
326
+ if (isFastlyNativeArtifact(options.native)) assertFastlyWasmBudget(options.native.wasm.length, maxWasmBytes);
290
327
  const auditedNative = isFastlyNativeArtifact(options.native)
291
328
  ? assertExactProviderNative(options.native)
292
329
  : null;
@@ -308,6 +345,8 @@ function writeFastlyCanonicalTarget(options = {}) {
308
345
  || (options.native && options.native.guestUnits),
309
346
  nativeOptimization: options.nativeOptimization
310
347
  || (options.experimentalNativeSize === true ? 'experimental-native-size' : undefined),
348
+ elideJsonCacheArena: options.elideJsonCacheArena,
349
+ emitWat: options.emitWat,
311
350
  compileTimeoutMs: options.compileTimeoutMs
312
351
  });
313
352
  native = realization.native;
@@ -373,7 +412,7 @@ function writeFastlyCanonicalTarget(options = {}) {
373
412
  }),
374
413
  optimization: native.manifest.optimization,
375
414
  wasm: Object.freeze({ file: 'bin/main.wasm', ...native.manifest.wasm }),
376
- wat: Object.freeze({ file: 'bin/main.wat', ...native.manifest.wat }),
415
+ wat: Object.freeze({ file: written.watFile ? 'bin/main.wat' : null, ...native.manifest.wat }),
377
416
  imports: native.manifest.imports,
378
417
  importModules: native.manifest.importModules,
379
418
  exports: native.manifest.exports,
@@ -402,7 +441,7 @@ function writeFastlyCanonicalTarget(options = {}) {
402
441
  localEntry: 'fastly-entry.cjs',
403
442
  sourceEntry: 'src/main.as.ts',
404
443
  wasm: 'bin/main.wasm',
405
- wat: 'bin/main.wat',
444
+ wat: written.watFile ? 'bin/main.wat' : null,
406
445
  nativePlan: 'fastly-native-plan.json',
407
446
  nativeManifest: 'fastly-native-manifest.json',
408
447
  fastlyToml: 'fastly.toml',
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+ const fs = require('node:fs');
3
+ const path = require('node:path');
4
+ function digestNativeSource(plan) {
5
+ if (!plan.effects.some(effect => effect.kind === 'crypto.digestText')) return '';
6
+ const selected = plan.crypto?.algorithms.find(entry => entry.algorithm === 'SHA-256');
7
+ if (!selected || selected.realization !== 'guest-source:pulse-hmac-as' || selected.automaticFallback !== false) throw new TypeError('Digest requires the selected Crypto SHA-256 guest source.');
8
+ const root = path.dirname(require.resolve('@pulse-compute/crypto/pulsewasm-native'));
9
+ return fs.readFileSync(path.join(root, 'as/digest-text.as.ts'), 'utf8') + `
10
+ function __pulse_fastly_digest_begin(index: i32, outer: __PulseFastlyValue): void {
11
+ const payload = __pulse_fastly_value(__pulse_fastly_payload_field(outer, 'invocation'))
12
+ const text = __pulse_fastly_value(__pulse_fastly_payload_field(payload, 'text'))
13
+ const digest = __pulse_crypto_digest_text(text.kind == PULSE_VALUE_STRING ? text.text : null)
14
+ if (text.kind == PULSE_VALUE_STRING) __pulse_fastly_remember_secret(text.text)
15
+ const result = host_value_object()
16
+ host_value_object_set(result, __pulse_fastly_string_value('status'), __pulse_fastly_string_value(digest.status))
17
+ if (digest.status == 'ok') {
18
+ host_value_object_set(result, __pulse_fastly_string_value('sha256'), __pulse_fastly_string_value(digest.sha256))
19
+ host_value_object_set(result, __pulse_fastly_string_value('byteLength'), host_value_number(f64(digest.byteLength)))
20
+ } else host_value_object_set(result, __pulse_fastly_string_value('reason'), __pulse_fastly_string_value(digest.reason))
21
+ __pulse_fastly_ready_effect(index, result)
22
+ }
23
+ `;
24
+ }
25
+ module.exports = { digestNativeSource };
@@ -0,0 +1,51 @@
1
+ 'use strict';
2
+
3
+ const { CANONICAL_EFFECT_INVOCATION_POLICY } = require('@pulse-compute/wasm-contracts/handler/canonical-runtime');
4
+
5
+ function runtimeSource(options = {}) {
6
+ const lifecycle = options.lifecycle;
7
+ const delivery = options.packageCompletion ? 'result == 0 ? pulse_package_set_effect_failure(index) : pulse_set_effect_result(index, result)' : 'pulse_set_effect_result(index, result)';
8
+ return `
9
+ const PULSE_FASTLY_MAX_EFFECT_INVOCATIONS: i32 = ${CANONICAL_EFFECT_INVOCATION_POLICY.defaultMaxEffects}
10
+ let __pulse_invocation_count: i32 = 0
11
+ let __pulse_invocation_started: bool = false
12
+ let __pulse_invocation_closed: bool = false
13
+ let __pulse_invocation_failure: i32 = 171
14
+ const __pulse_invocation_tickets = new StaticArray<i32>(PULSE_FASTLY_EFFECT_COUNT)
15
+ function __pulse_invocation_begin(index: i32): bool {
16
+ if (__pulse_invocation_closed || index < 0 || index >= PULSE_FASTLY_EFFECT_COUNT
17
+ || unchecked(__pulse_invocation_tickets[index]) != 0) {
18
+ __pulse_fastly_fail(PULSE_ERROR_STATE, __pulse_invocation_failure, index); return false
19
+ }
20
+ if (__pulse_invocation_count >= PULSE_FASTLY_MAX_EFFECT_INVOCATIONS) {
21
+ __pulse_invocation_closed = true
22
+ __pulse_invocation_failure = 170
23
+ __pulse_fastly_fail(PULSE_ERROR_STATE, 170, index); return false
24
+ }
25
+ unchecked(__pulse_invocation_tickets[index] = ++__pulse_invocation_count)
26
+ return true
27
+ }
28
+ function __pulse_invocation_settle(index: i32, ticket: i32, result: i32): i32 {
29
+ if (__pulse_invocation_closed || index < 0 || index >= PULSE_FASTLY_EFFECT_COUNT
30
+ || ticket <= 0 || unchecked(__pulse_invocation_tickets[index]) != ticket) {
31
+ __pulse_fastly_fail(PULSE_ERROR_STATE, __pulse_invocation_failure, index); return 0
32
+ }
33
+ ${lifecycle?.site('effect-settle') ? lifecycle.site('effect-settle') + '\n' : ''} unchecked(__pulse_invocation_tickets[index] = 0)
34
+ ${lifecycle ? lifecycle.site('effect-deliver', delivery) : 'return ' + delivery}
35
+ }
36
+ function __pulse_invocation_close(): void {
37
+ ${lifecycle?.site('invocation-close') ? lifecycle.site('invocation-close') + '\n' : ''} __pulse_invocation_closed = true
38
+ for (let i = 0; i < PULSE_FASTLY_EFFECT_COUNT; i += 1) unchecked(__pulse_invocation_tickets[i] = 0)
39
+ ${lifecycle?.site('invocation-closed') ? lifecycle.site('invocation-closed') + '\n' : ''}}
40
+ `;
41
+ }
42
+
43
+ function instrument(source) {
44
+ const signature = 'function host_effect_begin(effectIndex: i32, payload: i32): void {';
45
+ if (!source.includes(signature)) throw new Error('Fastly invocation admission boundary drift.');
46
+ // Every guest-requested slot gets a ticket, including a group member suppressed
47
+ // by an earlier application error. Its undefined result can then be drained.
48
+ return source.replace(signature, signature + '\n if (!__pulse_invocation_begin(effectIndex)) return;');
49
+ }
50
+
51
+ module.exports = { runtimeSource, instrument, policy: CANONICAL_EFFECT_INVOCATION_POLICY };
@@ -0,0 +1,32 @@
1
+ function __pulse_embedded_request_header(name: string): string | null {
2
+ const values = __pulse_request_header_list(name, false);
3
+ return values.length ? values.join(', ') : null;
4
+ }
5
+ function __pulse_embedded_field(payload: __PulseFastlyValue, name: string): string { return __pulse_fastly_string(__pulse_fastly_payload_field(payload, name)); }
6
+ function __pulse_fastly_embedded_asset(payload: __PulseFastlyValue): i32 {
7
+ // Avoid exposing provider buffers as canonical application values.
8
+ const length = __pulse_fastly_value(__pulse_fastly_payload_field(payload, 'embeddedFound')).boolean != 0 ? i32(__pulse_fastly_number(__pulse_fastly_payload_field(payload, 'embeddedLength'))) : -1;
9
+ const etag = __pulse_embedded_field(payload, 'embeddedEtag'), method = __pulse_embedded_field(payload, 'method');
10
+ const selected = __pulse_embedded_selection(length, method, etag,
11
+ __pulse_embedded_request_header('if-none-match'), __pulse_embedded_request_header('range'), __pulse_embedded_request_header('if-range'));
12
+ if (__pulse_request_headers_failed) return 0;
13
+ const output = new __PulseFastlyValue(); output.kind = PULSE_VALUE_RESPONSE; output.status = selected.status;
14
+ if (selected.status != 400 && selected.status != 404) {
15
+ output.headers.push(new __PulseFastlyHeader('content-type', __pulse_embedded_field(payload, 'embeddedType')));
16
+ output.headers.push(new __PulseFastlyHeader('etag', etag)); output.headers.push(new __PulseFastlyHeader('accept-ranges', 'bytes'));
17
+ if (selected.contentRange.length) output.headers.push(new __PulseFastlyHeader('content-range', selected.contentRange));
18
+ if (selected.status == 200 || selected.status == 206) {
19
+ output.headers.push(new __PulseFastlyHeader('content-length', max<i32>(0, selected.end - selected.start + 1).toString()));
20
+ if (method != 'HEAD') output.binaryBody = __pulse_embedded_bytes(__pulse_embedded_field(payload, 'embeddedData'), selected.start, selected.end);
21
+ }
22
+ }
23
+ return __pulse_fastly_put(output);
24
+ }
25
+ function __pulse_fastly_write_binary(handle: i32, data: Uint8Array): i32 {
26
+ const written = new StaticArray<i32>(1); let offset = 0;
27
+ while (offset < data.length) {
28
+ if (fastly_http_body_write(handle, data.dataStart + offset, data.length - offset, 0, changetype<usize>(written)) != 0 || written[0] <= 0 || written[0] > data.length - offset) return 1;
29
+ offset += written[0];
30
+ }
31
+ return 0;
32
+ }
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ const { nativeLoggingSource } = require('./native-stdio.js');
3
4
  const crypto = require('node:crypto');
4
5
  const fs = require('node:fs');
5
6
  const os = require('node:os');
@@ -41,6 +42,7 @@ const ALLOWED_IMPORTS = new Set([
41
42
  'fastly_http_resp:new',
42
43
  'fastly_http_resp:send_downstream',
43
44
  'fastly_http_resp:status_set',
45
+ 'wasi_snapshot_preview1:fd_write',
44
46
  'fastly_log:endpoint_get',
45
47
  'fastly_log:write',
46
48
  'fastly_secret_store:get',
@@ -178,8 +180,7 @@ function providerRuntimeSource(bindings, options) {
178
180
  @external("fastly_secret_store", "open") declare function fastly_secret_store_open(name: usize, nameLength: i32, handleOut: usize): i32
179
181
  @external("fastly_secret_store", "get") declare function fastly_secret_store_get(handle: i32, key: usize, keyLength: i32, secretOut: usize): i32
180
182
  @external("fastly_secret_store", "plaintext") declare function fastly_secret_store_plaintext(secret: i32, value: usize, valueLength: i32, writtenOut: usize): i32
181
- @external("fastly_log", "endpoint_get") declare function fastly_log_endpoint_get(name: usize, nameLength: i32, handleOut: usize): i32
182
- @external("fastly_log", "write") declare function fastly_log_write(handle: i32, message: usize, messageLength: i32, writtenOut: usize): i32
183
+ ${nativeLoggingSource(options.logEndpoint)}
183
184
 
184
185
  const __PULSE_FASTLY_ENTITIES_ABI: i64 = 1
185
186
  const __PULSE_FASTLY_ENTITIES_BUFFER: i32 = ${BUFFER_BYTES}
@@ -191,7 +192,6 @@ let __pulse_fastly_entities_results = new Array<string>()
191
192
  let __pulse_fastly_entities_ready = new Array<i32>()
192
193
  let __pulse_fastly_entities_ok = new Array<i32>()
193
194
  let __pulse_fastly_entities_redactions = new Array<string>()
194
- let __pulse_fastly_entities_log_handle: i32 = -1
195
195
 
196
196
  function __pulse_fastly_entities_out(): StaticArray<i32> { return new StaticArray<i32>(1) }
197
197
  function __pulse_fastly_entities_out_value(value: StaticArray<i32>): i32 { return load<i32>(changetype<usize>(value)) }
@@ -327,15 +327,8 @@ function pulse_entities_host_effect_begin(effectIndex: i32, payloadPointer: i32,
327
327
  }
328
328
  function pulse_entities_host_log(level: i32, payloadPointer: i32, payloadLength: i32): void {
329
329
  if (payloadPointer <= 0 || payloadLength < 0) return
330
- if (__pulse_fastly_entities_log_handle < 0) {
331
- const endpoint = __pulse_fastly_entities_utf8("stdout")
332
- const handleOut = __pulse_fastly_entities_out()
333
- if (fastly_log_endpoint_get(changetype<usize>(endpoint), endpoint.byteLength, changetype<usize>(handleOut)) != __PULSE_FASTLY_OK) return
334
- __pulse_fastly_entities_log_handle = __pulse_fastly_entities_out_value(handleOut)
335
- }
336
330
  const message = __pulse_fastly_entities_utf8("[pulse:entities:" + level.toString() + "] " + __pulse_fastly_entities_redact(changetype<string>(payloadPointer)) + "\n")
337
- const written = __pulse_fastly_entities_out()
338
- fastly_log_write(__pulse_fastly_entities_log_handle, changetype<usize>(message), message.byteLength, changetype<usize>(written))
331
+ __pulse_fastly_write_stdout(message)
339
332
  }
340
333
  function __pulse_fastly_entities_write_body(handle: i32, value: string): i32 {
341
334
  const bytes = __pulse_fastly_entities_utf8(value)
@@ -496,6 +489,7 @@ function compileFastlyEntitiesNative(sourceArtifact, options = {}) {
496
489
  '--path', path.join(compilerFallback, 'node_modules'),
497
490
  '--path', path.dirname(jsonAsRoot)
498
491
  ];
492
+ require('@pulse-compute/wasm-build-support/native-optimization').appendJsonCacheArenaArgs(args, options.elideJsonCacheArena, true);
499
493
  const startedAt = Date.now();
500
494
  const result = spawnSync(asc.executable, args, {
501
495
  cwd: staging,
@@ -546,6 +540,7 @@ function compileFastlyEntitiesNative(sourceArtifact, options = {}) {
546
540
  package: 'assemblyscript',
547
541
  version: JSON.parse(fs.readFileSync(path.join(asc.packageRoot, 'package.json'), 'utf8')).version,
548
542
  jsonAs: jsonAsManifest.version,
543
+ elideDisabledCacheArena: options.elideJsonCacheArena === true,
549
544
  durationMs: Date.now() - startedAt
550
545
  }),
551
546
  policy: generated.policy