@onda-lang/wasm-compiler 0.6.0 → 0.7.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.
package/src/index.d.ts CHANGED
@@ -50,15 +50,90 @@ export interface OndaCompileOptions {
50
50
  codegen?: OndaCodegenOptions;
51
51
  }
52
52
 
53
- export interface OndaProject {
53
+ export interface OndaSourceWorkspace {
54
54
  entry: string;
55
55
  sources: Record<string, string>;
56
56
  }
57
57
 
58
+ export type OndaSourceReferenceKind = "include" | "import";
59
+
60
+ export interface OndaSourceDocument {
61
+ path: string;
62
+ contents: string;
63
+ }
64
+
65
+ export interface OndaSourceResolution {
66
+ source: string;
67
+ kind: OndaSourceReferenceKind;
68
+ specifier: string;
69
+ target: string;
70
+ }
71
+
72
+ export interface OndaSourceGraph {
73
+ entry: string;
74
+ stdlibDigest: string;
75
+ documents: OndaSourceDocument[];
76
+ resolutions: OndaSourceResolution[];
77
+ }
78
+
79
+ export type OndaBufferElement = "bool" | "i32" | "i64" | "f32" | "f64";
80
+ export type OndaBufferData =
81
+ | Uint8Array
82
+ | Int32Array
83
+ | BigInt64Array
84
+ | Float32Array
85
+ | Float64Array;
86
+
87
+ export interface OndaBufferAssetBinding {
88
+ element: OndaBufferElement;
89
+ frames: number;
90
+ channels: number;
91
+ sampleRate: number;
92
+ data: OndaBufferData;
93
+ }
94
+
95
+ export interface OndaProjectBufferInfo {
96
+ name: string;
97
+ assetId: string;
98
+ element: OndaBufferElement;
99
+ frames: number;
100
+ channels: number;
101
+ sampleRate: number;
102
+ }
103
+
104
+ export interface OndaProjectImageInfo {
105
+ formatVersion: number;
106
+ contentDigest: string;
107
+ sourceGraph: OndaSourceGraph;
108
+ buffers: OndaProjectBufferInfo[];
109
+ }
110
+
111
+ export interface OndaSerializedProjectImage extends OndaProjectImageInfo {
112
+ bytes: Uint8Array;
113
+ }
114
+
115
+ export interface OndaMaterializedProjectFile {
116
+ path: string;
117
+ bytes: Uint8Array;
118
+ }
119
+
120
+ export interface OndaProjectMaterialization {
121
+ directories: string[];
122
+ files: OndaMaterializedProjectFile[];
123
+ }
124
+
125
+ export interface OndaProjectCapabilities {
126
+ imageFormatVersion: number;
127
+ bufferAssetFormatVersion: number;
128
+ stdlibDigest: string;
129
+ }
130
+
58
131
  export interface OndaCompilationResult {
59
132
  artifact: OndaProcessorArtifact;
60
133
  /** Entry first, then transitive non-stdlib imports/includes in discovery order. */
61
134
  sourceFiles: string[];
135
+ /** Exact resolved graph for successful multi-file/project-image compilation. */
136
+ sourceGraph: OndaSourceGraph | null;
62
137
  }
63
138
 
64
139
  export interface OndaCompilerInstance {
@@ -66,10 +141,38 @@ export interface OndaCompilerInstance {
66
141
  source: string,
67
142
  options?: OndaCompileOptions,
68
143
  ): Promise<OndaCompilationResult>;
69
- compileProject(
70
- project: OndaProject,
144
+ compileWorkspace(
145
+ workspace: OndaSourceWorkspace,
146
+ options?: OndaCompileOptions,
147
+ ): Promise<OndaCompilationResult>;
148
+ compileProjectImage(
149
+ imageBytes: ArrayBuffer | ArrayBufferView,
71
150
  options?: OndaCompileOptions,
72
151
  ): Promise<OndaCompilationResult>;
152
+ createProjectImage(
153
+ sourceGraph: OndaSourceGraph,
154
+ buffers?: Map<string, ArrayBuffer | ArrayBufferView>
155
+ | Record<string, ArrayBuffer | ArrayBufferView>,
156
+ ): Promise<OndaSerializedProjectImage>;
157
+ inspectProjectImage(
158
+ imageBytes: ArrayBuffer | ArrayBufferView,
159
+ ): Promise<OndaProjectImageInfo>;
160
+ loadProjectFiles(
161
+ files: Map<string, ArrayBuffer | ArrayBufferView>
162
+ | Record<string, ArrayBuffer | ArrayBufferView>,
163
+ projectFilePath?: string | null,
164
+ ): Promise<OndaSerializedProjectImage>;
165
+ materializeProjectImage(
166
+ imageBytes: ArrayBuffer | ArrayBufferView,
167
+ assetFileNames?: Map<string, string> | Record<string, string>,
168
+ ): Promise<OndaProjectMaterialization>;
169
+ encodeBufferAsset(binding: OndaBufferAssetBinding): Promise<Uint8Array>;
170
+ decodeBufferAsset(bytes: ArrayBuffer | ArrayBufferView): Promise<OndaBufferAssetBinding>;
171
+ decodeBufferFile(
172
+ bytes: ArrayBuffer | ArrayBufferView,
173
+ path?: string,
174
+ ): Promise<OndaBufferAssetBinding>;
175
+ projectCapabilities(): Promise<OndaProjectCapabilities>;
73
176
  sendLspMessage(message: OndaLspMessage): Promise<OndaLspMessage[]>;
74
177
  setLspAnalysisOptions(options?: OndaCompileOptions): Promise<void>;
75
178
  dispose(): Promise<void>;
package/src/index.js CHANGED
@@ -91,52 +91,204 @@ class OndaCompiler {
91
91
  } catch (error) {
92
92
  throw diagnosticsFromFrontend(error);
93
93
  }
94
- const { mir, sourceFiles } = consumeFrontendCompilation(frontendCompilation);
94
+ const { mir, sourceFiles, sourceGraph } = consumeFrontendCompilation(frontendCompilation);
95
95
  const artifact = compileMirTransport(
96
96
  mir,
97
97
  compile.codegen,
98
98
  this.compileTrustedMir,
99
99
  sourceFiles,
100
100
  );
101
- return { artifact, sourceFiles };
101
+ return { artifact, sourceFiles, sourceGraph };
102
102
  }
103
103
 
104
- async compileProject(project, options = {}) {
105
- if (!project || typeof project !== "object" || Array.isArray(project)) {
106
- throw configurationError("project must contain an entry and source map");
104
+ async compileWorkspace(workspace, options = {}) {
105
+ if (!workspace || typeof workspace !== "object" || Array.isArray(workspace)) {
106
+ throw configurationError("workspace must contain an entry and source map");
107
107
  }
108
- if (typeof project.entry !== "string" || project.entry.length === 0) {
109
- throw configurationError("project.entry must be a non-empty string");
108
+ if (typeof workspace.entry !== "string" || workspace.entry.length === 0) {
109
+ throw configurationError("workspace.entry must be a non-empty string");
110
110
  }
111
- if (!project.sources || typeof project.sources !== "object" || Array.isArray(project.sources)) {
112
- throw configurationError("project.sources must be an object of paths to source strings");
111
+ if (!workspace.sources || typeof workspace.sources !== "object" || Array.isArray(workspace.sources)) {
112
+ throw configurationError("workspace.sources must be an object of paths to source strings");
113
113
  }
114
- for (const [path, source] of Object.entries(project.sources)) {
114
+ for (const [path, source] of Object.entries(workspace.sources)) {
115
115
  if (typeof source !== "string") {
116
- throw configurationError(`project source '${path}' must be a string`);
116
+ throw configurationError(`workspace source '${path}' must be a string`);
117
117
  }
118
118
  }
119
119
 
120
120
  const compile = normalizeCompileOptions(options);
121
121
  let frontendCompilation;
122
122
  try {
123
- frontendCompilation = this.frontend.compile_project_to_mir_messagepack(
124
- project.entry,
125
- JSON.stringify(project.sources),
123
+ frontendCompilation = this.frontend.compile_source_workspace_to_mir_messagepack(
124
+ workspace.entry,
125
+ JSON.stringify(workspace.sources),
126
126
  compile.sampleRate,
127
127
  compile.blockSize,
128
128
  );
129
129
  } catch (error) {
130
130
  throw diagnosticsFromFrontend(error);
131
131
  }
132
- const { mir, sourceFiles } = consumeFrontendCompilation(frontendCompilation);
132
+ const { mir, sourceFiles, sourceGraph } = consumeFrontendCompilation(frontendCompilation);
133
133
  const artifact = compileMirTransport(
134
134
  mir,
135
135
  compile.codegen,
136
136
  this.compileTrustedMir,
137
137
  sourceFiles,
138
138
  );
139
- return { artifact, sourceFiles };
139
+ return { artifact, sourceFiles, sourceGraph };
140
+ }
141
+
142
+ async compileProjectImage(imageBytes, options = {}) {
143
+ const bytes = normalizeBytes(imageBytes, "project image");
144
+ const compile = normalizeCompileOptions(options);
145
+ let frontendCompilation;
146
+ try {
147
+ frontendCompilation = this.frontend.compile_project_image_to_mir_messagepack(
148
+ bytes,
149
+ compile.sampleRate,
150
+ compile.blockSize,
151
+ );
152
+ } catch (error) {
153
+ throw diagnosticsFromFrontend(error);
154
+ }
155
+ const { mir, sourceFiles, sourceGraph } = consumeFrontendCompilation(frontendCompilation);
156
+ const artifact = compileMirTransport(
157
+ mir,
158
+ compile.codegen,
159
+ this.compileTrustedMir,
160
+ sourceFiles,
161
+ );
162
+ return { artifact, sourceFiles, sourceGraph };
163
+ }
164
+
165
+ async createProjectImage(sourceGraph, buffers = new Map()) {
166
+ const graph = normalizeSourceGraph(sourceGraph);
167
+ const builder = new this.frontend.WebProjectImageBuilder(JSON.stringify(graph));
168
+ try {
169
+ for (const [name, bytes] of normalizeBufferAssetEntries(buffers)) {
170
+ builder.add_buffer(name, bytes);
171
+ }
172
+ const bytes = builder.serialize();
173
+ return {
174
+ bytes,
175
+ ...normalizeProjectImageInfo(JSON.parse(this.frontend.inspect_project_image(bytes))),
176
+ };
177
+ } catch (cause) {
178
+ throw new OndaCompilerError("failed to create Onda project image", { cause });
179
+ } finally {
180
+ builder.free();
181
+ }
182
+ }
183
+
184
+ async inspectProjectImage(imageBytes) {
185
+ try {
186
+ return normalizeProjectImageInfo(JSON.parse(this.frontend.inspect_project_image(
187
+ normalizeBytes(imageBytes, "project image"),
188
+ )));
189
+ } catch (cause) {
190
+ throw new OndaCompilerError("failed to inspect Onda project image", { cause });
191
+ }
192
+ }
193
+
194
+ async loadProjectFiles(files, projectFilePath = null) {
195
+ const builder = new this.frontend.WebMaterializedProjectBuilder();
196
+ try {
197
+ if (projectFilePath !== null) {
198
+ builder.select_project(normalizeProjectFilePath(projectFilePath));
199
+ }
200
+ for (const [path, bytes] of normalizeProjectFileEntries(files)) {
201
+ builder.add_file(path, bytes);
202
+ }
203
+ const bytes = builder.serialize();
204
+ return {
205
+ bytes,
206
+ ...normalizeProjectImageInfo(JSON.parse(this.frontend.inspect_project_image(bytes))),
207
+ };
208
+ } catch (cause) {
209
+ throw new OndaCompilerError("failed to load Onda project files", { cause });
210
+ } finally {
211
+ builder.free();
212
+ }
213
+ }
214
+
215
+ async materializeProjectImage(imageBytes, assetFileNames = new Map()) {
216
+ let plan;
217
+ try {
218
+ plan = this.frontend.materialize_project_image(
219
+ normalizeBytes(imageBytes, "project image"),
220
+ JSON.stringify(Object.fromEntries(normalizeAssetFileNameEntries(assetFileNames))),
221
+ );
222
+ const files = [];
223
+ for (let index = 0; index < plan.file_count(); index += 1) {
224
+ files.push({ path: plan.file_path(index), bytes: plan.file_bytes(index) });
225
+ }
226
+ return { directories: JSON.parse(plan.directories_json()), files };
227
+ } catch (cause) {
228
+ throw new OndaCompilerError("failed to materialize Onda project image", { cause });
229
+ } finally {
230
+ plan?.free();
231
+ }
232
+ }
233
+
234
+ async encodeBufferAsset(binding) {
235
+ const normalized = normalizeBufferBinding(binding);
236
+ try {
237
+ return this.frontend.encode_buffer_asset(
238
+ normalized.element,
239
+ normalized.frames,
240
+ normalized.channels,
241
+ normalized.sampleRate,
242
+ encodeCanonicalPayload(normalized.element, normalized.data),
243
+ );
244
+ } catch (cause) {
245
+ throw new OndaCompilerError("failed to encode Onda buffer asset", { cause });
246
+ }
247
+ }
248
+
249
+ async decodeBufferAsset(bytes) {
250
+ return this.#decodeBuffer(
251
+ () => this.frontend.decode_buffer_asset(normalizeBytes(bytes, "buffer asset")),
252
+ "failed to decode Onda buffer asset",
253
+ );
254
+ }
255
+
256
+ async decodeBufferFile(bytes, path = "buffer") {
257
+ return this.#decodeBuffer(
258
+ () => this.frontend.decode_buffer_file(
259
+ normalizeBytes(bytes, "buffer file"),
260
+ String(path),
261
+ ),
262
+ "failed to decode buffer file",
263
+ );
264
+ }
265
+
266
+ async #decodeBuffer(decode, message) {
267
+ let decoded;
268
+ try {
269
+ decoded = decode();
270
+ const element = decoded.element();
271
+ const payload = decoded.canonical_payload();
272
+ return {
273
+ element,
274
+ frames: decoded.frames(),
275
+ channels: decoded.channels(),
276
+ sampleRate: decoded.sample_rate(),
277
+ data: decodeCanonicalPayload(element, payload),
278
+ };
279
+ } catch (cause) {
280
+ throw new OndaCompilerError(message, { cause });
281
+ } finally {
282
+ decoded?.free();
283
+ }
284
+ }
285
+
286
+ async projectCapabilities() {
287
+ return {
288
+ imageFormatVersion: this.frontend.project_image_format_version(),
289
+ bufferAssetFormatVersion: this.frontend.buffer_asset_format_version(),
290
+ stdlibDigest: this.frontend.current_stdlib_digest(),
291
+ };
140
292
  }
141
293
 
142
294
  async sendLspMessage(message) {
@@ -190,8 +342,44 @@ class WorkerOndaCompiler {
190
342
  return this.request("compileSource", { source, options });
191
343
  }
192
344
 
193
- compileProject(project, options = {}) {
194
- return this.request("compileProject", { project, options });
345
+ compileWorkspace(workspace, options = {}) {
346
+ return this.request("compileWorkspace", { workspace, options });
347
+ }
348
+
349
+ compileProjectImage(imageBytes, options = {}) {
350
+ return this.request("compileProjectImage", { imageBytes, options });
351
+ }
352
+
353
+ createProjectImage(sourceGraph, buffers = new Map()) {
354
+ return this.request("createProjectImage", { sourceGraph, buffers });
355
+ }
356
+
357
+ inspectProjectImage(imageBytes) {
358
+ return this.request("inspectProjectImage", { imageBytes });
359
+ }
360
+
361
+ loadProjectFiles(files, projectFilePath = null) {
362
+ return this.request("loadProjectFiles", { files, projectFilePath });
363
+ }
364
+
365
+ materializeProjectImage(imageBytes, assetFileNames = new Map()) {
366
+ return this.request("materializeProjectImage", { imageBytes, assetFileNames });
367
+ }
368
+
369
+ encodeBufferAsset(binding) {
370
+ return this.request("encodeBufferAsset", { binding });
371
+ }
372
+
373
+ decodeBufferAsset(bytes) {
374
+ return this.request("decodeBufferAsset", { bytes });
375
+ }
376
+
377
+ decodeBufferFile(bytes, path = "buffer") {
378
+ return this.request("decodeBufferFile", { bytes, path });
379
+ }
380
+
381
+ projectCapabilities() {
382
+ return this.request("projectCapabilities");
195
383
  }
196
384
 
197
385
  sendLspMessage(message) {
@@ -340,7 +528,10 @@ function consumeFrontendCompilation(compilation) {
340
528
  try {
341
529
  const mir = compilation.take_mir();
342
530
  const sourceFiles = normalizeSourceFiles(JSON.parse(compilation.source_files_json()));
343
- return { mir, sourceFiles };
531
+ const sourceGraph = normalizeReturnedSourceGraph(
532
+ JSON.parse(compilation.source_image_json()),
533
+ );
534
+ return { mir, sourceFiles, sourceGraph };
344
535
  } finally {
345
536
  compilation.free();
346
537
  }
@@ -430,3 +621,193 @@ function normalizeSourceFiles(sourceFiles) {
430
621
  if (!Array.isArray(sourceFiles)) return [];
431
622
  return sourceFiles.map((path) => String(path));
432
623
  }
624
+
625
+ function normalizeBytes(value, context) {
626
+ if (value instanceof Uint8Array) return value;
627
+ if (value instanceof ArrayBuffer) return new Uint8Array(value);
628
+ if (ArrayBuffer.isView(value)) {
629
+ return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
630
+ }
631
+ throw new OndaCompilerError(`${context} must be an ArrayBuffer or typed-array view`);
632
+ }
633
+
634
+ function normalizeSourceGraph(graph) {
635
+ if (!graph || typeof graph !== "object" || Array.isArray(graph)) {
636
+ throw new OndaCompilerError("source graph must be an object");
637
+ }
638
+ const entry = String(graph.entry ?? "");
639
+ const stdlibDigest = String(graph.stdlibDigest ?? graph.stdlib_digest ?? "");
640
+ if (!entry || !stdlibDigest) {
641
+ throw new OndaCompilerError("source graph requires entry and stdlibDigest");
642
+ }
643
+ const documents = Array.isArray(graph.documents) ? graph.documents.map((document) => ({
644
+ path: String(document?.path ?? ""),
645
+ contents: String(document?.contents ?? ""),
646
+ })) : [];
647
+ const resolutions = Array.isArray(graph.resolutions) ? graph.resolutions.map((resolution) => ({
648
+ source: String(resolution?.source ?? ""),
649
+ kind: String(resolution?.kind ?? ""),
650
+ specifier: String(resolution?.specifier ?? ""),
651
+ target: String(resolution?.target ?? ""),
652
+ })) : [];
653
+ return {
654
+ entry,
655
+ stdlib_digest: stdlibDigest,
656
+ documents,
657
+ resolutions,
658
+ };
659
+ }
660
+
661
+ function normalizeReturnedSourceGraph(graph) {
662
+ if (!graph) return null;
663
+ return {
664
+ entry: String(graph.entry),
665
+ stdlibDigest: String(graph.stdlib_digest),
666
+ documents: graph.documents.map((document) => ({
667
+ path: String(document.path),
668
+ contents: String(document.contents),
669
+ })),
670
+ resolutions: graph.resolutions.map((resolution) => ({
671
+ source: String(resolution.source),
672
+ kind: String(resolution.kind),
673
+ specifier: String(resolution.specifier),
674
+ target: String(resolution.target),
675
+ })),
676
+ };
677
+ }
678
+
679
+ function normalizeProjectImageInfo(info) {
680
+ return {
681
+ formatVersion: Number(info.format_version),
682
+ contentDigest: String(info.content_digest),
683
+ sourceGraph: normalizeReturnedSourceGraph(info.sources),
684
+ buffers: info.buffers.map((buffer) => ({
685
+ name: String(buffer.name),
686
+ assetId: String(buffer.asset_id),
687
+ element: String(buffer.element),
688
+ frames: Number(buffer.frames),
689
+ channels: Number(buffer.channels),
690
+ sampleRate: Number(buffer.sample_rate),
691
+ })),
692
+ };
693
+ }
694
+
695
+ function normalizeBufferAssetEntries(buffers) {
696
+ const entries = buffers instanceof Map
697
+ ? [...buffers]
698
+ : buffers && typeof buffers === "object" && !Array.isArray(buffers)
699
+ ? Object.entries(buffers)
700
+ : null;
701
+ if (!entries) throw new OndaCompilerError("project buffers must be a Map or object");
702
+ return entries.map(([name, bytes]) => {
703
+ if (typeof name !== "string" || !name) {
704
+ throw new OndaCompilerError("project buffer names must be non-empty strings");
705
+ }
706
+ return [name, normalizeBytes(bytes, `project buffer '${name}'`)];
707
+ });
708
+ }
709
+
710
+ function normalizeAssetFileNameEntries(fileNames) {
711
+ const entries = fileNames instanceof Map
712
+ ? [...fileNames]
713
+ : fileNames && typeof fileNames === "object" && !Array.isArray(fileNames)
714
+ ? Object.entries(fileNames)
715
+ : null;
716
+ if (!entries) throw new OndaCompilerError("asset filenames must be a Map or object");
717
+ return entries.map(([name, fileName]) => {
718
+ if (typeof name !== "string" || !name || typeof fileName !== "string" || !fileName) {
719
+ throw new OndaCompilerError("asset filenames require non-empty buffer names and filenames");
720
+ }
721
+ return [name, fileName];
722
+ });
723
+ }
724
+
725
+ function normalizeProjectFilePath(path) {
726
+ if (typeof path !== "string" || !path) {
727
+ throw new OndaCompilerError("selected project manifest must be a non-empty string");
728
+ }
729
+ return path;
730
+ }
731
+
732
+ function normalizeProjectFileEntries(files) {
733
+ const entries = files instanceof Map
734
+ ? [...files]
735
+ : files && typeof files === "object" && !Array.isArray(files)
736
+ ? Object.entries(files)
737
+ : null;
738
+ if (!entries) throw new OndaCompilerError("project files must be a Map or object");
739
+ return entries.map(([path, bytes]) => {
740
+ if (typeof path !== "string" || !path) {
741
+ throw new OndaCompilerError("project file paths must be non-empty strings");
742
+ }
743
+ return [path, normalizeBytes(bytes, `project file '${path}'`)];
744
+ });
745
+ }
746
+
747
+ function normalizeBufferBinding(binding) {
748
+ if (!binding || typeof binding !== "object" || Array.isArray(binding)) {
749
+ throw new OndaCompilerError("buffer binding must be an object");
750
+ }
751
+ const element = String(binding.element ?? binding.scalar ?? "");
752
+ const frames = Number(binding.frames);
753
+ const channels = Number(binding.channels);
754
+ const sampleRate = Number(binding.sampleRate);
755
+ const data = binding.data;
756
+ const expectedConstructor = {
757
+ bool: Uint8Array,
758
+ i32: Int32Array,
759
+ i64: BigInt64Array,
760
+ f32: Float32Array,
761
+ f64: Float64Array,
762
+ }[element];
763
+ if (!expectedConstructor || !(data instanceof expectedConstructor)) {
764
+ throw new OndaCompilerError(`buffer element '${element}' requires ${expectedConstructor?.name ?? "a supported typed array"}`);
765
+ }
766
+ if (
767
+ !Number.isInteger(frames) || frames <= 0
768
+ || !Number.isInteger(channels) || channels <= 0
769
+ || !Number.isFinite(sampleRate) || sampleRate <= 0
770
+ || data.length !== frames * channels
771
+ ) {
772
+ throw new OndaCompilerError("buffer binding has an invalid shape or sample rate");
773
+ }
774
+ return { element, frames, channels, sampleRate, data };
775
+ }
776
+
777
+ function encodeCanonicalPayload(element, data) {
778
+ if (element === "bool") {
779
+ if (data.some((value) => value > 1)) {
780
+ throw new OndaCompilerError("bool buffer values must be 0 or 1");
781
+ }
782
+ return data.slice();
783
+ }
784
+ const bytes = new Uint8Array(data.length * data.BYTES_PER_ELEMENT);
785
+ const view = new DataView(bytes.buffer);
786
+ for (let index = 0; index < data.length; index += 1) {
787
+ const offset = index * data.BYTES_PER_ELEMENT;
788
+ if (element === "i32") view.setInt32(offset, data[index], true);
789
+ else if (element === "i64") view.setBigInt64(offset, data[index], true);
790
+ else if (element === "f32") view.setFloat32(offset, data[index], true);
791
+ else view.setFloat64(offset, data[index], true);
792
+ }
793
+ return bytes;
794
+ }
795
+
796
+ function decodeCanonicalPayload(element, payload) {
797
+ if (element === "bool") return payload.slice();
798
+ const elementBytes = element === "i32" || element === "f32" ? 4 : 8;
799
+ const length = payload.byteLength / elementBytes;
800
+ const output = element === "i32" ? new Int32Array(length)
801
+ : element === "i64" ? new BigInt64Array(length)
802
+ : element === "f32" ? new Float32Array(length)
803
+ : new Float64Array(length);
804
+ const view = new DataView(payload.buffer, payload.byteOffset, payload.byteLength);
805
+ for (let index = 0; index < length; index += 1) {
806
+ const offset = index * elementBytes;
807
+ output[index] = element === "i32" ? view.getInt32(offset, true)
808
+ : element === "i64" ? view.getBigInt64(offset, true)
809
+ : element === "f32" ? view.getFloat32(offset, true)
810
+ : view.getFloat64(offset, true);
811
+ }
812
+ return output;
813
+ }
package/src/worker.js CHANGED
@@ -19,14 +19,69 @@ globalThis.addEventListener("message", async (event) => {
19
19
  respond(requestId, result, [result.artifact.wasm.buffer]);
20
20
  return;
21
21
  }
22
- if (message.type === "compileProject") {
23
- const result = await (await compiler()).compileProject(
24
- message.project,
22
+ if (message.type === "compileWorkspace") {
23
+ const result = await (await compiler()).compileWorkspace(
24
+ message.workspace,
25
25
  message.options,
26
26
  );
27
27
  respond(requestId, result, [result.artifact.wasm.buffer]);
28
28
  return;
29
29
  }
30
+ if (message.type === "compileProjectImage") {
31
+ const result = await (await compiler()).compileProjectImage(
32
+ message.imageBytes,
33
+ message.options,
34
+ );
35
+ respond(requestId, result, [result.artifact.wasm.buffer]);
36
+ return;
37
+ }
38
+ if (message.type === "createProjectImage") {
39
+ const result = await (await compiler()).createProjectImage(
40
+ message.sourceGraph,
41
+ message.buffers,
42
+ );
43
+ respond(requestId, result, [result.bytes.buffer]);
44
+ return;
45
+ }
46
+ if (message.type === "inspectProjectImage") {
47
+ respond(requestId, await (await compiler()).inspectProjectImage(message.imageBytes));
48
+ return;
49
+ }
50
+ if (message.type === "loadProjectFiles") {
51
+ const result = await (await compiler()).loadProjectFiles(
52
+ message.files,
53
+ message.projectFilePath,
54
+ );
55
+ respond(requestId, result, [result.bytes.buffer]);
56
+ return;
57
+ }
58
+ if (message.type === "materializeProjectImage") {
59
+ const result = await (await compiler()).materializeProjectImage(
60
+ message.imageBytes,
61
+ message.assetFileNames,
62
+ );
63
+ respond(requestId, result, result.files.map((file) => file.bytes.buffer));
64
+ return;
65
+ }
66
+ if (message.type === "encodeBufferAsset") {
67
+ const result = await (await compiler()).encodeBufferAsset(message.binding);
68
+ respond(requestId, result, [result.buffer]);
69
+ return;
70
+ }
71
+ if (message.type === "decodeBufferAsset") {
72
+ const result = await (await compiler()).decodeBufferAsset(message.bytes);
73
+ respond(requestId, result, [result.data.buffer]);
74
+ return;
75
+ }
76
+ if (message.type === "decodeBufferFile") {
77
+ const result = await (await compiler()).decodeBufferFile(message.bytes, message.path);
78
+ respond(requestId, result, [result.data.buffer]);
79
+ return;
80
+ }
81
+ if (message.type === "projectCapabilities") {
82
+ respond(requestId, await (await compiler()).projectCapabilities());
83
+ return;
84
+ }
30
85
  if (message.type === "lspMessage") {
31
86
  const responses = await (await compiler()).sendLspMessage(message.message);
32
87
  respond(requestId, responses);