@pulse-compute/wasm-contracts 0.0.0 → 1.0.0-beta.2

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 (97) hide show
  1. package/README.md +35 -2
  2. package/package.json +124 -6
  3. package/src/assets/contracts.js +296 -0
  4. package/src/config/provider-resolution.js +54 -0
  5. package/src/config/runtime-provider-kv.js +73 -0
  6. package/src/config/symbolic-refs.js +192 -0
  7. package/src/crypto/contracts.js +647 -0
  8. package/src/definitions/config-schema.js +30 -0
  9. package/src/definitions/handler-roles.js +66 -0
  10. package/src/definitions/path-grammar.js +11 -0
  11. package/src/definitions/router-api.js +149 -0
  12. package/src/diagnostics/codes.js +42 -0
  13. package/src/diagnostics/reporter.js +20 -0
  14. package/src/diagnostics.js +139 -0
  15. package/src/dispatch-table.js +23 -0
  16. package/src/entities/catalog.d.ts +7 -0
  17. package/src/entities/catalog.js +87 -0
  18. package/src/entities/contracts.d.ts +95 -0
  19. package/src/entities/contracts.js +122 -0
  20. package/src/entities/json-rpc.d.ts +27 -0
  21. package/src/entities/json-rpc.js +69 -0
  22. package/src/entities/runtime.d.ts +67 -0
  23. package/src/entities/runtime.js +288 -0
  24. package/src/events/contracts.js +456 -0
  25. package/src/execution-plan.js +42 -0
  26. package/src/grip/contracts.js +106 -0
  27. package/src/handler/backend-json-request-body.js +58 -0
  28. package/src/handler/beta-lifecycle-golden.js +97 -0
  29. package/src/handler/canonical-native-plan.js +143 -0
  30. package/src/handler/canonical-native-runtime.js +168 -0
  31. package/src/handler/canonical-runtime.js +13 -0
  32. package/src/handler/context.js +131 -0
  33. package/src/handler/ctx-contract.js +71 -0
  34. package/src/handler/doctor-readiness-aggregator.js +67 -0
  35. package/src/handler/effects.js +446 -0
  36. package/src/handler/io-lifecycle.js +134 -0
  37. package/src/handler/lifecycle-authoring-alignment.js +56 -0
  38. package/src/handler/lifecycle-readiness-aggregate.js +93 -0
  39. package/src/handler/reference-node-lifecycle-golden.js +73 -0
  40. package/src/handler/request-json-body.js +147 -0
  41. package/src/handler/runtime-api.js +471 -0
  42. package/src/handler/schema-decode-result.js +135 -0
  43. package/src/handler/schema-response-codec.js +141 -0
  44. package/src/handler/surface-contract.js +601 -0
  45. package/src/handler/types-contract.js +51 -0
  46. package/src/handler-table.js +28 -0
  47. package/src/host/backend-capabilities.js +24 -0
  48. package/src/host/capabilities.js +273 -0
  49. package/src/host/channel-broadcaster.js +60 -0
  50. package/src/host/json-body.js +80 -0
  51. package/src/host/request-result-headers.js +38 -0
  52. package/src/host/streaming-passthrough.js +90 -0
  53. package/src/host/wasm-host-abi.js +154 -0
  54. package/src/index.js +75 -0
  55. package/src/jwt/contracts.js +427 -0
  56. package/src/library/api-surface.js +99 -0
  57. package/src/library/contracts.js +273 -0
  58. package/src/library/manifest.js +317 -0
  59. package/src/library/second-package-owned-lowering.js +39 -0
  60. package/src/library/sidecars.js +147 -0
  61. package/src/logging.js +89 -0
  62. package/src/package/package-contract.js +975 -0
  63. package/src/package/package-contract.schema.json +303 -0
  64. package/src/package/runtime-pulse-live.js +100 -0
  65. package/src/path-table.js +12 -0
  66. package/src/path.js +275 -0
  67. package/src/project/config-factory.js +48 -0
  68. package/src/project/config-plan.js +409 -0
  69. package/src/project/config-runtime.js +46 -0
  70. package/src/project/javascript-application.js +212 -0
  71. package/src/project/javascript-core-capabilities.js +44 -0
  72. package/src/project/native-optimization.js +9 -0
  73. package/src/project/package-ownership.js +242 -0
  74. package/src/project/package-product-projection.js +171 -0
  75. package/src/project/reachable-graph-identity.js +219 -0
  76. package/src/project/reachable-graph-projections.js +279 -0
  77. package/src/project/reachable-graph-resolver.js +303 -0
  78. package/src/project/reachable-graph-v2.js +430 -0
  79. package/src/project/reachable-graph-v2.schema.json +285 -0
  80. package/src/project/reachable-graph.js +199 -0
  81. package/src/project/reachable-graph.schema.json +222 -0
  82. package/src/project/target-support-evidence.js +559 -0
  83. package/src/provider/canonical-provider.js +239 -0
  84. package/src/provider/final-wasm-policy.js +87 -0
  85. package/src/provider/toolchain.js +771 -0
  86. package/src/route-plan.js +43 -0
  87. package/src/s3/contracts.js +12 -0
  88. package/src/schema-json/compile.js +63 -0
  89. package/src/schema-json/contracts.js +10 -0
  90. package/src/schema-json/generic-parser.js +62 -0
  91. package/src/schema-json/registry.js +359 -0
  92. package/src/schema-json/semantic-trace.js +241 -0
  93. package/src/schema-json/v1.js +65 -0
  94. package/src/schema-json/v2.js +110 -0
  95. package/src/sha256.js +104 -0
  96. package/src/spine.js +381 -0
  97. package/src/stable-id.js +142 -0
@@ -0,0 +1,97 @@
1
+ 'use strict';
2
+
3
+ const BETA_LIFECYCLE_GOLDEN_VERSION = 'pulsewasm.beta-lifecycle-golden.v1';
4
+ const BETA_LIFECYCLE_GOLDEN_PHASE = '51';
5
+ const BETA_LIFECYCLE_GOLDEN_ARTIFACT = 'beta-lifecycle-golden.json';
6
+ const BETA_LIFECYCLE_GOLDEN_CONTRACT_ID = 'pulse.beta-lifecycle-golden';
7
+
8
+ const BETA_LIFECYCLE_GOLDEN_AUTHORING_SUBSET = Object.freeze({
9
+ asyncAwait: false,
10
+ promises: false,
11
+ loops: false,
12
+ dynamicBackends: false,
13
+ dynamicAssetKeys: false,
14
+ arbitraryObjectLowering: false,
15
+ automaticSchemaGeneration: false,
16
+ binaryBodies: false,
17
+ streams: false,
18
+ multipart: false,
19
+ uploads: false,
20
+ generalObjectStoreSemantics: false
21
+ });
22
+
23
+ const BETA_LIFECYCLE_GOLDEN_SCOPE = Object.freeze({
24
+ betaApp: 'examples/beta-lifecycle/app.js',
25
+ referenceApp: 'examples/reference-node-lifecycle/app.js',
26
+ assetsPackageOutApp: 'examples/assets-package-out/app.js',
27
+ command: 'node wasm/scripts/run-wasm-tests.cjs --profile release --no-report',
28
+ publicSurfaceOnly: true,
29
+ compilerOrchestrates: true,
30
+ packageOwnedLowering: true,
31
+ packageOutDiscovery: true,
32
+ providersOwnProviderBehavior: true,
33
+ nodeReferenceLifecycle: 'implemented',
34
+ nodeCompiledWasmResolveResume: 'implemented',
35
+ nodeCompiledWasmAssets: 'implemented-narrow-terminal-get-head-text',
36
+ fastlyReferenceLifecycle: 'symbolic-parity',
37
+ fastlyPostJsonRequestBodies: 'plan-only',
38
+ fastlyCompiledWasmAssets: 'plan-only',
39
+ noReferenceAppSpecialPath: true,
40
+ noBetaAppSpecialPath: true,
41
+ noHiddenEagerWork: true,
42
+ noUserAuthoredAsync: true,
43
+ promises: false,
44
+ asyncAwait: false,
45
+ asyncify: false,
46
+ authoringSubset: BETA_LIFECYCLE_GOLDEN_AUTHORING_SUBSET
47
+ });
48
+
49
+ const BETA_LIFECYCLE_GOLDEN_POLICY = Object.freeze({
50
+ purpose: 'beta-quality lifecycle harness for trying small apps across backend effects, schema JSON, package-owned lowerers, and provider readiness',
51
+ productionCompletenessRequired: false,
52
+ productionAssetServingTarget: false,
53
+ simpleUserFunctionLoweringIntentional: true,
54
+ appBoundary: 'beta/reference apps use only public router, ctx, and package lowerable facades',
55
+ harnessBoundary: 'tests and proof builders may orchestrate origins, package-out fixtures, providers, and CLI commands',
56
+ requiredCommand: 'node wasm/scripts/run-wasm-tests.cjs --profile release --no-report',
57
+ validates: Object.freeze([
58
+ 'combined beta lifecycle example app',
59
+ 'reference Node lifecycle golden lane',
60
+ 'assets package-owned lowering',
61
+ 'assets package-out discovery',
62
+ 'assets compiled-Wasm sidecar readiness',
63
+ 'assets sidecar compile/link proof',
64
+ 'Node compiled-Wasm assets lifecycle proof',
65
+ 'Fastly lifecycle parity classification',
66
+ 'Fastly assets package-out parity classification',
67
+ 'CLI plan/doctor/build for the combined beta app',
68
+ 'router.head public route method support',
69
+ 'route/method consistency for HEAD asset routes',
70
+ 'docs for beta authoring subset and diagnostics',
71
+ 'canonical alpha artifact path hygiene'
72
+ ]),
73
+ authoringSubset: BETA_LIFECYCLE_GOLDEN_AUTHORING_SUBSET,
74
+ outOfScope: Object.freeze([
75
+ 'production asset CDN semantics',
76
+ 'binary asset bodies',
77
+ 'compiled-Wasm stream asset bodies',
78
+ 'range requests',
79
+ 'uploads',
80
+ 'cache invalidation',
81
+ 'arbitrary third-party lowerer execution',
82
+ 'async/await lowering',
83
+ 'Promise lowering',
84
+ 'automatic schema generation',
85
+ 'arbitrary JavaScript object lowering'
86
+ ])
87
+ });
88
+
89
+ module.exports = {
90
+ BETA_LIFECYCLE_GOLDEN_VERSION,
91
+ BETA_LIFECYCLE_GOLDEN_PHASE,
92
+ BETA_LIFECYCLE_GOLDEN_ARTIFACT,
93
+ BETA_LIFECYCLE_GOLDEN_CONTRACT_ID,
94
+ BETA_LIFECYCLE_GOLDEN_AUTHORING_SUBSET,
95
+ BETA_LIFECYCLE_GOLDEN_SCOPE,
96
+ BETA_LIFECYCLE_GOLDEN_POLICY
97
+ };
@@ -0,0 +1,143 @@
1
+ 'use strict';
2
+
3
+ const CANONICAL_NATIVE_PLAN_VERSION = 'pulse.canonical-native-plan.v2';
4
+ const CANONICAL_NATIVE_PLAN_HASH_ALGORITHM = 'sha256';
5
+ const CANONICAL_NATIVE_PLAN_OWNERSHIP_VERSION = 'pulse.canonical-native-ownership.v1';
6
+
7
+ const CANONICAL_NATIVE_STATEMENT_KINDS = Object.freeze([
8
+ 'local',
9
+ 'effect',
10
+ 'effect-group',
11
+ 'if',
12
+ 'return',
13
+ 'expression'
14
+ ]);
15
+
16
+ const CANONICAL_NATIVE_EXPRESSION_KINDS = Object.freeze([
17
+ 'literal',
18
+ 'undefined',
19
+ 'local',
20
+ 'context-read',
21
+ 'array',
22
+ 'object',
23
+ 'template',
24
+ 'binary',
25
+ 'unary',
26
+ 'conditional',
27
+ 'property',
28
+ 'element',
29
+ 'intrinsic',
30
+ 'method-call',
31
+ 'assignment',
32
+ 'update',
33
+ 'spread'
34
+ ]);
35
+
36
+ const CANONICAL_NATIVE_CONTEXT_READS = Object.freeze([
37
+ 'req.method',
38
+ 'req.url',
39
+ 'req.path',
40
+ 'req.headers',
41
+ 'event.payload'
42
+ ]);
43
+
44
+ const CANONICAL_NATIVE_INTRINSICS = Object.freeze([
45
+ 'request.header',
46
+ 'request.text',
47
+ 'request.json',
48
+ 'response.json',
49
+ 'response.text',
50
+ 'response.custom',
51
+ 'kv.namespace',
52
+ 'state.get',
53
+ 'state.set',
54
+ 'logging.emit',
55
+ 'event.runtime-id',
56
+ 'router.match',
57
+ 'router.param',
58
+ 'grip.is-websocket',
59
+ 'grip.subscribe',
60
+ 'grip.handoff'
61
+ ]);
62
+
63
+ const CANONICAL_NATIVE_DECODER_KINDS = Object.freeze([
64
+ 'json',
65
+ 'text'
66
+ ]);
67
+
68
+ const CANONICAL_NATIVE_RESULT_MODES = Object.freeze([
69
+ 'bind',
70
+ 'bind-group',
71
+ 'discard',
72
+ 'return'
73
+ ]);
74
+
75
+ const CANONICAL_NATIVE_VALUE_KINDS = Object.freeze([
76
+ 'unknown',
77
+ 'undefined',
78
+ 'null',
79
+ 'boolean',
80
+ 'number',
81
+ 'string',
82
+ 'string-or-undefined',
83
+ 'headers',
84
+ 'array',
85
+ 'object',
86
+ 'json',
87
+ 'json-or-undefined',
88
+ 'fetch-response',
89
+ 'kv-namespace',
90
+ 'pulse-result',
91
+ 'opaque-response',
92
+ 'structured-response',
93
+ 'ack'
94
+ ]);
95
+
96
+ const CANONICAL_NATIVE_PLAN_DIAGNOSTIC_CODES = Object.freeze({
97
+ COMPILED_PROGRAM_REQUIRED: 'PULSE_CANONICAL_NATIVE_COMPILED_PROGRAM_REQUIRED',
98
+ GENERATED_HANDLER_MISSING: 'PULSE_CANONICAL_NATIVE_HANDLER_MISSING',
99
+ GENERATED_HANDLER_DUPLICATE: 'PULSE_CANONICAL_NATIVE_HANDLER_DUPLICATE',
100
+ STATEMENT_UNSUPPORTED: 'PULSE_CANONICAL_NATIVE_STATEMENT_UNSUPPORTED',
101
+ EXPRESSION_UNSUPPORTED: 'PULSE_CANONICAL_NATIVE_EXPRESSION_UNSUPPORTED',
102
+ BINDING_UNSUPPORTED: 'PULSE_CANONICAL_NATIVE_BINDING_UNSUPPORTED',
103
+ LOCAL_UNRESOLVED: 'PULSE_CANONICAL_NATIVE_LOCAL_UNRESOLVED',
104
+ EFFECT_INVALID: 'PULSE_CANONICAL_NATIVE_EFFECT_INVALID',
105
+ EFFECT_MISMATCH: 'PULSE_CANONICAL_NATIVE_EFFECT_MISMATCH',
106
+ CONTINUATION_MISMATCH: 'PULSE_CANONICAL_NATIVE_CONTINUATION_MISMATCH',
107
+ EVENT_HANDLER_INELIGIBLE: 'PULSE_CANONICAL_NATIVE_EVENT_HANDLER_INELIGIBLE',
108
+ LOG_INVALID: 'PULSE_CANONICAL_NATIVE_LOG_INVALID',
109
+ PLAN_INVALID: 'PULSE_CANONICAL_NATIVE_PLAN_INVALID'
110
+ });
111
+
112
+ const CANONICAL_NATIVE_PLAN_POLICY = Object.freeze({
113
+ version: CANONICAL_NATIVE_PLAN_VERSION,
114
+ ownershipVersion: CANONICAL_NATIVE_PLAN_OWNERSHIP_VERSION,
115
+ providerNeutral: true,
116
+ providerSelected: false,
117
+ providerSdkUserland: false,
118
+ javascriptRuntime: false,
119
+ promiseSemantics: false,
120
+ asyncify: false,
121
+ controlFlow: 'structured straight-line statements plus if/else branches',
122
+ suspension: 'explicit effect and effect-group statements with stable continuation IDs',
123
+ values: 'versioned JSON expression tree with stable local identities',
124
+ logging: 'compile-time threshold pruning plus synchronous provider-adapter emission',
125
+ schemas: 'canonical compiled schema registry and explicit schema references',
126
+ crypto: 'explicit preselected realization plan; guest source remains package-owned and fallback-free',
127
+ packages: 'trusted package-owned canonical effects and pure intrinsic records only'
128
+ });
129
+
130
+ module.exports = Object.freeze({
131
+ CANONICAL_NATIVE_PLAN_VERSION,
132
+ CANONICAL_NATIVE_PLAN_HASH_ALGORITHM,
133
+ CANONICAL_NATIVE_PLAN_OWNERSHIP_VERSION,
134
+ CANONICAL_NATIVE_STATEMENT_KINDS,
135
+ CANONICAL_NATIVE_EXPRESSION_KINDS,
136
+ CANONICAL_NATIVE_CONTEXT_READS,
137
+ CANONICAL_NATIVE_INTRINSICS,
138
+ CANONICAL_NATIVE_DECODER_KINDS,
139
+ CANONICAL_NATIVE_RESULT_MODES,
140
+ CANONICAL_NATIVE_VALUE_KINDS,
141
+ CANONICAL_NATIVE_PLAN_DIAGNOSTIC_CODES,
142
+ CANONICAL_NATIVE_PLAN_POLICY
143
+ });
@@ -0,0 +1,168 @@
1
+ 'use strict';
2
+
3
+ const CANONICAL_NATIVE_WASM_VERSION = 'pulse.canonical-native-wasm.v2';
4
+ const CANONICAL_NATIVE_ABI_VERSION = 2;
5
+ const CANONICAL_NATIVE_AS_GENERATOR_VERSION = 'pulse.canonical-native-as-generator.v3';
6
+ const CANONICAL_NATIVE_COMPILER_VERSION = 'pulse.canonical-native-wasm-compiler.v3';
7
+ const CANONICAL_NATIVE_HOST_VERSION = 'pulse.canonical-native-host.v3';
8
+
9
+ const CANONICAL_NATIVE_RUN_STATUS = Object.freeze({
10
+ COMPLETE: 0,
11
+ SUSPENDED: 1,
12
+ FAILED: -1,
13
+ INVALID_RESUME: -2
14
+ });
15
+
16
+ const CANONICAL_NATIVE_RESULT_STATUS = Object.freeze({
17
+ REJECTED: 0,
18
+ ACCEPTED: 1
19
+ });
20
+
21
+ const CANONICAL_NATIVE_ERROR_CODES = Object.freeze({
22
+ NONE: 0,
23
+ INVALID_START: 1,
24
+ INCOMPLETE_RESUME: 2,
25
+ INVALID_EFFECT_RESULT: 3,
26
+ FALLTHROUGH_WITHOUT_RESULT: 4,
27
+ HOST_FAILURE: 5,
28
+ INVALID_PROGRAM_COUNTER: 6
29
+ });
30
+
31
+ const CANONICAL_NATIVE_BINARY_OPERATORS = Object.freeze([
32
+ '===', '!==', '==', '!=', '<', '<=', '>', '>=', '+', '-', '*', '/', '%', '**',
33
+ '&&', '||', '??', '&', '|', '^', '<<', '>>', '>>>', 'in'
34
+ ]);
35
+
36
+ const CANONICAL_NATIVE_UNARY_OPERATORS = Object.freeze([
37
+ '!', '+', '-', '~', 'typeof', 'void'
38
+ ]);
39
+
40
+ const CANONICAL_NATIVE_ASSIGNMENT_OPERATORS = Object.freeze([
41
+ '=', '+=', '-=', '*=', '/=', '%=', '**=', '&&=', '||=', '??=', '&=', '|=', '^=', '<<=', '>>=', '>>>='
42
+ ]);
43
+
44
+ const CANONICAL_NATIVE_IMPORT_MODULE = 'pulse_host';
45
+ const CANONICAL_NATIVE_ALLOWED_ENV_IMPORTS = Object.freeze(['abort', 'seed']);
46
+ const CANONICAL_NATIVE_IMPORTS = Object.freeze([
47
+ ['value_undefined', [], ['i32']],
48
+ ['value_null', [], ['i32']],
49
+ ['value_boolean', ['i32'], ['i32']],
50
+ ['value_number', ['f64'], ['i32']],
51
+ ['value_string', ['i32', 'i32'], ['i32']],
52
+ ['value_array', [], ['i32']],
53
+ ['value_array_push', ['i32', 'i32'], []],
54
+ ['value_array_spread', ['i32', 'i32'], []],
55
+ ['value_object', [], ['i32']],
56
+ ['value_object_set', ['i32', 'i32', 'i32'], []],
57
+ ['value_object_spread', ['i32', 'i32'], []],
58
+ ['value_property', ['i32', 'i32'], ['i32']],
59
+ ['value_property_set', ['i32', 'i32', 'i32'], ['i32']],
60
+ ['value_element', ['i32', 'i32'], ['i32']],
61
+ ['value_element_set', ['i32', 'i32', 'i32'], ['i32']],
62
+ ['value_binary', ['i32', 'i32', 'i32'], ['i32']],
63
+ ['value_unary', ['i32', 'i32'], ['i32']],
64
+ ['value_truthy', ['i32'], ['i32']],
65
+ ['value_nullish', ['i32'], ['i32']],
66
+ ['log', ['i32', 'i32'], []],
67
+ ['request_method', [], ['i32']],
68
+ ['request_url', [], ['i32']],
69
+ ['request_path', [], ['i32']],
70
+ ['request_headers', [], ['i32']],
71
+ ['request_header', ['i32'], ['i32']],
72
+ ['request_text', [], ['i32']],
73
+ ['request_json', ['i32'], ['i32']],
74
+ ['router_match', ['i32', 'i32'], ['i32']],
75
+ ['router_param', ['i32', 'i32', 'i32'], ['i32']],
76
+ ['response_json', ['i32', 'i32'], ['i32']],
77
+ ['response_text', ['i32', 'i32'], ['i32']],
78
+ ['response_custom', ['i32'], ['i32']],
79
+ ['grip_is_websocket', [], ['i32']],
80
+ ['grip_subscribe', ['i32', 'i32'], ['i32']],
81
+ ['grip_handoff', ['i32'], ['i32']],
82
+ ['kv_namespace', ['i32'], ['i32']],
83
+ ['fetch_json', ['i32', 'i32'], ['i32']],
84
+ ['fetch_text', ['i32'], ['i32']],
85
+ ['fetch_header', ['i32', 'i32'], ['i32']],
86
+ ['effect_begin', ['i32', 'i32'], []]
87
+ ]);
88
+
89
+ const CANONICAL_NATIVE_EXPORTS = Object.freeze([
90
+ ['memory', 'memory'],
91
+ ['pulse_abi_version', [], ['i32']],
92
+ ['pulse_plan_hash_ptr', [], ['i32']],
93
+ ['pulse_plan_hash_length', [], ['i32']],
94
+ ['pulse_start', [], ['i32']],
95
+ ['pulse_resume', [], ['i32']],
96
+ ['pulse_set_effect_result', ['i32', 'i32'], ['i32']],
97
+ ['pulse_result_handle', [], ['i32']],
98
+ ['pulse_program_counter', [], ['i32']],
99
+ ['pulse_continuation_state', [], ['i32']],
100
+ ['pulse_last_error_code', [], ['i32']],
101
+ ['pulse_pending_count', [], ['i32']]
102
+ ]);
103
+
104
+ const CANONICAL_NATIVE_SCHEMA_EXPORTS = Object.freeze([
105
+ ['__new', ['i32', 'i32'], ['i32']],
106
+ ['__pin', ['i32'], ['i32']],
107
+ ['__unpin', ['i32'], []],
108
+ ['pulse_schema_string_id', [], ['i32']],
109
+ ['pulse_schema_decode', ['i32', 'i32'], ['i32']],
110
+ ['pulse_schema_encode', ['i32', 'i32'], ['i32']]
111
+ ]);
112
+
113
+ const CANONICAL_NATIVE_IMPORT_NAMES = Object.freeze(CANONICAL_NATIVE_IMPORTS.map(([name]) => name));
114
+ const CANONICAL_NATIVE_EXPORT_NAMES = Object.freeze(CANONICAL_NATIVE_EXPORTS.map(([name]) => name));
115
+ const CANONICAL_NATIVE_SCHEMA_EXPORT_NAMES = Object.freeze(CANONICAL_NATIVE_SCHEMA_EXPORTS.map(([name]) => name));
116
+
117
+ const CANONICAL_NATIVE_DIAGNOSTIC_CODES = Object.freeze({
118
+ PLAN_REQUIRED: 'PULSE_CANONICAL_NATIVE_WASM_PLAN_REQUIRED',
119
+ PLAN_INVALID: 'PULSE_CANONICAL_NATIVE_WASM_PLAN_INVALID',
120
+ STATEMENT_UNSUPPORTED: 'PULSE_CANONICAL_NATIVE_WASM_STATEMENT_UNSUPPORTED',
121
+ EXPRESSION_UNSUPPORTED: 'PULSE_CANONICAL_NATIVE_WASM_EXPRESSION_UNSUPPORTED',
122
+ LOCAL_UNRESOLVED: 'PULSE_CANONICAL_NATIVE_WASM_LOCAL_UNRESOLVED',
123
+ EFFECT_UNRESOLVED: 'PULSE_CANONICAL_NATIVE_WASM_EFFECT_UNRESOLVED',
124
+ ASSEMBLYSCRIPT_MISSING: 'PULSE_CANONICAL_NATIVE_WASM_ASC_MISSING',
125
+ ASSEMBLYSCRIPT_FAILED: 'PULSE_CANONICAL_NATIVE_WASM_ASC_FAILED',
126
+ WASM_INVALID: 'PULSE_CANONICAL_NATIVE_WASM_INVALID',
127
+ ABI_INVALID: 'PULSE_CANONICAL_NATIVE_WASM_ABI_INVALID'
128
+ });
129
+
130
+ const CANONICAL_NATIVE_POLICY = Object.freeze({
131
+ providerNeutral: true,
132
+ providerSelected: false,
133
+ javascriptRuntime: false,
134
+ asyncify: false,
135
+ promiseSemantics: false,
136
+ valueOwnership: 'host-owned opaque i32 handles; generated Wasm owns control flow and local identities',
137
+ controlFlow: 'generated AssemblyScript state machine with stable basic blocks',
138
+ suspension: 'effect_begin records descriptors before one explicit suspension boundary; results are injected before pulse_resume',
139
+ groupedEffects: 'all group members begin before one suspension boundary and all results must be ready before resume',
140
+ incompleteResume: 'rejected without advancing the program counter or consuming available results',
141
+ authority: 'request data and consequential effects remain host-owned; guest control flow remains authoritative',
142
+ schemaJson: 'normalized registry IR generates json-as 1.5.0 guest codecs; host preflight enforces shared policy and structured errors',
143
+ schemaBodyOwnership: 'request and fetched-response bytes are snapshotted once; application JSON values are encoded before suspension'
144
+ });
145
+
146
+ module.exports = Object.freeze({
147
+ CANONICAL_NATIVE_WASM_VERSION,
148
+ CANONICAL_NATIVE_ABI_VERSION,
149
+ CANONICAL_NATIVE_AS_GENERATOR_VERSION,
150
+ CANONICAL_NATIVE_COMPILER_VERSION,
151
+ CANONICAL_NATIVE_HOST_VERSION,
152
+ CANONICAL_NATIVE_RUN_STATUS,
153
+ CANONICAL_NATIVE_RESULT_STATUS,
154
+ CANONICAL_NATIVE_ERROR_CODES,
155
+ CANONICAL_NATIVE_BINARY_OPERATORS,
156
+ CANONICAL_NATIVE_UNARY_OPERATORS,
157
+ CANONICAL_NATIVE_ASSIGNMENT_OPERATORS,
158
+ CANONICAL_NATIVE_IMPORT_MODULE,
159
+ CANONICAL_NATIVE_ALLOWED_ENV_IMPORTS,
160
+ CANONICAL_NATIVE_IMPORTS,
161
+ CANONICAL_NATIVE_IMPORT_NAMES,
162
+ CANONICAL_NATIVE_EXPORTS,
163
+ CANONICAL_NATIVE_EXPORT_NAMES,
164
+ CANONICAL_NATIVE_SCHEMA_EXPORTS,
165
+ CANONICAL_NATIVE_SCHEMA_EXPORT_NAMES,
166
+ CANONICAL_NATIVE_DIAGNOSTIC_CODES,
167
+ CANONICAL_NATIVE_POLICY
168
+ });
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const CANONICAL_PROGRAM_VERSION = 'pulse.canonical-program.v2';
4
+ const CANONICAL_RUNTIME_PROTOCOL_VERSION = 'pulse.canonical-runtime-protocol.v2';
5
+ const CANONICAL_EFFECT_MARKER_KINDS = Object.freeze(['effect', 'group']);
6
+ const CANONICAL_PACKAGE_EFFECT_VERSION = 'pulse.canonical-package-effect.v1';
7
+
8
+ module.exports = Object.freeze({
9
+ CANONICAL_PROGRAM_VERSION,
10
+ CANONICAL_RUNTIME_PROTOCOL_VERSION,
11
+ CANONICAL_EFFECT_MARKER_KINDS,
12
+ CANONICAL_PACKAGE_EFFECT_VERSION
13
+ });
@@ -0,0 +1,131 @@
1
+ 'use strict';
2
+
3
+ const ROUTE_HANDLER_CONTEXT_LOWERING_VERSION = 'pulsewasm.route-handler-context-lowering.v1';
4
+ const ROUTE_HANDLER_CONTEXT_LOWERING_PHASE = '31';
5
+ const ROUTE_HANDLER_CONTEXT_LOWERING_ARTIFACT = 'route-handler-context-lowering-plan.json';
6
+ const ROUTE_HANDLER_CONTEXT_CONTRACT_ID = 'pulse.route-handler-context';
7
+
8
+ const ROUTE_HANDLER_CONTEXT_PLAN_SCOPE = Object.freeze({
9
+ syncContextLowering: true,
10
+ runtimeBehaviorChanged: true,
11
+ providerBehaviorImplemented: false,
12
+ effectExecutionImplemented: false,
13
+ asyncAwait: false,
14
+ promises: false,
15
+ asyncify: false,
16
+ closureCapture: false
17
+ });
18
+
19
+ const ROUTE_HANDLER_CONTEXT_SYNC_SURFACE = Object.freeze([
20
+ 'ctx.param',
21
+ 'ctx.paramI32',
22
+ 'ctx.request.method',
23
+ 'ctx.request.path',
24
+ 'ctx.state.get',
25
+ 'ctx.state.set',
26
+ 'ctx.request.header.first',
27
+ 'ctx.request.header.count',
28
+ 'ctx.request.header.at',
29
+ 'ctx.response.header.set',
30
+ 'ctx.response.header.append',
31
+ 'ctx.response.header.delete',
32
+ 'ctx.result.text',
33
+ 'ctx.result.jsonText',
34
+ 'ctx.result.empty',
35
+ 'ctx.error',
36
+ 'next',
37
+ 'next(error)'
38
+ ]);
39
+
40
+ const ROUTE_HANDLER_CONTEXT_RESERVED_SURFACE = Object.freeze([
41
+ 'ctx.fetch',
42
+ 'ctx.resolve',
43
+ 'ctx.resolved',
44
+ 'ctx.bodyText',
45
+ 'ctx.request.body',
46
+ 'ctx.request.json',
47
+ 'ctx.request.arrayBuffer',
48
+ 'global fetch',
49
+ 'Promise',
50
+ 'async/await'
51
+ ]);
52
+
53
+ const ROUTE_HANDLER_CONTEXT_EXPRESSION_SUBSET = Object.freeze({
54
+ literals: Object.freeze(['string', 'number', 'boolean']),
55
+ identifiers: 'locals declared in the same handler body',
56
+ binaryOperators: Object.freeze(['+', '-', '*', '/', '%', '===', '!==', '==', '!=', '<', '<=', '>', '>=', '&&', '||']),
57
+ unaryOperators: Object.freeze(['!']),
58
+ branches: 'if/else is lowerable when branches remain within the same synchronous context surface',
59
+ rejected: Object.freeze([
60
+ 'loops',
61
+ 'switch',
62
+ 'try/catch/throw',
63
+ 'classes/new',
64
+ 'destructuring',
65
+ 'spread/rest',
66
+ 'computed property access',
67
+ 'dynamic ctx member access',
68
+ 'inline closure capture',
69
+ 'nested functions',
70
+ 'recursion',
71
+ 'Promise',
72
+ 'async/await',
73
+ 'ctx.resolve runtime execution'
74
+ ])
75
+ });
76
+
77
+ const ROUTE_HANDLER_CONTEXT_DIAGNOSTICS = Object.freeze({
78
+ handlerSourceMissing: 'PULSEWASM_CONTEXT_HANDLER_SOURCE_MISSING',
79
+ parameterUnsupported: 'PULSEWASM_CONTEXT_PARAMETER_UNSUPPORTED',
80
+ captureUnsupported: 'PULSEWASM_CONTEXT_CAPTURE_UNSUPPORTED',
81
+ destructuringUnsupported: 'PULSEWASM_CONTEXT_DESTRUCTURING_UNSUPPORTED',
82
+ loopUnsupported: 'PULSEWASM_CONTEXT_LOOP_UNSUPPORTED',
83
+ asyncUnsupported: 'PULSEWASM_CONTEXT_ASYNC_UNSUPPORTED',
84
+ promiseUnsupported: 'PULSEWASM_CONTEXT_PROMISE_UNSUPPORTED',
85
+ throwUnsupported: 'PULSEWASM_CONTEXT_THROW_UNSUPPORTED',
86
+ classUnsupported: 'PULSEWASM_CONTEXT_CLASS_UNSUPPORTED',
87
+ computedPropertyUnsupported: 'PULSEWASM_CONTEXT_COMPUTED_PROPERTY_UNSUPPORTED',
88
+ unsupportedStatement: 'PULSEWASM_CONTEXT_UNSUPPORTED_STATEMENT',
89
+ unsupportedExpression: 'PULSEWASM_CONTEXT_UNSUPPORTED_EXPRESSION',
90
+ unsupportedCall: 'PULSEWASM_CONTEXT_UNSUPPORTED_CALL',
91
+ unsupportedContextSurface: 'PULSEWASM_CONTEXT_UNSUPPORTED_SURFACE',
92
+ effectBoundaryReserved: 'PULSEWASM_CONTEXT_EFFECT_BOUNDARY_RESERVED',
93
+ effectUnsupported: 'PULSEWASM_CONTEXT_EFFECT_UNSUPPORTED',
94
+ resultTerminalConflict: 'PULSEWASM_CONTEXT_TERMINAL_CONFLICT',
95
+ ifBranchUnsupported: 'PULSEWASM_CONTEXT_IF_BRANCH_UNSUPPORTED'
96
+ });
97
+
98
+ function defaultRouteHandlerContextLoweringPolicy() {
99
+ return {
100
+ ...ROUTE_HANDLER_CONTEXT_PLAN_SCOPE,
101
+ contractId: ROUTE_HANDLER_CONTEXT_CONTRACT_ID,
102
+ artifact: ROUTE_HANDLER_CONTEXT_LOWERING_ARTIFACT,
103
+ syncSurface: [...ROUTE_HANDLER_CONTEXT_SYNC_SURFACE],
104
+ reservedSurface: [...ROUTE_HANDLER_CONTEXT_RESERVED_SURFACE],
105
+ expressionSubset: JSON.parse(JSON.stringify(ROUTE_HANDLER_CONTEXT_EXPRESSION_SUBSET)),
106
+ lifecycle: {
107
+ handlerRunsSynchronously: true,
108
+ effectBoundaryReserved: true,
109
+ providerExecution: false,
110
+ wasmSuspension: false,
111
+ continuationReentry: 'ctx.resolve plan only; not implemented by Pass 31'
112
+ }
113
+ };
114
+ }
115
+
116
+ module.exports = {
117
+ ROUTE_HANDLER_CONTEXT_LOWERING_VERSION,
118
+ ROUTE_HANDLER_CONTEXT_PLAN_VERSION: ROUTE_HANDLER_CONTEXT_LOWERING_VERSION,
119
+ ROUTE_HANDLER_CONTEXT_LOWERING_PHASE,
120
+ ROUTE_HANDLER_CONTEXT_PLAN_PHASE: ROUTE_HANDLER_CONTEXT_LOWERING_PHASE,
121
+ ROUTE_HANDLER_CONTEXT_LOWERING_ARTIFACT,
122
+ ROUTE_HANDLER_CONTEXT_PLAN_ARTIFACT: ROUTE_HANDLER_CONTEXT_LOWERING_ARTIFACT,
123
+ ROUTE_HANDLER_CONTEXT_CONTRACT_ID,
124
+ ROUTE_HANDLER_CONTEXT_PLAN_SCOPE,
125
+ ROUTE_HANDLER_CONTEXT_SYNC_SURFACE,
126
+ ROUTE_HANDLER_CONTEXT_RESERVED_SURFACE,
127
+ ROUTE_HANDLER_CONTEXT_EXPRESSION_SUBSET,
128
+ ROUTE_HANDLER_CONTEXT_DIAGNOSTICS,
129
+ defaultRouteHandlerContextLoweringPolicy,
130
+ defaultRouteHandlerContextPolicy: defaultRouteHandlerContextLoweringPolicy
131
+ };
@@ -0,0 +1,71 @@
1
+ 'use strict';
2
+
3
+ const { HANDLER_SURFACE_DEFINITIONS, HANDLER_SURFACE_CONTRACT_VERSION } = require('./surface-contract.js');
4
+
5
+ const CTX_CONTRACT_VERSION = 'pulse.ctx-contract.v4';
6
+ const CTX_CONTRACT_ID = 'pulse.ctx';
7
+ const CTX_SURFACE_IDS = Object.freeze([
8
+ 'ctx.param','ctx.req.method','ctx.req.url','ctx.req.path','ctx.req.header','ctx.req.headers',
9
+ 'ctx.state.get','ctx.state.set','ctx.json','ctx.text','ctx.response','ctx.req.text','ctx.req.json.schema',
10
+ 'ctx.req.json.generic','ctx.fetch.projected','ctx.fetch.opaque-return','ctx.config.get','ctx.secret.get',
11
+ 'ctx.kv.get','ctx.kv.put','ctx.kv.getVersioned','ctx.kv.insertIfAbsent','ctx.kv.compareAndSwap','ctx.emit','package.operation'
12
+ ]);
13
+ const surfaceById = new Map(HANDLER_SURFACE_DEFINITIONS.map((entry) => [entry.id, entry]));
14
+ const CTX_SURFACES = Object.freeze(CTX_SURFACE_IDS.map((id) => {
15
+ const surface = surfaceById.get(id);
16
+ if (!surface) throw new TypeError(`Missing handler-surface definition for ctx contract entry ${id}.`);
17
+ return Object.freeze({
18
+ id: surface.id,
19
+ class: surface.class,
20
+ canonicalOperation: surface.canonicalOperation,
21
+ awaitPolicy: surface.awaitPolicy,
22
+ publicForms: surface.publicForms,
23
+ nativeEligible: surface.targetSupport.native,
24
+ javascriptSupported: surface.targetSupport.javascript,
25
+ schemaPolicy: surface.schemaPolicy || null,
26
+ redaction: surface.redaction || null
27
+ });
28
+ }));
29
+ function defaultCtxContract() {
30
+ return Object.freeze({
31
+ version: CTX_CONTRACT_VERSION,
32
+ contractId: CTX_CONTRACT_ID,
33
+ handlerSurfaceVersion: HANDLER_SURFACE_CONTRACT_VERSION,
34
+ surfaces: CTX_SURFACES,
35
+ planes: Object.freeze({
36
+ sharedAuthoring: Object.freeze(['state', 'log', 'fetch', 'parallel', 'config', 'secret', 'kv', 'emit']),
37
+ httpAuthoring: Object.freeze(['req', 'json', 'text', 'response']),
38
+ routeAuthoring: Object.freeze(['param']),
39
+ eventAuthoring: Object.freeze(['event.type', 'event.payload']),
40
+ eventExecutionImplemented: true,
41
+ emitPublished: true,
42
+ emitJavascriptExecutionImplemented: true,
43
+ emitNativeExecutionImplemented: false
44
+ }),
45
+ policies: Object.freeze({
46
+ handlersAsyncShaped: true,
47
+ syncAwaitIsWarning: true,
48
+ effectAwaitRequiredWhenConsumed: true,
49
+ terminalNextAwaitForbidden: true,
50
+ stateRepresentation: 'execution-local-string-map',
51
+ stateMissingValue: 'undefined',
52
+ stateClearedPerRequest: true,
53
+ stateClearedPerExecution: true,
54
+ nativePromiseRuntime: false,
55
+ nativeAsyncify: false,
56
+ packageCapabilitiesManifestClassified: true
57
+ })
58
+ });
59
+ }
60
+ function validateCtxContract(contract = defaultCtxContract()) {
61
+ if (contract.version !== CTX_CONTRACT_VERSION) throw new TypeError(`Unsupported ctx contract version ${contract.version}.`);
62
+ const ids = new Set();
63
+ for (const surface of contract.surfaces) {
64
+ if (ids.has(surface.id)) throw new TypeError(`Duplicate ctx surface ${surface.id}.`);
65
+ ids.add(surface.id);
66
+ }
67
+ if (ids.size !== CTX_SURFACE_IDS.length) throw new TypeError('ctx contract surface count does not match its sealed ID list.');
68
+ if (contract.policies.nativePromiseRuntime !== false || contract.policies.nativeAsyncify !== false) throw new TypeError('Native ctx lowering must remain Promise-free and Asyncify-free.');
69
+ return contract;
70
+ }
71
+ module.exports = Object.freeze({ CTX_CONTRACT_VERSION, CTX_CONTRACT_ID, CTX_SURFACE_IDS, CTX_SURFACES, defaultCtxContract, validateCtxContract });