@pulse-compute/wasm-compiler 0.0.0 → 1.0.0-beta.1

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 (104) hide show
  1. package/README.md +52 -1
  2. package/bin/provider-proof-composition.js +34 -0
  3. package/bin/pulsewasm-extract.js +20 -0
  4. package/package.json +60 -5
  5. package/src/artifacts-dir.js +13 -0
  6. package/src/ast-json.js +52 -0
  7. package/src/build-manifest.js +354 -0
  8. package/src/canonical-api-compiler.js +245 -0
  9. package/src/canonical-native-compiler.js +411 -0
  10. package/src/canonical-native-plan.js +1477 -0
  11. package/src/canonical-project-compiler.js +1218 -0
  12. package/src/canonical-router-compiler.js +25 -0
  13. package/src/cli-intents.js +1235 -0
  14. package/src/cli.js +1927 -0
  15. package/src/codegen/assemblyscript-compile.js +3 -0
  16. package/src/codegen/assemblyscript-core.js +3 -0
  17. package/src/codegen/assemblyscript-shape.js +3 -0
  18. package/src/codegen/assemblyscript-wasm-smoke.js +3 -0
  19. package/src/codegen/backend-capabilities.js +3 -0
  20. package/src/codegen/channel-broadcaster.js +3 -0
  21. package/src/codegen/compiled-handlers.js +3 -0
  22. package/src/codegen/compiled-wasm-runtime.js +3 -0
  23. package/src/codegen/config-references.js +248 -0
  24. package/src/codegen/dispatch-ts.js +145 -0
  25. package/src/codegen/effect-composition.js +331 -0
  26. package/src/codegen/effect-runtime.js +418 -0
  27. package/src/codegen/execution-harness-ts.js +467 -0
  28. package/src/codegen/handler-bindings-ts.js +298 -0
  29. package/src/codegen/handler-library-contracts.js +3 -0
  30. package/src/codegen/host-capabilities.js +3 -0
  31. package/src/codegen/host-runtime-kernel.js +3 -0
  32. package/src/codegen/integrated-compiled-app.js +3 -0
  33. package/src/codegen/json-body.js +3 -0
  34. package/src/codegen/library-sidecars.js +3 -0
  35. package/src/codegen/local-harness-ts.js +453 -0
  36. package/src/codegen/pulse-wrapper.js +217 -0
  37. package/src/codegen/request-result-headers.js +3 -0
  38. package/src/codegen/schema-json-compile.js +3 -0
  39. package/src/codegen/schema-json-sidecar-v2.js +3 -0
  40. package/src/codegen/schema-json-sidecar.js +3 -0
  41. package/src/codegen/streaming-passthrough.js +3 -0
  42. package/src/codegen/wasm-host-abi.js +3 -0
  43. package/src/codegen/wasm-host-bridge.js +3 -0
  44. package/src/compiled-wasm-host-runtime-kv.js +3 -0
  45. package/src/config-resolver.js +813 -0
  46. package/src/crypto-requirement-planner.js +89 -0
  47. package/src/definitions/config-schema.js +14 -0
  48. package/src/definitions/handler-roles.js +14 -0
  49. package/src/definitions/path-grammar.js +14 -0
  50. package/src/definitions/router-api.js +14 -0
  51. package/src/diagnostics/codes.js +14 -0
  52. package/src/diagnostics/reporter.js +14 -0
  53. package/src/diagnostics.js +14 -0
  54. package/src/dispatch-table.js +400 -0
  55. package/src/events/event-emit.js +265 -0
  56. package/src/events/event-topology.js +127 -0
  57. package/src/execution-plan.js +463 -0
  58. package/src/extractor.js +2816 -0
  59. package/src/handler-eval.js +1154 -0
  60. package/src/handler-table.js +326 -0
  61. package/src/index.js +19 -0
  62. package/src/javascript-application-plan.js +181 -0
  63. package/src/kv-provider.js +3 -0
  64. package/src/path-table.js +60 -0
  65. package/src/path.js +14 -0
  66. package/src/patterns/config-define.js +30 -0
  67. package/src/patterns/dependency-call.js +18 -0
  68. package/src/patterns/env-lookup.js +13 -0
  69. package/src/patterns/handler-reference.js +29 -0
  70. package/src/patterns/path-literal.js +35 -0
  71. package/src/patterns/result.js +15 -0
  72. package/src/patterns/router-chain-call.js +50 -0
  73. package/src/patterns/router-construction.js +19 -0
  74. package/src/project/package-reachability.js +782 -0
  75. package/src/project/reachable-graph-builder.js +992 -0
  76. package/src/project/reachable-graph-contract.js +54 -0
  77. package/src/project/reachable-graph-implementation.js +36 -0
  78. package/src/project/router-module-linker.js +710 -0
  79. package/src/project-config-compiler.js +222 -0
  80. package/src/project-target-support.js +500 -0
  81. package/src/provider-toolchain.js +299 -0
  82. package/src/spine/async-surface-normalizer.js +312 -0
  83. package/src/spine/canonical-handler-ir.js +335 -0
  84. package/src/spine/canonical-native-module.js +87 -0
  85. package/src/spine/canonical-native-plan.js +89 -0
  86. package/src/spine/canonical-project.js +76 -0
  87. package/src/spine/canonical-router.js +155 -0
  88. package/src/spine/canonical-source.js +165 -0
  89. package/src/spine/diagnostic-authority.js +290 -0
  90. package/src/spine/equivalence.js +262 -0
  91. package/src/spine/guest-unit-stage.js +87 -0
  92. package/src/spine/handler-ir-emitter.js +454 -0
  93. package/src/spine/handler-ir-managed.js +1597 -0
  94. package/src/spine/handler-ir.js +797 -0
  95. package/src/spine/handler-surface-authority.js +585 -0
  96. package/src/spine/package-operation-seam.js +1015 -0
  97. package/src/spine/pipeline.js +202 -0
  98. package/src/spine/plain-handler-frontend.js +537 -0
  99. package/src/spine/provider-requirement-authority.js +208 -0
  100. package/src/spine/router-control-contract.js +17 -0
  101. package/src/spine/router-handler-frontend.js +513 -0
  102. package/src/spine/router-handler-ir.js +372 -0
  103. package/src/spine/router-topology-frontend.js +635 -0
  104. package/src/stable-id.js +14 -0
@@ -0,0 +1,262 @@
1
+ 'use strict';
2
+
3
+ const crypto = require('node:crypto');
4
+ const path = require('node:path');
5
+
6
+ const PORTABLE_EQUIVALENCE_VERSION = 'pulse.compiler-equivalence-portable.v1';
7
+ const PORTABLE_PROJECT_ROOT = '$PROJECT_ROOT';
8
+ const PORTABLE_PROJECT_SOURCE_HASH = '$PROJECT_SOURCE_HASH';
9
+ const PORTABLE_PLAN_HASH = '$PLAN_HASH';
10
+
11
+ function sha256(value) {
12
+ return crypto.createHash('sha256').update(value).digest('hex');
13
+ }
14
+
15
+ function stableObject(value) {
16
+ if (Array.isArray(value)) return value.map(stableObject);
17
+ if (!value || typeof value !== 'object') return value;
18
+ const out = {};
19
+ for (const key of Object.keys(value).sort()) {
20
+ if (value[key] !== undefined) out[key] = stableObject(value[key]);
21
+ }
22
+ return out;
23
+ }
24
+
25
+ function stableJson(value) {
26
+ const encoded = JSON.stringify(stableObject(value));
27
+ return encoded === undefined ? 'undefined' : encoded;
28
+ }
29
+
30
+ function hashJson(value) {
31
+ return sha256(stableJson(value));
32
+ }
33
+
34
+ function compiledProjectFingerprint(compiled) {
35
+ const router = compiled.router ? {
36
+ version: compiled.router.version,
37
+ authoringVersion: compiled.router.authoringVersion,
38
+ fileName: compiled.router.fileName,
39
+ rootRouter: compiled.router.rootRouter,
40
+ sourceText: compiled.router.sourceText,
41
+ compilerPrelude: compiled.router.compilerPrelude,
42
+ compilerOwnedCalls: compiled.router.compilerOwnedCalls,
43
+ routePlan: compiled.router.routePlan,
44
+ handlerTable: compiled.router.handlerTable,
45
+ routerTree: compiled.router.routerTree,
46
+ executionPlan: compiled.router.executionPlan,
47
+ metadata: compiled.router.metadata,
48
+ diagnostics: compiled.router.diagnostics
49
+ } : null;
50
+ const schema = {
51
+ active: compiled.schema.active,
52
+ bundle: compiled.schema.bundle,
53
+ diagnostics: compiled.schema.diagnostics,
54
+ warnings: compiled.schema.warnings,
55
+ compiledSchemas: compiled.schema.compiledSchemas,
56
+ compilerVersion: compiled.schema.compilerVersion,
57
+ summary: compiled.schema.summary
58
+ };
59
+ const packageExtensions = {
60
+ active: compiled.packageExtensions.active,
61
+ allowedRuntimeImports: compiled.packageExtensions.allowedRuntimeImports,
62
+ effects: compiled.packageExtensions.effects,
63
+ plans: compiled.packageExtensions.plans,
64
+ diagnostics: compiled.packageExtensions.diagnostics
65
+ };
66
+ return Object.freeze({
67
+ version: compiled.version,
68
+ projectCompilerVersion: compiled.projectCompilerVersion,
69
+ metadataSha256: hashJson(compiled.metadata),
70
+ schemaBundleSha256: hashJson(compiled.schemaBundle),
71
+ generatedSourceSha256: sha256(compiled.generatedSource),
72
+ generatedEsmSourceSha256: sha256(compiled.generatedEsmSource),
73
+ diagnosticsSha256: hashJson(compiled.diagnostics),
74
+ routerSha256: hashJson(router),
75
+ schemaSha256: hashJson(schema),
76
+ packageExtensionsSha256: hashJson(packageExtensions),
77
+ summary: Object.freeze({
78
+ authoringKind: compiled.metadata.authoring && compiled.metadata.authoring.kind || 'plain-handler',
79
+ effectCount: compiled.metadata.effectCount,
80
+ continuationCount: compiled.metadata.continuationCount,
81
+ schemaReferenceCount: compiled.metadata.schemaReferenceCount,
82
+ packageEffectCount: compiled.metadata.packageEffectCount,
83
+ routeCount: compiled.metadata.router && compiled.metadata.router.routes ? compiled.metadata.router.routes.length : 0,
84
+ routerEntryCount: compiled.metadata.router && compiled.metadata.router.entries ? compiled.metadata.router.entries.length : 0
85
+ })
86
+ });
87
+ }
88
+
89
+ function normalizePortablePath(value, projectRoot) {
90
+ if (typeof value !== 'string' || !projectRoot || !path.isAbsolute(value)) return value;
91
+ const root = path.resolve(projectRoot);
92
+ const candidate = path.resolve(value);
93
+ const relative = path.relative(root, candidate);
94
+ if (relative === '') return PORTABLE_PROJECT_ROOT;
95
+ if (relative.startsWith(`..${path.sep}`) || relative === '..' || path.isAbsolute(relative)) return value;
96
+ return `${PORTABLE_PROJECT_ROOT}/${relative.split(path.sep).join('/')}`;
97
+ }
98
+
99
+ function normalizePortableValue(value, options = {}, key = '') {
100
+ if (Array.isArray(value)) return value.map((entry) => normalizePortableValue(entry, options));
101
+ if (!value || typeof value !== 'object') {
102
+ if (key === 'projectSourceHash') return PORTABLE_PROJECT_SOURCE_HASH;
103
+ if (key === 'planHash') return PORTABLE_PLAN_HASH;
104
+ return normalizePortablePath(value, options.projectRoot);
105
+ }
106
+ const out = {};
107
+ for (const property of Object.keys(value)) {
108
+ if (value[property] === undefined) continue;
109
+ out[property] = normalizePortableValue(value[property], options, property);
110
+ }
111
+ return out;
112
+ }
113
+
114
+ function normalizeGeneratedSource(value, options = {}) {
115
+ let source = String(value).replace(
116
+ /("projectSourceHash"\s*:\s*")[0-9a-f]{64}("\s*[,}])/g,
117
+ `$1${PORTABLE_PROJECT_SOURCE_HASH}$2`
118
+ );
119
+ if (options.projectRoot) {
120
+ const root = path.resolve(options.projectRoot);
121
+ for (const candidate of new Set([root, root.split(path.sep).join('/')])) {
122
+ if (candidate) source = source.split(candidate).join(PORTABLE_PROJECT_ROOT);
123
+ }
124
+ }
125
+ return source;
126
+ }
127
+
128
+ function portableCompiledProjectFingerprint(compiled, options = {}) {
129
+ const router = compiled.router ? {
130
+ version: compiled.router.version,
131
+ authoringVersion: compiled.router.authoringVersion,
132
+ fileName: compiled.router.fileName,
133
+ rootRouter: compiled.router.rootRouter,
134
+ sourceText: compiled.router.sourceText,
135
+ compilerPrelude: compiled.router.compilerPrelude,
136
+ compilerOwnedCalls: compiled.router.compilerOwnedCalls,
137
+ routePlan: compiled.router.routePlan,
138
+ handlerTable: compiled.router.handlerTable,
139
+ routerTree: compiled.router.routerTree,
140
+ executionPlan: compiled.router.executionPlan,
141
+ metadata: compiled.router.metadata,
142
+ diagnostics: compiled.router.diagnostics
143
+ } : null;
144
+ const schema = {
145
+ active: compiled.schema.active,
146
+ bundle: compiled.schema.bundle,
147
+ diagnostics: compiled.schema.diagnostics,
148
+ warnings: compiled.schema.warnings,
149
+ compiledSchemas: compiled.schema.compiledSchemas,
150
+ compilerVersion: compiled.schema.compilerVersion,
151
+ summary: compiled.schema.summary
152
+ };
153
+ const packageExtensions = {
154
+ active: compiled.packageExtensions.active,
155
+ allowedRuntimeImports: compiled.packageExtensions.allowedRuntimeImports,
156
+ effects: compiled.packageExtensions.effects,
157
+ plans: compiled.packageExtensions.plans,
158
+ diagnostics: compiled.packageExtensions.diagnostics
159
+ };
160
+ return Object.freeze({
161
+ normalizationVersion: PORTABLE_EQUIVALENCE_VERSION,
162
+ version: compiled.version,
163
+ projectCompilerVersion: compiled.projectCompilerVersion,
164
+ metadataSha256: hashJson(normalizePortableValue(compiled.metadata, options)),
165
+ schemaBundleSha256: hashJson(normalizePortableValue(compiled.schemaBundle, options)),
166
+ generatedSourceSha256: sha256(normalizeGeneratedSource(compiled.generatedSource, options)),
167
+ generatedEsmSourceSha256: sha256(normalizeGeneratedSource(compiled.generatedEsmSource, options)),
168
+ diagnosticsSha256: hashJson(normalizePortableValue(compiled.diagnostics, options)),
169
+ routerSha256: hashJson(normalizePortableValue(router, options)),
170
+ schemaSha256: hashJson(normalizePortableValue(schema, options)),
171
+ packageExtensionsSha256: hashJson(normalizePortableValue(packageExtensions, options)),
172
+ summary: Object.freeze({
173
+ authoringKind: compiled.metadata.authoring && compiled.metadata.authoring.kind || 'plain-handler',
174
+ effectCount: compiled.metadata.effectCount,
175
+ continuationCount: compiled.metadata.continuationCount,
176
+ schemaReferenceCount: compiled.metadata.schemaReferenceCount,
177
+ packageEffectCount: compiled.metadata.packageEffectCount,
178
+ routeCount: compiled.metadata.router && compiled.metadata.router.routes ? compiled.metadata.router.routes.length : 0,
179
+ routerEntryCount: compiled.metadata.router && compiled.metadata.router.entries ? compiled.metadata.router.entries.length : 0
180
+ })
181
+ });
182
+ }
183
+
184
+ function nativePlanFingerprint(plan, stringify) {
185
+ const json = stringify(plan);
186
+ return Object.freeze({
187
+ version: plan.version,
188
+ compilerVersion: plan.compilerVersion,
189
+ planHash: plan.planHash,
190
+ stableJsonSha256: sha256(json),
191
+ summarySha256: hashJson(plan.summary),
192
+ effectsSha256: hashJson(plan.effects),
193
+ continuationsSha256: hashJson(plan.continuations),
194
+ routingSha256: hashJson(plan.routing)
195
+ });
196
+ }
197
+
198
+ function portableNativePlanFingerprint(plan, options = {}) {
199
+ const normalized = normalizePortableValue(plan, options);
200
+ return Object.freeze({
201
+ normalizationVersion: PORTABLE_EQUIVALENCE_VERSION,
202
+ version: plan.version,
203
+ compilerVersion: plan.compilerVersion,
204
+ stableJsonSha256: hashJson(normalized),
205
+ sourceSha256: hashJson(normalized.source),
206
+ entrySha256: hashJson(normalized.entry),
207
+ summarySha256: hashJson(normalized.summary),
208
+ effectsSha256: hashJson(normalized.effects),
209
+ continuationsSha256: hashJson(normalized.continuations),
210
+ routingSha256: hashJson(normalized.routing),
211
+ packagesSha256: hashJson(normalized.packages)
212
+ });
213
+ }
214
+
215
+ function nativeModuleFingerprint(compiled, options = {}) {
216
+ const omittedManifestKeys = new Set(options.omitManifestKeys || []);
217
+ const manifest = omittedManifestKeys.size === 0
218
+ ? compiled.manifest
219
+ : Object.fromEntries(
220
+ Object.entries(compiled.manifest).filter(([key]) => !omittedManifestKeys.has(key))
221
+ );
222
+ return Object.freeze({
223
+ version: compiled.version,
224
+ compilerVersion: compiled.compilerVersion,
225
+ sourceHash: compiled.sourceHash,
226
+ sourceSha256: sha256(compiled.source),
227
+ wasmSha256: sha256(compiled.wasm),
228
+ watSha256: sha256(compiled.wat),
229
+ inspectionSha256: hashJson(compiled.inspection),
230
+ manifestSha256: hashJson(manifest)
231
+ });
232
+ }
233
+
234
+ function compilationErrorFingerprint(error) {
235
+ return Object.freeze({
236
+ name: error && error.name,
237
+ code: error && error.code,
238
+ diagnosticsSha256: hashJson(error && error.diagnostics || []),
239
+ diagnostics: Object.freeze((error && error.diagnostics || []).map((diagnostic) => Object.freeze({
240
+ code: diagnostic.code,
241
+ severity: diagnostic.severity,
242
+ message: diagnostic.message,
243
+ file: diagnostic.file,
244
+ position: diagnostic.position,
245
+ detail: diagnostic.detail
246
+ })))
247
+ });
248
+ }
249
+
250
+ module.exports = Object.freeze({
251
+ PORTABLE_EQUIVALENCE_VERSION,
252
+ sha256,
253
+ stableObject,
254
+ stableJson,
255
+ hashJson,
256
+ compiledProjectFingerprint,
257
+ portableCompiledProjectFingerprint,
258
+ nativePlanFingerprint,
259
+ portableNativePlanFingerprint,
260
+ nativeModuleFingerprint,
261
+ compilationErrorFingerprint
262
+ });
@@ -0,0 +1,87 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+
5
+ function loadGuestUnitStage() {
6
+ try {
7
+ return require('@pulse-compute/wasm-guest-link/stage');
8
+ } catch (error) {
9
+ if (error && ['MODULE_NOT_FOUND', 'ERR_PACKAGE_PATH_NOT_EXPORTED'].includes(error.code)) {
10
+ return require('../../../wasm-guest-link/src/stage.js');
11
+ }
12
+ throw error;
13
+ }
14
+ }
15
+
16
+ function loadPackageContract() {
17
+ try {
18
+ return require('@pulse-compute/wasm-contracts/package/package-contract');
19
+ } catch (error) {
20
+ if (error && ['MODULE_NOT_FOUND', 'ERR_PACKAGE_PATH_NOT_EXPORTED'].includes(error.code)) {
21
+ return require('../../../contracts/src/package/package-contract.js');
22
+ }
23
+ throw error;
24
+ }
25
+ }
26
+
27
+ const guestUnitStage = loadGuestUnitStage();
28
+ const {
29
+ GUEST_UNIT_CONTRIBUTION_FIELDS,
30
+ normalizeCanonicalGuestUnitContribution
31
+ } = loadPackageContract();
32
+
33
+ function optimizationPosture(value) {
34
+ if (value === undefined || value === null || value === false) return 'native-default';
35
+ if (
36
+ value === true
37
+ || value === 'experimental-native-size'
38
+ || (value && typeof value === 'object' && value.mode === 'experimental-native-size')
39
+ ) return 'native-size';
40
+ const error = new Error(`Unsupported Native guest-link optimization mode ${String(value && value.mode || value)}.`);
41
+ error.code = 'PULSE_GUEST_OPTIMIZATION_FAILED';
42
+ throw error;
43
+ }
44
+
45
+ function canonicalContribution(selection) {
46
+ return normalizeCanonicalGuestUnitContribution(Object.fromEntries(
47
+ GUEST_UNIT_CONTRIBUTION_FIELDS.map((field) => [field, selection && selection[field]])
48
+ ));
49
+ }
50
+
51
+ function realizeSelectedGuestUnits(realization, guestUnits, options = {}) {
52
+ const selected = Array.isArray(guestUnits) ? guestUnits : [];
53
+ if (selected.length === 0) return realization;
54
+ const result = guestUnitStage.realizeGuestLinkStage({
55
+ version: guestUnitStage.GUEST_LINK_STAGE_INVOCATION_VERSION,
56
+ primaryWasm: realization && realization.wasm,
57
+ guestUnits: selected.map((selection) => Object.freeze({
58
+ contribution: canonicalContribution(selection),
59
+ packageRoot: selection && selection.packageRoot
60
+ })),
61
+ projectRoot: path.resolve(options.projectRoot || options.cwd || process.cwd()),
62
+ profile: String(options.profile || 'native'),
63
+ finalWasmPolicy: options.targetDescriptor && options.targetDescriptor.finalWasmPolicy,
64
+ synchronizedPackages: options.synchronizedPackages,
65
+ optimizationPosture: optimizationPosture(options.nativeOptimization)
66
+ });
67
+ return Object.freeze({
68
+ ...realization,
69
+ wasm: result.wasm,
70
+ wat: result.wat,
71
+ guestUnits: result.guestUnits,
72
+ guestLink: Object.freeze({
73
+ version: result.version,
74
+ plan: result.plan,
75
+ report: result.report,
76
+ audit: result.audit,
77
+ materialization: result.materialization,
78
+ finalArtifact: result.finalArtifact,
79
+ providerPackaging: result.providerPackaging,
80
+ fallback: result.fallback
81
+ })
82
+ });
83
+ }
84
+
85
+ module.exports = Object.freeze({
86
+ realizeSelectedGuestUnits
87
+ });