@astrojs/compiler 0.1.4 → 0.1.9

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/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @astrojs/compiler
2
2
 
3
+ ## 0.1.9
4
+
5
+ ### Patch Changes
6
+
7
+ - 7d887de: Allows the Astro runtime to create the Astro.slots object
8
+
9
+ ## 0.1.8
10
+
11
+ ### Patch Changes
12
+
13
+ - d159658: Publish via PR
14
+
15
+ ## 0.1.7
16
+
17
+ ### Patch Changes
18
+
19
+ - c52e69b: Include astro.wasm in the package
20
+
21
+ ## 0.1.6
22
+
23
+ ### Patch Changes
24
+
25
+ - bd05f7c: Actually include _any_ files?
26
+
27
+ ## 0.1.5
28
+
29
+ ### Patch Changes
30
+
31
+ - c4ed69e: Includes the wasm binary in the npm package
32
+
3
33
  ## 0.1.4
4
34
 
5
35
  ### Patch Changes
package/astro.wasm ADDED
Binary file
@@ -0,0 +1,3 @@
1
+ import type * as types from "../shared/types";
2
+ export declare const transform: typeof types.transform;
3
+ export declare const initialize: typeof types.initialize;
@@ -0,0 +1,59 @@
1
+ import Go from "./wasm_exec.js";
2
+ export const transform = (input, options) => {
3
+ return ensureServiceIsRunning().transform(input, options);
4
+ };
5
+ let initializePromise;
6
+ let longLivedService;
7
+ export const initialize = (options) => {
8
+ let wasmURL = options.wasmURL;
9
+ let useWorker = options.worker !== false;
10
+ if (!wasmURL)
11
+ throw new Error('Must provide the "wasmURL" option');
12
+ wasmURL += "";
13
+ if (initializePromise)
14
+ throw new Error('Cannot call "initialize" more than once');
15
+ initializePromise = startRunningService(wasmURL, useWorker);
16
+ initializePromise.catch(() => {
17
+ // Let the caller try again if this fails
18
+ initializePromise = void 0;
19
+ });
20
+ return initializePromise;
21
+ };
22
+ let ensureServiceIsRunning = () => {
23
+ if (longLivedService)
24
+ return longLivedService;
25
+ if (initializePromise)
26
+ throw new Error('You need to wait for the promise returned from "initialize" to be resolved before calling this');
27
+ throw new Error('You need to call "initialize" before calling this');
28
+ };
29
+ const instantiateWASM = async (wasmURL, importObject) => {
30
+ let response = undefined;
31
+ if (WebAssembly.instantiateStreaming) {
32
+ response = await WebAssembly.instantiateStreaming(fetch(wasmURL), importObject);
33
+ }
34
+ else {
35
+ const fetchAndInstantiateTask = async () => {
36
+ const wasmArrayBuffer = await fetch(wasmURL).then((response) => response.arrayBuffer());
37
+ return WebAssembly.instantiate(wasmArrayBuffer, importObject);
38
+ };
39
+ response = await fetchAndInstantiateTask();
40
+ }
41
+ return response;
42
+ };
43
+ const startRunningService = async (wasmURL, useWorker) => {
44
+ const go = new Go();
45
+ const wasm = await instantiateWASM(wasmURL, go.importObject);
46
+ go.run(wasm.instance);
47
+ const apiKeys = new Set([
48
+ 'transform'
49
+ ]);
50
+ const service = Object.create(null);
51
+ for (const key of apiKeys.values()) {
52
+ const globalKey = `__astro_${key}`;
53
+ service[key] = globalThis[globalKey];
54
+ delete globalThis[globalKey];
55
+ }
56
+ longLivedService = {
57
+ transform: (input, options) => new Promise((resolve) => resolve(service.transform(input, options || {})))
58
+ };
59
+ };
@@ -0,0 +1,7 @@
1
+ export default class Go {
2
+ importObject: Record<string, any>;
3
+ constructor();
4
+ run(instance: any): Promise<void>;
5
+ private _resume;
6
+ private _makeFuncWrapper;
7
+ }
@@ -0,0 +1,432 @@
1
+ // @ts-nocheck
2
+ // Copyright 2018 The Go Authors. All rights reserved.
3
+ // Use of this source code is governed by a BSD-style
4
+ // license that can be found in the LICENSE file.
5
+ //
6
+ // This file has been modified for use by the TinyGo compiler.
7
+ // This file has been further modified for use by Astro.
8
+ const enosys = () => {
9
+ const err = new Error("not implemented");
10
+ err.code = "ENOSYS";
11
+ return err;
12
+ };
13
+ let outputBuf = "";
14
+ const fs = {
15
+ constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1 },
16
+ writeSync(fd, buf) {
17
+ outputBuf += decoder.decode(buf);
18
+ const nl = outputBuf.lastIndexOf("\n");
19
+ if (nl != -1) {
20
+ console.log(outputBuf.substr(0, nl));
21
+ outputBuf = outputBuf.substr(nl + 1);
22
+ }
23
+ return buf.length;
24
+ },
25
+ write(fd, buf, offset, length, position, callback) {
26
+ if (offset !== 0 || length !== buf.length || position !== null) {
27
+ callback(enosys());
28
+ return;
29
+ }
30
+ const n = this.writeSync(fd, buf);
31
+ callback(null, n);
32
+ },
33
+ chmod(path, mode, callback) { callback(enosys()); },
34
+ chown(path, uid, gid, callback) { callback(enosys()); },
35
+ close(fd, callback) { callback(enosys()); },
36
+ fchmod(fd, mode, callback) { callback(enosys()); },
37
+ fchown(fd, uid, gid, callback) { callback(enosys()); },
38
+ fstat(fd, callback) { callback(enosys()); },
39
+ fsync(fd, callback) { callback(null); },
40
+ ftruncate(fd, length, callback) { callback(enosys()); },
41
+ lchown(path, uid, gid, callback) { callback(enosys()); },
42
+ link(path, link, callback) { callback(enosys()); },
43
+ lstat(path, callback) { callback(enosys()); },
44
+ mkdir(path, perm, callback) { callback(enosys()); },
45
+ open(path, flags, mode, callback) { callback(enosys()); },
46
+ read(fd, buffer, offset, length, position, callback) { callback(enosys()); },
47
+ readdir(path, callback) { callback(enosys()); },
48
+ readlink(path, callback) { callback(enosys()); },
49
+ rename(from, to, callback) { callback(enosys()); },
50
+ rmdir(path, callback) { callback(enosys()); },
51
+ stat(path, callback) { callback(enosys()); },
52
+ symlink(path, link, callback) { callback(enosys()); },
53
+ truncate(path, length, callback) { callback(enosys()); },
54
+ unlink(path, callback) { callback(enosys()); },
55
+ utimes(path, atime, mtime, callback) { callback(enosys()); },
56
+ };
57
+ const process = {
58
+ getuid() { return -1; },
59
+ getgid() { return -1; },
60
+ geteuid() { return -1; },
61
+ getegid() { return -1; },
62
+ getgroups() { throw enosys(); },
63
+ pid: -1,
64
+ ppid: -1,
65
+ umask() { throw enosys(); },
66
+ cwd() { throw enosys(); },
67
+ chdir() { throw enosys(); },
68
+ };
69
+ Object.defineProperties(globalThis, {
70
+ fs: {
71
+ value: fs,
72
+ enumerable: true,
73
+ },
74
+ process: {
75
+ value: process,
76
+ enumerable: true
77
+ }
78
+ });
79
+ const encoder = new TextEncoder("utf-8");
80
+ const decoder = new TextDecoder("utf-8");
81
+ var logLine = [];
82
+ export default class Go {
83
+ constructor() {
84
+ this._callbackTimeouts = new Map();
85
+ this._nextCallbackTimeoutID = 1;
86
+ const mem = () => {
87
+ // The buffer may change when requesting more memory.
88
+ return new DataView(this._inst.exports.memory.buffer);
89
+ };
90
+ const setInt64 = (addr, v) => {
91
+ mem().setUint32(addr + 0, v, true);
92
+ mem().setUint32(addr + 4, Math.floor(v / 4294967296), true);
93
+ };
94
+ const getInt64 = (addr) => {
95
+ const low = mem().getUint32(addr + 0, true);
96
+ const high = mem().getInt32(addr + 4, true);
97
+ return low + high * 4294967296;
98
+ };
99
+ const loadValue = (addr) => {
100
+ const f = mem().getFloat64(addr, true);
101
+ if (f === 0) {
102
+ return undefined;
103
+ }
104
+ if (!isNaN(f)) {
105
+ return f;
106
+ }
107
+ const id = mem().getUint32(addr, true);
108
+ return this._values[id];
109
+ };
110
+ const storeValue = (addr, v) => {
111
+ const nanHead = 0x7ff80000;
112
+ if (typeof v === "number") {
113
+ if (isNaN(v)) {
114
+ mem().setUint32(addr + 4, nanHead, true);
115
+ mem().setUint32(addr, 0, true);
116
+ return;
117
+ }
118
+ if (v === 0) {
119
+ mem().setUint32(addr + 4, nanHead, true);
120
+ mem().setUint32(addr, 1, true);
121
+ return;
122
+ }
123
+ mem().setFloat64(addr, v, true);
124
+ return;
125
+ }
126
+ switch (v) {
127
+ case undefined:
128
+ mem().setFloat64(addr, 0, true);
129
+ return;
130
+ case null:
131
+ mem().setUint32(addr + 4, nanHead, true);
132
+ mem().setUint32(addr, 2, true);
133
+ return;
134
+ case true:
135
+ mem().setUint32(addr + 4, nanHead, true);
136
+ mem().setUint32(addr, 3, true);
137
+ return;
138
+ case false:
139
+ mem().setUint32(addr + 4, nanHead, true);
140
+ mem().setUint32(addr, 4, true);
141
+ return;
142
+ }
143
+ let id = this._ids.get(v);
144
+ if (id === undefined) {
145
+ id = this._idPool.pop();
146
+ if (id === undefined) {
147
+ id = this._values.length;
148
+ }
149
+ this._values[id] = v;
150
+ this._goRefCounts[id] = 0;
151
+ this._ids.set(v, id);
152
+ }
153
+ this._goRefCounts[id]++;
154
+ let typeFlag = 1;
155
+ switch (typeof v) {
156
+ case "string":
157
+ typeFlag = 2;
158
+ break;
159
+ case "symbol":
160
+ typeFlag = 3;
161
+ break;
162
+ case "function":
163
+ typeFlag = 4;
164
+ break;
165
+ }
166
+ mem().setUint32(addr + 4, nanHead | typeFlag, true);
167
+ mem().setUint32(addr, id, true);
168
+ };
169
+ const loadSlice = (array, len, cap) => {
170
+ return new Uint8Array(this._inst.exports.memory.buffer, array, len);
171
+ };
172
+ const loadSliceOfValues = (array, len, cap) => {
173
+ const a = new Array(len);
174
+ for (let i = 0; i < len; i++) {
175
+ a[i] = loadValue(array + i * 8);
176
+ }
177
+ return a;
178
+ };
179
+ const loadString = (ptr, len) => {
180
+ return decoder.decode(new DataView(this._inst.exports.memory.buffer, ptr, len));
181
+ };
182
+ const timeOrigin = Date.now() - performance.now();
183
+ this.importObject = {
184
+ wasi_snapshot_preview1: {
185
+ // https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#fd_write
186
+ fd_write: function (fd, iovs_ptr, iovs_len, nwritten_ptr) {
187
+ let nwritten = 0;
188
+ if (fd == 1) {
189
+ for (let iovs_i = 0; iovs_i < iovs_len; iovs_i++) {
190
+ let iov_ptr = iovs_ptr + iovs_i * 8; // assuming wasm32
191
+ let ptr = mem().getUint32(iov_ptr + 0, true);
192
+ let len = mem().getUint32(iov_ptr + 4, true);
193
+ for (let i = 0; i < len; i++) {
194
+ let c = mem().getUint8(ptr + i);
195
+ if (c == 13) {
196
+ // CR
197
+ // ignore
198
+ }
199
+ else if (c == 10) {
200
+ // LF
201
+ // write line
202
+ let line = decoder.decode(new Uint8Array(logLine));
203
+ logLine = [];
204
+ console.log(line);
205
+ }
206
+ else {
207
+ logLine.push(c);
208
+ }
209
+ }
210
+ }
211
+ }
212
+ else {
213
+ console.error("invalid file descriptor:", fd);
214
+ }
215
+ mem().setUint32(nwritten_ptr, nwritten, true);
216
+ return 0;
217
+ },
218
+ proc_exit: (code) => {
219
+ if (globalThis.process) {
220
+ // Node.js
221
+ process.exit(code);
222
+ }
223
+ else {
224
+ // Can't exit in a browser.
225
+ throw "trying to exit with code " + code;
226
+ }
227
+ },
228
+ },
229
+ env: {
230
+ // func ticks() float64
231
+ "runtime.ticks": () => {
232
+ return timeOrigin + performance.now();
233
+ },
234
+ // func sleepTicks(timeout float64)
235
+ "runtime.sleepTicks": (timeout) => {
236
+ // Do not sleep, only reactivate scheduler after the given timeout.
237
+ setTimeout(this._inst.exports.go_scheduler, timeout);
238
+ },
239
+ // func finalizeRef(v ref)
240
+ "syscall/js.finalizeRef": (v_addr) => {
241
+ // Note: TinyGo does not support finalizers so this is only called
242
+ // for one specific case, by js.go:jsString.
243
+ const id = mem().getUint32(v_addr, true);
244
+ this._goRefCounts[id]--;
245
+ if (this._goRefCounts[id] === 0) {
246
+ const v = this._values[id];
247
+ this._values[id] = null;
248
+ this._ids.delete(v);
249
+ this._idPool.push(id);
250
+ }
251
+ },
252
+ // func stringVal(value string) ref
253
+ "syscall/js.stringVal": (ret_ptr, value_ptr, value_len) => {
254
+ const s = loadString(value_ptr, value_len);
255
+ storeValue(ret_ptr, s);
256
+ },
257
+ // func valueGet(v ref, p string) ref
258
+ "syscall/js.valueGet": (retval, v_addr, p_ptr, p_len) => {
259
+ let prop = loadString(p_ptr, p_len);
260
+ let value = loadValue(v_addr);
261
+ let result = Reflect.get(value, prop);
262
+ storeValue(retval, result);
263
+ },
264
+ // func valueSet(v ref, p string, x ref)
265
+ "syscall/js.valueSet": (v_addr, p_ptr, p_len, x_addr) => {
266
+ const v = loadValue(v_addr);
267
+ const p = loadString(p_ptr, p_len);
268
+ const x = loadValue(x_addr);
269
+ Reflect.set(v, p, x);
270
+ },
271
+ // func valueDelete(v ref, p string)
272
+ "syscall/js.valueDelete": (v_addr, p_ptr, p_len) => {
273
+ const v = loadValue(v_addr);
274
+ const p = loadString(p_ptr, p_len);
275
+ Reflect.deleteProperty(v, p);
276
+ },
277
+ // func valueIndex(v ref, i int) ref
278
+ "syscall/js.valueIndex": (ret_addr, v_addr, i) => {
279
+ storeValue(ret_addr, Reflect.get(loadValue(v_addr), i));
280
+ },
281
+ // valueSetIndex(v ref, i int, x ref)
282
+ "syscall/js.valueSetIndex": (v_addr, i, x_addr) => {
283
+ Reflect.set(loadValue(v_addr), i, loadValue(x_addr));
284
+ },
285
+ // func valueCall(v ref, m string, args []ref) (ref, bool)
286
+ "syscall/js.valueCall": (ret_addr, v_addr, m_ptr, m_len, args_ptr, args_len, args_cap) => {
287
+ const v = loadValue(v_addr);
288
+ const name = loadString(m_ptr, m_len);
289
+ const args = loadSliceOfValues(args_ptr, args_len, args_cap);
290
+ try {
291
+ const m = Reflect.get(v, name);
292
+ storeValue(ret_addr, Reflect.apply(m, v, args));
293
+ mem().setUint8(ret_addr + 8, 1);
294
+ }
295
+ catch (err) {
296
+ storeValue(ret_addr, err);
297
+ mem().setUint8(ret_addr + 8, 0);
298
+ }
299
+ },
300
+ // func valueInvoke(v ref, args []ref) (ref, bool)
301
+ "syscall/js.valueInvoke": (ret_addr, v_addr, args_ptr, args_len, args_cap) => {
302
+ try {
303
+ const v = loadValue(v_addr);
304
+ const args = loadSliceOfValues(args_ptr, args_len, args_cap);
305
+ storeValue(ret_addr, Reflect.apply(v, undefined, args));
306
+ mem().setUint8(ret_addr + 8, 1);
307
+ }
308
+ catch (err) {
309
+ storeValue(ret_addr, err);
310
+ mem().setUint8(ret_addr + 8, 0);
311
+ }
312
+ },
313
+ // func valueNew(v ref, args []ref) (ref, bool)
314
+ "syscall/js.valueNew": (ret_addr, v_addr, args_ptr, args_len, args_cap) => {
315
+ const v = loadValue(v_addr);
316
+ const args = loadSliceOfValues(args_ptr, args_len, args_cap);
317
+ try {
318
+ storeValue(ret_addr, Reflect.construct(v, args));
319
+ mem().setUint8(ret_addr + 8, 1);
320
+ }
321
+ catch (err) {
322
+ storeValue(ret_addr, err);
323
+ mem().setUint8(ret_addr + 8, 0);
324
+ }
325
+ },
326
+ // func valueLength(v ref) int
327
+ "syscall/js.valueLength": (v_addr) => {
328
+ return loadValue(v_addr).length;
329
+ },
330
+ // valuePrepareString(v ref) (ref, int)
331
+ "syscall/js.valuePrepareString": (ret_addr, v_addr) => {
332
+ const s = String(loadValue(v_addr));
333
+ const str = encoder.encode(s);
334
+ storeValue(ret_addr, str);
335
+ setInt64(ret_addr + 8, str.length);
336
+ },
337
+ // valueLoadString(v ref, b []byte)
338
+ "syscall/js.valueLoadString": (v_addr, slice_ptr, slice_len, slice_cap) => {
339
+ const str = loadValue(v_addr);
340
+ loadSlice(slice_ptr, slice_len, slice_cap).set(str);
341
+ },
342
+ // func valueInstanceOf(v ref, t ref) bool
343
+ "syscall/js.valueInstanceOf": (v_addr, t_addr) => {
344
+ return loadValue(v_addr) instanceof loadValue(t_addr);
345
+ },
346
+ // func copyBytesToGo(dst []byte, src ref) (int, bool)
347
+ "syscall/js.copyBytesToGo": (ret_addr, dest_addr, dest_len, dest_cap, source_addr) => {
348
+ let num_bytes_copied_addr = ret_addr;
349
+ let returned_status_addr = ret_addr + 4; // Address of returned boolean status variable
350
+ const dst = loadSlice(dest_addr, dest_len);
351
+ const src = loadValue(source_addr);
352
+ if (!(src instanceof Uint8Array)) {
353
+ mem().setUint8(returned_status_addr, 0); // Return "not ok" status
354
+ return;
355
+ }
356
+ const toCopy = src.subarray(0, dst.length);
357
+ dst.set(toCopy);
358
+ setInt64(num_bytes_copied_addr, toCopy.length);
359
+ mem().setUint8(returned_status_addr, 1); // Return "ok" status
360
+ },
361
+ // copyBytesToJS(dst ref, src []byte) (int, bool)
362
+ // Originally copied from upstream Go project, then modified:
363
+ // https://github.com/golang/go/blob/3f995c3f3b43033013013e6c7ccc93a9b1411ca9/misc/wasm/wasm_exec.js#L404-L416
364
+ "syscall/js.copyBytesToJS": (ret_addr, dest_addr, source_addr, source_len, source_cap) => {
365
+ let num_bytes_copied_addr = ret_addr;
366
+ let returned_status_addr = ret_addr + 4; // Address of returned boolean status variable
367
+ const dst = loadValue(dest_addr);
368
+ const src = loadSlice(source_addr, source_len);
369
+ if (!(dst instanceof Uint8Array)) {
370
+ mem().setUint8(returned_status_addr, 0); // Return "not ok" status
371
+ return;
372
+ }
373
+ const toCopy = src.subarray(0, dst.length);
374
+ dst.set(toCopy);
375
+ setInt64(num_bytes_copied_addr, toCopy.length);
376
+ mem().setUint8(returned_status_addr, 1); // Return "ok" status
377
+ },
378
+ },
379
+ };
380
+ }
381
+ async run(instance) {
382
+ this._inst = instance;
383
+ this._values = [
384
+ // JS values that Go currently has references to, indexed by reference id
385
+ NaN,
386
+ 0,
387
+ null,
388
+ true,
389
+ false,
390
+ globalThis,
391
+ this,
392
+ ];
393
+ this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference id
394
+ this._ids = new Map(); // mapping from JS values to reference ids
395
+ this._idPool = []; // unused ids that have been garbage collected
396
+ this.exited = false; // whether the Go program has exited
397
+ const mem = new DataView(this._inst.exports.memory.buffer);
398
+ while (true) {
399
+ const callbackPromise = new Promise((resolve) => {
400
+ this._resolveCallbackPromise = () => {
401
+ if (this.exited) {
402
+ throw new Error("bad callback: Go program has already exited");
403
+ }
404
+ setTimeout(resolve, 0); // make sure it is asynchronous
405
+ };
406
+ });
407
+ this._inst.exports._start();
408
+ if (this.exited) {
409
+ break;
410
+ }
411
+ await callbackPromise;
412
+ }
413
+ }
414
+ _resume() {
415
+ if (this.exited) {
416
+ throw new Error("Go program has already exited");
417
+ }
418
+ this._inst.exports.resume();
419
+ if (this.exited) {
420
+ this._resolveExitPromise();
421
+ }
422
+ }
423
+ _makeFuncWrapper(id) {
424
+ const go = this;
425
+ return function () {
426
+ const event = { id: id, this: this, args: arguments };
427
+ go._pendingEvent = event;
428
+ go._resume();
429
+ return event.result;
430
+ };
431
+ }
432
+ }
@@ -0,0 +1,3 @@
1
+ import type * as types from "../shared/types";
2
+ export declare const transform: typeof types.transform;
3
+ export declare const compile: (template: string) => Promise<string>;
package/node/index.js ADDED
@@ -0,0 +1,43 @@
1
+ import { promises as fs } from 'fs';
2
+ import Go from "./wasm_exec.js";
3
+ import { fileURLToPath } from "url";
4
+ export const transform = async (input, options) => {
5
+ return ensureServiceIsRunning().then(service => service.transform(input, options));
6
+ };
7
+ export const compile = async (template) => {
8
+ const { default: mod } = await import(`data:text/javascript;charset=utf-8;base64,${Buffer.from(template).toString('base64')}`);
9
+ return mod.__render();
10
+ };
11
+ let longLivedService;
12
+ let ensureServiceIsRunning = () => {
13
+ if (longLivedService)
14
+ return Promise.resolve(longLivedService);
15
+ return startRunningService();
16
+ };
17
+ const instantiateWASM = async (wasmURL, importObject) => {
18
+ let response = undefined;
19
+ const fetchAndInstantiateTask = async () => {
20
+ const wasmArrayBuffer = await fs.readFile(wasmURL).then((response) => response.buffer);
21
+ return WebAssembly.instantiate(new Uint8Array(wasmArrayBuffer), importObject);
22
+ };
23
+ response = await fetchAndInstantiateTask();
24
+ return response;
25
+ };
26
+ const startRunningService = async () => {
27
+ const go = new Go();
28
+ const wasm = await instantiateWASM(fileURLToPath(new URL('../astro.wasm', import.meta.url)), go.importObject);
29
+ go.run(wasm.instance);
30
+ const apiKeys = new Set([
31
+ 'transform'
32
+ ]);
33
+ const service = Object.create(null);
34
+ for (const key of apiKeys.values()) {
35
+ const globalKey = `__astro_${key}`;
36
+ service[key] = globalThis[globalKey];
37
+ delete globalThis[globalKey];
38
+ }
39
+ longLivedService = {
40
+ transform: (input, options) => new Promise((resolve) => resolve(service.transform(input, options || {})))
41
+ };
42
+ return longLivedService;
43
+ };
@@ -0,0 +1,7 @@
1
+ export default class Go {
2
+ importObject: Record<string, any>;
3
+ constructor();
4
+ run(instance: any): Promise<void>;
5
+ private _resume;
6
+ private _makeFuncWrapper;
7
+ }
@@ -0,0 +1,387 @@
1
+ // @ts-nocheck
2
+ // Copyright 2018 The Go Authors. All rights reserved.
3
+ // Use of this source code is governed by a BSD-style
4
+ // license that can be found in the LICENSE file.
5
+ //
6
+ // This file has been modified for use by the TinyGo compiler.
7
+ // This file has been further modified for use by Astro.
8
+ import fs from "fs";
9
+ import crypto from "crypto";
10
+ import { TextEncoder, TextDecoder } from "util";
11
+ Object.defineProperties(globalThis, {
12
+ fs: {
13
+ value: fs,
14
+ enumerable: true,
15
+ },
16
+ crypto: {
17
+ value: {
18
+ getRandomValues(b) {
19
+ crypto.randomFillSync(b);
20
+ },
21
+ },
22
+ enumerable: true,
23
+ },
24
+ performance: {
25
+ value: {
26
+ now() {
27
+ const [sec, nsec] = process.hrtime();
28
+ return sec * 1000 + nsec / 1000000;
29
+ },
30
+ },
31
+ enumerable: true,
32
+ },
33
+ });
34
+ const encoder = new TextEncoder("utf-8");
35
+ const decoder = new TextDecoder("utf-8");
36
+ var logLine = [];
37
+ export default class Go {
38
+ constructor() {
39
+ this._callbackTimeouts = new Map();
40
+ this._nextCallbackTimeoutID = 1;
41
+ const mem = () => {
42
+ // The buffer may change when requesting more memory.
43
+ return new DataView(this._inst.exports.memory.buffer);
44
+ };
45
+ const setInt64 = (addr, v) => {
46
+ mem().setUint32(addr + 0, v, true);
47
+ mem().setUint32(addr + 4, Math.floor(v / 4294967296), true);
48
+ };
49
+ const getInt64 = (addr) => {
50
+ const low = mem().getUint32(addr + 0, true);
51
+ const high = mem().getInt32(addr + 4, true);
52
+ return low + high * 4294967296;
53
+ };
54
+ const loadValue = (addr) => {
55
+ const f = mem().getFloat64(addr, true);
56
+ if (f === 0) {
57
+ return undefined;
58
+ }
59
+ if (!isNaN(f)) {
60
+ return f;
61
+ }
62
+ const id = mem().getUint32(addr, true);
63
+ return this._values[id];
64
+ };
65
+ const storeValue = (addr, v) => {
66
+ const nanHead = 0x7ff80000;
67
+ if (typeof v === "number") {
68
+ if (isNaN(v)) {
69
+ mem().setUint32(addr + 4, nanHead, true);
70
+ mem().setUint32(addr, 0, true);
71
+ return;
72
+ }
73
+ if (v === 0) {
74
+ mem().setUint32(addr + 4, nanHead, true);
75
+ mem().setUint32(addr, 1, true);
76
+ return;
77
+ }
78
+ mem().setFloat64(addr, v, true);
79
+ return;
80
+ }
81
+ switch (v) {
82
+ case undefined:
83
+ mem().setFloat64(addr, 0, true);
84
+ return;
85
+ case null:
86
+ mem().setUint32(addr + 4, nanHead, true);
87
+ mem().setUint32(addr, 2, true);
88
+ return;
89
+ case true:
90
+ mem().setUint32(addr + 4, nanHead, true);
91
+ mem().setUint32(addr, 3, true);
92
+ return;
93
+ case false:
94
+ mem().setUint32(addr + 4, nanHead, true);
95
+ mem().setUint32(addr, 4, true);
96
+ return;
97
+ }
98
+ let id = this._ids.get(v);
99
+ if (id === undefined) {
100
+ id = this._idPool.pop();
101
+ if (id === undefined) {
102
+ id = this._values.length;
103
+ }
104
+ this._values[id] = v;
105
+ this._goRefCounts[id] = 0;
106
+ this._ids.set(v, id);
107
+ }
108
+ this._goRefCounts[id]++;
109
+ let typeFlag = 1;
110
+ switch (typeof v) {
111
+ case "string":
112
+ typeFlag = 2;
113
+ break;
114
+ case "symbol":
115
+ typeFlag = 3;
116
+ break;
117
+ case "function":
118
+ typeFlag = 4;
119
+ break;
120
+ }
121
+ mem().setUint32(addr + 4, nanHead | typeFlag, true);
122
+ mem().setUint32(addr, id, true);
123
+ };
124
+ const loadSlice = (array, len, cap) => {
125
+ return new Uint8Array(this._inst.exports.memory.buffer, array, len);
126
+ };
127
+ const loadSliceOfValues = (array, len, cap) => {
128
+ const a = new Array(len);
129
+ for (let i = 0; i < len; i++) {
130
+ a[i] = loadValue(array + i * 8);
131
+ }
132
+ return a;
133
+ };
134
+ const loadString = (ptr, len) => {
135
+ return decoder.decode(new DataView(this._inst.exports.memory.buffer, ptr, len));
136
+ };
137
+ const timeOrigin = Date.now() - performance.now();
138
+ this.importObject = {
139
+ wasi_snapshot_preview1: {
140
+ // https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#fd_write
141
+ fd_write: function (fd, iovs_ptr, iovs_len, nwritten_ptr) {
142
+ let nwritten = 0;
143
+ if (fd == 1) {
144
+ for (let iovs_i = 0; iovs_i < iovs_len; iovs_i++) {
145
+ let iov_ptr = iovs_ptr + iovs_i * 8; // assuming wasm32
146
+ let ptr = mem().getUint32(iov_ptr + 0, true);
147
+ let len = mem().getUint32(iov_ptr + 4, true);
148
+ for (let i = 0; i < len; i++) {
149
+ let c = mem().getUint8(ptr + i);
150
+ if (c == 13) {
151
+ // CR
152
+ // ignore
153
+ }
154
+ else if (c == 10) {
155
+ // LF
156
+ // write line
157
+ let line = decoder.decode(new Uint8Array(logLine));
158
+ logLine = [];
159
+ console.log(line);
160
+ }
161
+ else {
162
+ logLine.push(c);
163
+ }
164
+ }
165
+ }
166
+ }
167
+ else {
168
+ console.error("invalid file descriptor:", fd);
169
+ }
170
+ mem().setUint32(nwritten_ptr, nwritten, true);
171
+ return 0;
172
+ },
173
+ proc_exit: (code) => {
174
+ if (globalThis.process) {
175
+ // Node.js
176
+ process.exit(code);
177
+ }
178
+ else {
179
+ // Can't exit in a browser.
180
+ throw "trying to exit with code " + code;
181
+ }
182
+ },
183
+ },
184
+ env: {
185
+ // func ticks() float64
186
+ "runtime.ticks": () => {
187
+ return timeOrigin + performance.now();
188
+ },
189
+ // func sleepTicks(timeout float64)
190
+ "runtime.sleepTicks": (timeout) => {
191
+ // Do not sleep, only reactivate scheduler after the given timeout.
192
+ setTimeout(this._inst.exports.go_scheduler, timeout);
193
+ },
194
+ // func finalizeRef(v ref)
195
+ "syscall/js.finalizeRef": (v_addr) => {
196
+ // Note: TinyGo does not support finalizers so this is only called
197
+ // for one specific case, by js.go:jsString.
198
+ const id = mem().getUint32(v_addr, true);
199
+ this._goRefCounts[id]--;
200
+ if (this._goRefCounts[id] === 0) {
201
+ const v = this._values[id];
202
+ this._values[id] = null;
203
+ this._ids.delete(v);
204
+ this._idPool.push(id);
205
+ }
206
+ },
207
+ // func stringVal(value string) ref
208
+ "syscall/js.stringVal": (ret_ptr, value_ptr, value_len) => {
209
+ const s = loadString(value_ptr, value_len);
210
+ storeValue(ret_ptr, s);
211
+ },
212
+ // func valueGet(v ref, p string) ref
213
+ "syscall/js.valueGet": (retval, v_addr, p_ptr, p_len) => {
214
+ let prop = loadString(p_ptr, p_len);
215
+ let value = loadValue(v_addr);
216
+ let result = Reflect.get(value, prop);
217
+ storeValue(retval, result);
218
+ },
219
+ // func valueSet(v ref, p string, x ref)
220
+ "syscall/js.valueSet": (v_addr, p_ptr, p_len, x_addr) => {
221
+ const v = loadValue(v_addr);
222
+ const p = loadString(p_ptr, p_len);
223
+ const x = loadValue(x_addr);
224
+ Reflect.set(v, p, x);
225
+ },
226
+ // func valueDelete(v ref, p string)
227
+ "syscall/js.valueDelete": (v_addr, p_ptr, p_len) => {
228
+ const v = loadValue(v_addr);
229
+ const p = loadString(p_ptr, p_len);
230
+ Reflect.deleteProperty(v, p);
231
+ },
232
+ // func valueIndex(v ref, i int) ref
233
+ "syscall/js.valueIndex": (ret_addr, v_addr, i) => {
234
+ storeValue(ret_addr, Reflect.get(loadValue(v_addr), i));
235
+ },
236
+ // valueSetIndex(v ref, i int, x ref)
237
+ "syscall/js.valueSetIndex": (v_addr, i, x_addr) => {
238
+ Reflect.set(loadValue(v_addr), i, loadValue(x_addr));
239
+ },
240
+ // func valueCall(v ref, m string, args []ref) (ref, bool)
241
+ "syscall/js.valueCall": (ret_addr, v_addr, m_ptr, m_len, args_ptr, args_len, args_cap) => {
242
+ const v = loadValue(v_addr);
243
+ const name = loadString(m_ptr, m_len);
244
+ const args = loadSliceOfValues(args_ptr, args_len, args_cap);
245
+ try {
246
+ const m = Reflect.get(v, name);
247
+ storeValue(ret_addr, Reflect.apply(m, v, args));
248
+ mem().setUint8(ret_addr + 8, 1);
249
+ }
250
+ catch (err) {
251
+ storeValue(ret_addr, err);
252
+ mem().setUint8(ret_addr + 8, 0);
253
+ }
254
+ },
255
+ // func valueInvoke(v ref, args []ref) (ref, bool)
256
+ "syscall/js.valueInvoke": (ret_addr, v_addr, args_ptr, args_len, args_cap) => {
257
+ try {
258
+ const v = loadValue(v_addr);
259
+ const args = loadSliceOfValues(args_ptr, args_len, args_cap);
260
+ storeValue(ret_addr, Reflect.apply(v, undefined, args));
261
+ mem().setUint8(ret_addr + 8, 1);
262
+ }
263
+ catch (err) {
264
+ storeValue(ret_addr, err);
265
+ mem().setUint8(ret_addr + 8, 0);
266
+ }
267
+ },
268
+ // func valueNew(v ref, args []ref) (ref, bool)
269
+ "syscall/js.valueNew": (ret_addr, v_addr, args_ptr, args_len, args_cap) => {
270
+ const v = loadValue(v_addr);
271
+ const args = loadSliceOfValues(args_ptr, args_len, args_cap);
272
+ try {
273
+ storeValue(ret_addr, Reflect.construct(v, args));
274
+ mem().setUint8(ret_addr + 8, 1);
275
+ }
276
+ catch (err) {
277
+ storeValue(ret_addr, err);
278
+ mem().setUint8(ret_addr + 8, 0);
279
+ }
280
+ },
281
+ // func valueLength(v ref) int
282
+ "syscall/js.valueLength": (v_addr) => {
283
+ return loadValue(v_addr).length;
284
+ },
285
+ // valuePrepareString(v ref) (ref, int)
286
+ "syscall/js.valuePrepareString": (ret_addr, v_addr) => {
287
+ const s = String(loadValue(v_addr));
288
+ const str = encoder.encode(s);
289
+ storeValue(ret_addr, str);
290
+ setInt64(ret_addr + 8, str.length);
291
+ },
292
+ // valueLoadString(v ref, b []byte)
293
+ "syscall/js.valueLoadString": (v_addr, slice_ptr, slice_len, slice_cap) => {
294
+ const str = loadValue(v_addr);
295
+ loadSlice(slice_ptr, slice_len, slice_cap).set(str);
296
+ },
297
+ // func valueInstanceOf(v ref, t ref) bool
298
+ "syscall/js.valueInstanceOf": (v_addr, t_addr) => {
299
+ return loadValue(v_addr) instanceof loadValue(t_addr);
300
+ },
301
+ // func copyBytesToGo(dst []byte, src ref) (int, bool)
302
+ "syscall/js.copyBytesToGo": (ret_addr, dest_addr, dest_len, dest_cap, source_addr) => {
303
+ let num_bytes_copied_addr = ret_addr;
304
+ let returned_status_addr = ret_addr + 4; // Address of returned boolean status variable
305
+ const dst = loadSlice(dest_addr, dest_len);
306
+ const src = loadValue(source_addr);
307
+ if (!(src instanceof Uint8Array)) {
308
+ mem().setUint8(returned_status_addr, 0); // Return "not ok" status
309
+ return;
310
+ }
311
+ const toCopy = src.subarray(0, dst.length);
312
+ dst.set(toCopy);
313
+ setInt64(num_bytes_copied_addr, toCopy.length);
314
+ mem().setUint8(returned_status_addr, 1); // Return "ok" status
315
+ },
316
+ // copyBytesToJS(dst ref, src []byte) (int, bool)
317
+ // Originally copied from upstream Go project, then modified:
318
+ // https://github.com/golang/go/blob/3f995c3f3b43033013013e6c7ccc93a9b1411ca9/misc/wasm/wasm_exec.js#L404-L416
319
+ "syscall/js.copyBytesToJS": (ret_addr, dest_addr, source_addr, source_len, source_cap) => {
320
+ let num_bytes_copied_addr = ret_addr;
321
+ let returned_status_addr = ret_addr + 4; // Address of returned boolean status variable
322
+ const dst = loadValue(dest_addr);
323
+ const src = loadSlice(source_addr, source_len);
324
+ if (!(dst instanceof Uint8Array)) {
325
+ mem().setUint8(returned_status_addr, 0); // Return "not ok" status
326
+ return;
327
+ }
328
+ const toCopy = src.subarray(0, dst.length);
329
+ dst.set(toCopy);
330
+ setInt64(num_bytes_copied_addr, toCopy.length);
331
+ mem().setUint8(returned_status_addr, 1); // Return "ok" status
332
+ },
333
+ },
334
+ };
335
+ }
336
+ async run(instance) {
337
+ this._inst = instance;
338
+ this._values = [
339
+ // JS values that Go currently has references to, indexed by reference id
340
+ NaN,
341
+ 0,
342
+ null,
343
+ true,
344
+ false,
345
+ globalThis,
346
+ this,
347
+ ];
348
+ this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference id
349
+ this._ids = new Map(); // mapping from JS values to reference ids
350
+ this._idPool = []; // unused ids that have been garbage collected
351
+ this.exited = false; // whether the Go program has exited
352
+ const mem = new DataView(this._inst.exports.memory.buffer);
353
+ while (true) {
354
+ const callbackPromise = new Promise((resolve) => {
355
+ this._resolveCallbackPromise = () => {
356
+ if (this.exited) {
357
+ throw new Error("bad callback: Go program has already exited");
358
+ }
359
+ setTimeout(resolve, 0); // make sure it is asynchronous
360
+ };
361
+ });
362
+ this._inst.exports._start();
363
+ if (this.exited) {
364
+ break;
365
+ }
366
+ await callbackPromise;
367
+ }
368
+ }
369
+ _resume() {
370
+ if (this.exited) {
371
+ throw new Error("Go program has already exited");
372
+ }
373
+ this._inst.exports.resume();
374
+ if (this.exited) {
375
+ this._resolveExitPromise();
376
+ }
377
+ }
378
+ _makeFuncWrapper(id) {
379
+ const go = this;
380
+ return function () {
381
+ const event = { id: id, this: this, args: arguments };
382
+ go._pendingEvent = event;
383
+ go._resume();
384
+ return event.result;
385
+ };
386
+ }
387
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@astrojs/compiler",
3
3
  "type": "module",
4
- "version": "0.1.4",
4
+ "version": "0.1.9",
5
5
  "scripts": {
6
6
  "build": "tsc -p ."
7
7
  },
@@ -0,0 +1,18 @@
1
+ export interface TransformOptions {
2
+ sourcefile?: string;
3
+ internalURL?: string;
4
+ sourcemap?: boolean | 'inline' | 'external' | 'both';
5
+ as?: 'document' | 'fragment';
6
+ }
7
+ export interface TransformResult {
8
+ code: string;
9
+ map: string;
10
+ warnings: any[];
11
+ }
12
+ export declare function transform(input: string, options?: TransformOptions): Promise<TransformResult>;
13
+ export declare function compile(input: string, options?: TransformOptions): Promise<TransformResult>;
14
+ export declare function initialize(options: InitializeOptions): Promise<void>;
15
+ export interface InitializeOptions {
16
+ wasmURL?: string;
17
+ worker?: boolean;
18
+ }
@@ -0,0 +1 @@
1
+ export {};