fullstacked 1.0.0-alpha.1748 → 1.0.0-alpha.1753

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/index.js CHANGED
@@ -159,8 +159,8 @@ async function BridgeNodeInit() {
159
159
  async Async(payload) {
160
160
  const dataView = new DataView(payload);
161
161
  const id = dataView.getUint8(1);
162
- return new Promise((resolve2) => {
163
- asyncResponsePromises3.set(id, resolve2);
162
+ return new Promise((resolve3) => {
163
+ asyncResponsePromises3.set(id, resolve3);
164
164
  globalThis.postMessage(payload);
165
165
  });
166
166
  }
@@ -182,6 +182,12 @@ async function BridgeNodeInit() {
182
182
  ws.onopen = res;
183
183
  });
184
184
  await webSocketForCallback;
185
+ globalThis.fullstacked.open = function(ctx2) {
186
+ return globalThis.fullstacked.fetch("/open", {
187
+ method: "POST",
188
+ body: new Uint8Array([ctx2])
189
+ });
190
+ };
185
191
  globalThis.fullstacked.exit = function() {
186
192
  ws.close();
187
193
  if (window.opener || window.history && window.history.length === 1) {
@@ -250,6 +256,7 @@ async function BridgeAppleInit() {
250
256
  };
251
257
  } else {
252
258
  globalThis.fullstacked.exit = () => globalThis.webkit.messageHandlers.exit.postMessage("");
259
+ globalThis.fullstacked.open = (ctx2) => globalThis.webkit.messageHandlers.open.postMessage(ctx2);
253
260
  if (globalThis.webkit.messageHandlers.clipboard) {
254
261
  const td2 = new TextDecoder();
255
262
  globalThis.fullstacked.clipboard.respondPaste = (id, responseBase64) => {
@@ -259,8 +266,8 @@ async function BridgeAppleInit() {
259
266
  };
260
267
  globalThis.fullstacked.clipboard.paste = () => {
261
268
  const id = Math.floor(Math.random() * 1e6);
262
- return new Promise((resolve2) => {
263
- clipboardResponsePromises.set(id, resolve2);
269
+ return new Promise((resolve3) => {
270
+ clipboardResponsePromises.set(id, resolve3);
264
271
  globalThis.webkit.messageHandlers.clipboard.postMessage(
265
272
  id.toString()
266
273
  );
@@ -276,15 +283,15 @@ async function BridgeAppleInit() {
276
283
  if (globalThis.webkit.messageHandlers.resize) {
277
284
  const resizeResponsePromises = [];
278
285
  globalThis.fullstacked.window.respondGetSize = function(response) {
279
- const resolve2 = resizeResponsePromises.shift();
280
- resolve2?.(response);
286
+ const resolve3 = resizeResponsePromises.shift();
287
+ resolve3?.(response);
281
288
  };
282
289
  globalThis.fullstacked.window.resize = function(size) {
283
290
  globalThis.webkit.messageHandlers.resize.postMessage(size);
284
291
  };
285
292
  globalThis.fullstacked.window.getSize = function() {
286
- return new Promise((resolve2) => {
287
- resizeResponsePromises.push(resolve2);
293
+ return new Promise((resolve3) => {
294
+ resizeResponsePromises.push(resolve3);
288
295
  globalThis.webkit.messageHandlers.resize.postMessage("get");
289
296
  });
290
297
  };
@@ -295,8 +302,8 @@ async function BridgeAppleInit() {
295
302
  async Async(payload) {
296
303
  const dataView = new DataView(payload);
297
304
  const id = dataView.getUint8(1);
298
- return new Promise((resolve2) => {
299
- asyncResponsePromises.set(id, resolve2);
305
+ return new Promise((resolve3) => {
306
+ asyncResponsePromises.set(id, resolve3);
300
307
  if (isWorker) {
301
308
  globalThis.postMessage(payload, {
302
309
  targetOrigin: "bridge"
@@ -362,6 +369,7 @@ async function BridgeWindowsInit() {
362
369
  };
363
370
  } else {
364
371
  globalThis.fullstacked.exit = () => globalThis.fullstacked.fetch("/exit");
372
+ globalThis.fullstacked.open = (ctx2) => globalThis.fullstacked.fetch(`/open?ctx=${ctx2}`);
365
373
  globalThis.fullstacked.window.getSize = () => globalThis.fullstacked.fetch("/resize").then((r) => r.text());
366
374
  globalThis.fullstacked.window.resize = function(size) {
367
375
  globalThis.fullstacked.fetch(`/resize?size=${size}`);
@@ -372,8 +380,8 @@ async function BridgeWindowsInit() {
372
380
  async Async(payload) {
373
381
  const dataView = new DataView(payload);
374
382
  const id = dataView.getUint8(1);
375
- return new Promise((resolve2) => {
376
- asyncResponsePromises2.set(id, resolve2);
383
+ return new Promise((resolve3) => {
384
+ asyncResponsePromises2.set(id, resolve3);
377
385
  if (isWorker) {
378
386
  globalThis.postMessage(payload, {
379
387
  targetOrigin: "bridge"
@@ -449,7 +457,7 @@ var init_platform = __esm({
449
457
  } else {
450
458
  globalThis.global = globalThis;
451
459
  platformBridge = {
452
- ready: new Promise(async (resolve2, reject) => {
460
+ ready: new Promise(async (resolve3, reject) => {
453
461
  if (isWorker) {
454
462
  await new Promise((workerReady) => {
455
463
  self.onmessage = () => workerReady();
@@ -479,7 +487,7 @@ var init_platform = __esm({
479
487
  platformBridge.bridge = await BridgeWindowsInit();
480
488
  break;
481
489
  }
482
- resolve2();
490
+ resolve3();
483
491
  })
484
492
  };
485
493
  }
@@ -495,6 +503,7 @@ var Path = 4;
495
503
  var Os = 5;
496
504
  var Fetch = 8;
497
505
  var Bundle = 9;
506
+ var Packages = 12;
498
507
  var Plugin = 14;
499
508
  var CoreResponseError = 0;
500
509
  var CoreResponseData = 1;
@@ -927,8 +936,8 @@ function createDuplex(id) {
927
936
  return duplex.opening;
928
937
  };
929
938
  const read = () => {
930
- return new Promise((resolve2, reject) => {
931
- duplex.asyncRead.promise = { resolve: resolve2, reject };
939
+ return new Promise((resolve3, reject) => {
940
+ duplex.asyncRead.promise = { resolve: resolve3, reject };
932
941
  });
933
942
  };
934
943
  const next = async () => {
@@ -1029,10 +1038,10 @@ function createDuplex(id) {
1029
1038
  if (duplex.done) {
1030
1039
  return res;
1031
1040
  }
1032
- await new Promise((resolve2) => {
1041
+ await new Promise((resolve3) => {
1033
1042
  const onClose = () => {
1034
1043
  duplex.listeners.close.delete(onClose);
1035
- resolve2();
1044
+ resolve3();
1036
1045
  };
1037
1046
  duplex.listeners.close.add(onClose);
1038
1047
  });
@@ -1137,7 +1146,7 @@ async function fetchCore(request, init2) {
1137
1146
  signal.addEventListener("abort", onAbort, { once: true });
1138
1147
  }
1139
1148
  try {
1140
- responseHead = await new Promise(async (resolve2, reject) => {
1149
+ responseHead = await new Promise(async (resolve3, reject) => {
1141
1150
  rejectHead = reject;
1142
1151
  responseHeadEE = (await globalThis.fullstacked.bridge({
1143
1152
  mod: Fetch,
@@ -1145,7 +1154,7 @@ async function fetchCore(request, init2) {
1145
1154
  data: [requestHead, new Uint8Array(requestBody)]
1146
1155
  })).eventEmitter();
1147
1156
  responseHeadEE.on("response", (responseHead2) => {
1148
- resolve2(responseHead2);
1157
+ resolve3(responseHead2);
1149
1158
  });
1150
1159
  responseHeadEE.on("error", (error) => {
1151
1160
  reject(error);
@@ -1287,8 +1296,8 @@ var Exit = 5;
1287
1296
  // ../../core/internal/bundle/lib/process/index.ts
1288
1297
  init_isWorker();
1289
1298
 
1290
- // ../../core/internal/bundle/lib/process/version.json with { type: 'json' }
1291
- var version_default = { major: "1", minor: "0", patch: "0-alpha", branch: "v1", build: "1748", hash: "7c960ea337e7106b199163dff256a67ddd78f29d" };
1299
+ // ../../core/internal/bundle/lib/process/version.json
1300
+ var version_default = { major: "1", minor: "0", patch: "0-alpha", branch: "v1", build: "1753", hash: "8e2b475d51b7c4ecbbd84a6a76174572246a7169" };
1292
1301
 
1293
1302
  // ../../core/internal/bundle/lib/timers/index.ts
1294
1303
  var setTimeout2 = globalThis.setTimeout.bind(globalThis);
@@ -1634,8 +1643,8 @@ var constants = {
1634
1643
  return sep;
1635
1644
  }
1636
1645
  };
1637
- function isAbsolute(path6) {
1638
- return path6.startsWith("/") || path6.startsWith("\\") || /^[a-zA-Z]:[/\\]/.test(path6);
1646
+ function isAbsolute(path3) {
1647
+ return path3.startsWith("/") || path3.startsWith("\\") || /^[a-zA-Z]:[/\\]/.test(path3);
1639
1648
  }
1640
1649
  function resolve(...paths) {
1641
1650
  if (paths[0].startsWith("build:")) {
@@ -1662,34 +1671,34 @@ function join(...paths) {
1662
1671
  true
1663
1672
  );
1664
1673
  }
1665
- function normalize(path6) {
1674
+ function normalize(path3) {
1666
1675
  return globalThis.fullstacked.bridge(
1667
1676
  {
1668
1677
  mod: Path,
1669
1678
  fn: Normalize,
1670
- data: [path6]
1679
+ data: [path3]
1671
1680
  },
1672
1681
  true
1673
1682
  );
1674
1683
  }
1675
- function parse(path6) {
1684
+ function parse(path3) {
1676
1685
  return globalThis.fullstacked.bridge(
1677
1686
  {
1678
1687
  mod: Path,
1679
1688
  fn: Parse,
1680
- data: [path6]
1689
+ data: [path3]
1681
1690
  },
1682
1691
  true
1683
1692
  );
1684
1693
  }
1685
- function extname(path6) {
1686
- return parse(path6).ext;
1694
+ function extname(path3) {
1695
+ return parse(path3).ext;
1687
1696
  }
1688
- function dirname(path6) {
1689
- return parse(path6).dir;
1697
+ function dirname(path3) {
1698
+ return parse(path3).dir;
1690
1699
  }
1691
- function basename(path6, suffix) {
1692
- const base = parse(path6).base;
1700
+ function basename(path3, suffix) {
1701
+ const base = parse(path3).base;
1693
1702
  if (suffix && base.endsWith(suffix)) {
1694
1703
  return base.slice(0, 0 - suffix.length);
1695
1704
  }
@@ -1723,8 +1732,8 @@ var path_default = mod;
1723
1732
 
1724
1733
  // ../../core/internal/bundle/lib/fs/common.ts
1725
1734
  init_base64();
1726
- function formatPathLike(path6) {
1727
- const pathStr = path6 instanceof URL ? path6.pathname : path6.toString();
1735
+ function formatPathLike(path3) {
1736
+ const pathStr = path3 instanceof URL ? path3.pathname : path3.toString();
1728
1737
  return pathStr;
1729
1738
  }
1730
1739
  function decodeStringData(data, options) {
@@ -1776,16 +1785,16 @@ function convertGoFileInfo(baseDir, items, withFileTypes) {
1776
1785
  }
1777
1786
 
1778
1787
  // ../../core/internal/bundle/lib/fs/promises.ts
1779
- async function readFile(path6, options) {
1788
+ async function readFile(path3, options) {
1780
1789
  const data = await globalThis.fullstacked.bridge({
1781
1790
  mod: Fs,
1782
1791
  fn: ReadFile,
1783
- data: [formatPathLike(path6)]
1792
+ data: [formatPathLike(path3)]
1784
1793
  });
1785
1794
  return decodeStringData(data, options);
1786
1795
  }
1787
- async function readdir(path6, options) {
1788
- const baseDir = formatPathLike(path6);
1796
+ async function readdir(path3, options) {
1797
+ const baseDir = formatPathLike(path3);
1789
1798
  const items = await globalThis.fullstacked.bridge({
1790
1799
  mod: Fs,
1791
1800
  fn: ReadDir,
@@ -1793,54 +1802,54 @@ async function readdir(path6, options) {
1793
1802
  });
1794
1803
  return convertGoFileInfo(baseDir, items, options?.withFileTypes);
1795
1804
  }
1796
- async function stat(path6, options) {
1805
+ async function stat(path3, options) {
1797
1806
  const fileInfo = await globalThis.fullstacked.bridge({
1798
1807
  mod: Fs,
1799
1808
  fn: Stats,
1800
- data: [formatPathLike(path6)]
1809
+ data: [formatPathLike(path3)]
1801
1810
  });
1802
1811
  return fileInfoToStat(fileInfo);
1803
1812
  }
1804
- function writeFile(path6, data) {
1813
+ function writeFile(path3, data) {
1805
1814
  return globalThis.fullstacked.bridge({
1806
1815
  mod: Fs,
1807
1816
  fn: WriteFile,
1808
- data: [formatPathLike(path6), data]
1817
+ data: [formatPathLike(path3), data]
1809
1818
  });
1810
1819
  }
1811
- function appendFile(path6, data) {
1820
+ function appendFile(path3, data) {
1812
1821
  return globalThis.fullstacked.bridge({
1813
1822
  mod: Fs,
1814
1823
  fn: AppendFile,
1815
- data: [formatPathLike(path6), data]
1824
+ data: [formatPathLike(path3), data]
1816
1825
  });
1817
1826
  }
1818
- function mkdir(path6) {
1827
+ function mkdir(path3) {
1819
1828
  return globalThis.fullstacked.bridge({
1820
1829
  mod: Fs,
1821
1830
  fn: Mkdir,
1822
- data: [formatPathLike(path6)]
1831
+ data: [formatPathLike(path3)]
1823
1832
  });
1824
1833
  }
1825
- function rm(path6) {
1834
+ function rm(path3) {
1826
1835
  return globalThis.fullstacked.bridge({
1827
1836
  mod: Fs,
1828
1837
  fn: Rm,
1829
- data: [formatPathLike(path6)]
1838
+ data: [formatPathLike(path3)]
1830
1839
  });
1831
1840
  }
1832
- function unlink(path6) {
1841
+ function unlink(path3) {
1833
1842
  return globalThis.fullstacked.bridge({
1834
1843
  mod: Fs,
1835
1844
  fn: Rm,
1836
- data: [formatPathLike(path6)]
1845
+ data: [formatPathLike(path3)]
1837
1846
  });
1838
1847
  }
1839
- function rename(path6, path22) {
1848
+ function rename(path3, path22) {
1840
1849
  return globalThis.fullstacked.bridge({
1841
1850
  mod: Fs,
1842
1851
  fn: Rename,
1843
- data: [formatPathLike(path6), formatPathLike(path22)]
1852
+ data: [formatPathLike(path3), formatPathLike(path22)]
1844
1853
  });
1845
1854
  }
1846
1855
  function cp(src, dst) {
@@ -1864,50 +1873,50 @@ var promises_default = {
1864
1873
  };
1865
1874
 
1866
1875
  // ../../core/internal/bundle/lib/fs/index.ts
1867
- function existsSync(path6) {
1876
+ function existsSync(path3) {
1868
1877
  return globalThis.fullstacked.bridge(
1869
1878
  {
1870
1879
  mod: Fs,
1871
1880
  fn: Exists,
1872
- data: [formatPathLike(path6)]
1881
+ data: [formatPathLike(path3)]
1873
1882
  },
1874
1883
  true
1875
1884
  );
1876
1885
  }
1877
- function statSync(path6, options) {
1886
+ function statSync(path3, options) {
1878
1887
  const fileInfo = globalThis.fullstacked.bridge(
1879
1888
  {
1880
1889
  mod: Fs,
1881
1890
  fn: Stats,
1882
- data: [formatPathLike(path6)]
1891
+ data: [formatPathLike(path3)]
1883
1892
  },
1884
1893
  true
1885
1894
  );
1886
1895
  return fileInfoToStat(fileInfo);
1887
1896
  }
1888
- function stat2(path6, options, callback) {
1897
+ function stat2(path3, options, callback) {
1889
1898
  const cb = typeof options === "function" ? options : callback;
1890
1899
  const opts = typeof options === "function" ? null : options;
1891
- promises_default.stat(formatPathLike(path6), opts).then((stats) => cb(null, stats)).catch((e) => cb(e, null));
1900
+ promises_default.stat(formatPathLike(path3), opts).then((stats) => cb(null, stats)).catch((e) => cb(e, null));
1892
1901
  }
1893
- function readFileSync(path6, options) {
1902
+ function readFileSync(path3, options) {
1894
1903
  const data = globalThis.fullstacked.bridge(
1895
1904
  {
1896
1905
  mod: Fs,
1897
1906
  fn: ReadFile,
1898
- data: [formatPathLike(path6)]
1907
+ data: [formatPathLike(path3)]
1899
1908
  },
1900
1909
  true
1901
1910
  );
1902
1911
  return decodeStringData(data, options);
1903
1912
  }
1904
- function readFile2(path6, options, callback) {
1913
+ function readFile2(path3, options, callback) {
1905
1914
  const cb = typeof options === "function" ? options : callback;
1906
1915
  const opts = typeof options === "function" ? null : options;
1907
- promises_default.readFile(formatPathLike(path6), opts).then((data) => cb(null, data)).catch((e) => cb(e, null));
1916
+ promises_default.readFile(formatPathLike(path3), opts).then((data) => cb(null, data)).catch((e) => cb(e, null));
1908
1917
  }
1909
- function readdirSync(path6, options) {
1910
- const baseDir = formatPathLike(path6);
1918
+ function readdirSync(path3, options) {
1919
+ const baseDir = formatPathLike(path3);
1911
1920
  const items = globalThis.fullstacked.bridge(
1912
1921
  {
1913
1922
  mod: Fs,
@@ -1918,10 +1927,10 @@ function readdirSync(path6, options) {
1918
1927
  );
1919
1928
  return convertGoFileInfo(baseDir, items, options?.withFileTypes);
1920
1929
  }
1921
- function readdir2(path6, options, callback) {
1930
+ function readdir2(path3, options, callback) {
1922
1931
  const cb = typeof options === "function" ? options : callback;
1923
1932
  const opts = typeof options === "function" ? {} : options;
1924
- const baseDir = formatPathLike(path6);
1933
+ const baseDir = formatPathLike(path3);
1925
1934
  globalThis.fullstacked.bridge({
1926
1935
  mod: Fs,
1927
1936
  fn: ReadDir,
@@ -1933,86 +1942,86 @@ function readdir2(path6, options, callback) {
1933
1942
  )
1934
1943
  ).catch((e) => cb(e, null));
1935
1944
  }
1936
- function mkdirSync(path6) {
1945
+ function mkdirSync(path3) {
1937
1946
  return globalThis.fullstacked.bridge(
1938
1947
  {
1939
1948
  mod: Fs,
1940
1949
  fn: Mkdir,
1941
- data: [formatPathLike(path6)]
1950
+ data: [formatPathLike(path3)]
1942
1951
  },
1943
1952
  true
1944
1953
  );
1945
1954
  }
1946
- async function mkdir2(path6, callback) {
1947
- promises_default.mkdir(path6).then(() => callback(null)).catch((e) => callback(e));
1955
+ async function mkdir2(path3, callback) {
1956
+ promises_default.mkdir(path3).then(() => callback(null)).catch((e) => callback(e));
1948
1957
  }
1949
- function rmSync(path6) {
1958
+ function rmSync(path3) {
1950
1959
  return globalThis.fullstacked.bridge(
1951
1960
  {
1952
1961
  mod: Fs,
1953
1962
  fn: Rm,
1954
- data: [formatPathLike(path6)]
1963
+ data: [formatPathLike(path3)]
1955
1964
  },
1956
1965
  true
1957
1966
  );
1958
1967
  }
1959
- async function rm2(path6, callback) {
1960
- promises_default.rm(path6).then(() => callback(null)).catch((e) => callback(e));
1968
+ async function rm2(path3, callback) {
1969
+ promises_default.rm(path3).then(() => callback(null)).catch((e) => callback(e));
1961
1970
  }
1962
- function unlinkSync(path6) {
1971
+ function unlinkSync(path3) {
1963
1972
  return globalThis.fullstacked.bridge(
1964
1973
  {
1965
1974
  mod: Fs,
1966
1975
  fn: Rm,
1967
- data: [formatPathLike(path6)]
1976
+ data: [formatPathLike(path3)]
1968
1977
  },
1969
1978
  true
1970
1979
  );
1971
1980
  }
1972
- async function unlink2(path6, callback) {
1973
- promises_default.unlink(path6).then(() => callback(null)).catch((e) => callback(e));
1981
+ async function unlink2(path3, callback) {
1982
+ promises_default.unlink(path3).then(() => callback(null)).catch((e) => callback(e));
1974
1983
  }
1975
- function writeFileSync(path6, data) {
1984
+ function writeFileSync(path3, data) {
1976
1985
  return globalThis.fullstacked.bridge(
1977
1986
  {
1978
1987
  mod: Fs,
1979
1988
  fn: WriteFile,
1980
- data: [formatPathLike(path6), data]
1989
+ data: [formatPathLike(path3), data]
1981
1990
  },
1982
1991
  true
1983
1992
  );
1984
1993
  }
1985
- function writeFile2(path6, data, callback) {
1986
- promises_default.writeFile(path6, data).then(() => callback(null)).catch((e) => callback(e));
1994
+ function writeFile2(path3, data, callback) {
1995
+ promises_default.writeFile(path3, data).then(() => callback(null)).catch((e) => callback(e));
1987
1996
  }
1988
- function appendFileSync(path6, data) {
1997
+ function appendFileSync(path3, data) {
1989
1998
  return globalThis.fullstacked.bridge(
1990
1999
  {
1991
2000
  mod: Fs,
1992
2001
  fn: AppendFile,
1993
- data: [formatPathLike(path6), data]
2002
+ data: [formatPathLike(path3), data]
1994
2003
  },
1995
2004
  true
1996
2005
  );
1997
2006
  }
1998
- function appendFile2(path6, data, callback) {
1999
- promises_default.appendFile(path6, data).then(() => callback(null)).catch((e) => callback(e));
2007
+ function appendFile2(path3, data, callback) {
2008
+ promises_default.appendFile(path3, data).then(() => callback(null)).catch((e) => callback(e));
2000
2009
  }
2001
- function renameSync(path6, path22) {
2010
+ function renameSync(path3, path22) {
2002
2011
  return globalThis.fullstacked.bridge(
2003
2012
  {
2004
2013
  mod: Fs,
2005
2014
  fn: Rename,
2006
- data: [formatPathLike(path6), formatPathLike(path22)]
2015
+ data: [formatPathLike(path3), formatPathLike(path22)]
2007
2016
  },
2008
2017
  true
2009
2018
  );
2010
2019
  }
2011
- function rename2(path6, path22, callback) {
2012
- promises_default.rename(path6, path22).then(() => callback(null)).catch((e) => callback(e));
2020
+ function rename2(path3, path22, callback) {
2021
+ promises_default.rename(path3, path22).then(() => callback(null)).catch((e) => callback(e));
2013
2022
  }
2014
- function realpathSync(path6) {
2015
- return resolve(formatPathLike(path6));
2023
+ function realpathSync(path3) {
2024
+ return resolve(formatPathLike(path3));
2016
2025
  }
2017
2026
  function cpSync(src, dst) {
2018
2027
  return globalThis.fullstacked.bridge(
@@ -2030,12 +2039,12 @@ function cp2(src, dst, callback) {
2030
2039
  var WriteStream = class extends Writable {
2031
2040
  duplex = null;
2032
2041
  eventEmitter = null;
2033
- constructor(path6, options) {
2042
+ constructor(path3, options) {
2034
2043
  super(options);
2035
2044
  globalThis.fullstacked.bridge({
2036
2045
  mod: Fs,
2037
2046
  fn: CreateWriteStream,
2038
- data: [formatPathLike(path6)]
2047
+ data: [formatPathLike(path3)]
2039
2048
  }).then((d) => {
2040
2049
  this.duplex = d;
2041
2050
  this.eventEmitter = d.eventEmitter();
@@ -2075,8 +2084,8 @@ var WriteStream = class extends Writable {
2075
2084
  }
2076
2085
  }
2077
2086
  };
2078
- function createWriteStream(path6, options) {
2079
- return new WriteStream(formatPathLike(path6), options);
2087
+ function createWriteStream(path3, options) {
2088
+ return new WriteStream(formatPathLike(path3), options);
2080
2089
  }
2081
2090
  var fs_default = {
2082
2091
  existsSync,
@@ -2221,7 +2230,7 @@ async function init() {
2221
2230
  }
2222
2231
  return response;
2223
2232
  }
2224
- return new Promise(async (resolve2, reject) => {
2233
+ return new Promise(async (resolve3, reject) => {
2225
2234
  const payload = preparePayload();
2226
2235
  const responseBuffer = await platformBridge2.bridge.Async(
2227
2236
  payload.buffer
@@ -2230,7 +2239,7 @@ async function init() {
2230
2239
  if (response instanceof Error) {
2231
2240
  reject(response);
2232
2241
  } else {
2233
- resolve2(response);
2242
+ resolve3(response);
2234
2243
  }
2235
2244
  });
2236
2245
  };
@@ -2270,327 +2279,323 @@ function processResponse(buffer) {
2270
2279
  throw new Error("don't know how to process response from core");
2271
2280
  }
2272
2281
 
2273
- // src/index.ts
2274
- import path5 from "node:path";
2275
-
2276
- // src/core.ts
2277
- import path2 from "node:path";
2278
- import { createRequire } from "node:module";
2282
+ // ../../core/internal/bundle/lib/@types/bundle.ts
2283
+ var BundleDir = 1;
2284
+ var BundleFile = 2;
2279
2285
 
2280
- // utils.ts
2281
- import os from "node:os";
2282
- import path from "node:path";
2283
- import url from "node:url";
2284
- import fs from "node:fs";
2285
- var platform2 = os.platform();
2286
- var archArgIndex = process.argv.indexOf("--arch");
2287
- var arch2 = archArgIndex === -1 ? os.arch() : process.argv.at(archArgIndex + 1);
2288
- var environment = `${platform2}-${arch2}`;
2289
- var binExtension = platform2 === "win32" ? "dll" : "so";
2290
- var binBasename = `fullstacked.${binExtension}`;
2291
- var bindingBasename = "binding.node";
2292
- var currentDirectory = path.dirname(
2293
- url.fileURLToPath(import.meta.url)
2294
- );
2295
- var packageJson = JSON.parse(
2296
- fs.readFileSync(path.resolve(currentDirectory, "package.json"), "utf-8")
2297
- );
2298
- var binLocations = [
2299
- // flattened dependencies when installed in project
2300
- path.resolve(currentDirectory, "..", "@fullstacked", environment),
2301
- // when installed globally
2302
- path.resolve(currentDirectory, "node_modules", "@fullstacked", environment)
2303
- ];
2286
+ // ../../core/internal/bundle/lib/bundle/index.ts
2287
+ function bundle(entryPoint) {
2288
+ const resolved = path_default.resolve(entryPoint ?? ".");
2289
+ return new Promise(async (resolve3) => {
2290
+ const ee = (await globalThis.fullstacked.bridge({
2291
+ mod: Bundle,
2292
+ fn: BundleDir,
2293
+ data: [resolved]
2294
+ })).eventEmitter();
2295
+ ee.on("result", resolve3);
2296
+ });
2297
+ }
2298
+ function bundleFile(entryPoint) {
2299
+ const resolved = path_default.resolve(entryPoint);
2300
+ return globalThis.fullstacked.bridge({
2301
+ mod: Bundle,
2302
+ fn: BundleFile,
2303
+ data: [resolved]
2304
+ });
2305
+ }
2304
2306
 
2305
- // src/core.ts
2306
- import fs2 from "node:fs";
2307
- globalThis.require = createRequire(import.meta.url);
2308
- var core;
2309
- function findBinLocation() {
2310
- for (const binLocation of binLocations) {
2311
- if (fs2.existsSync(binLocation)) {
2312
- return binLocation;
2313
- }
2314
- }
2315
- return void 0;
2307
+ // ../../core/internal/bundle/lib/run/index.ts
2308
+ async function run(directoryOrOptions) {
2309
+ const directory = typeof directoryOrOptions === "string" ? directoryOrOptions : directoryOrOptions?.directory;
2310
+ const env2 = typeof directoryOrOptions === "object" ? directoryOrOptions.env : void 0;
2311
+ const resolved = path_default.resolve(directory ?? ".");
2312
+ const newCtx = await globalThis.fullstacked.bridge({
2313
+ mod: Core,
2314
+ fn: Run,
2315
+ data: [resolved, env2]
2316
+ });
2317
+ return newCtx;
2316
2318
  }
2317
- function verifyVersion(binLocation) {
2318
- const packageJsonFileBin = path2.resolve(binLocation, "package.json");
2319
- try {
2320
- const packageJsonBin = JSON.parse(
2321
- fs2.readFileSync(packageJsonFileBin, { encoding: "utf-8" })
2322
- );
2323
- return packageJsonBin.version === packageJson.version;
2324
- } catch (e) {
2325
- return false;
2319
+ var run_default = run;
2320
+
2321
+ // ../../core/internal/bundle/lib/@types/plugin.ts
2322
+ var StartPluginStream = 0;
2323
+ var Register = 1;
2324
+ var Unregister = 2;
2325
+
2326
+ // ../../core/internal/bundle/lib/plugin/index.ts
2327
+ var plugins = /* @__PURE__ */ new Map();
2328
+ var duplexStream = null;
2329
+ var eventEmitter = null;
2330
+ var connectionPromise = null;
2331
+ var te3 = new TextEncoder();
2332
+ async function connect() {
2333
+ if (duplexStream) {
2334
+ return;
2326
2335
  }
2336
+ const duplex = await globalThis.fullstacked.bridge({
2337
+ mod: Plugin,
2338
+ fn: StartPluginStream
2339
+ });
2340
+ const emitter = duplex.eventEmitter();
2341
+ const readyPromise = new Promise((resolve3) => {
2342
+ emitter.on("ready", function onReady() {
2343
+ emitter.off("ready", onReady);
2344
+ resolve3();
2345
+ });
2346
+ });
2347
+ await duplex.open();
2348
+ await readyPromise;
2349
+ duplexStream = duplex;
2350
+ eventEmitter = emitter;
2351
+ eventEmitter.on(
2352
+ "plugin-call",
2353
+ async (pluginId, requestId, ...args2) => {
2354
+ let result = null;
2355
+ let errorMsg = null;
2356
+ try {
2357
+ const registeredPlugin = plugins.get(pluginId);
2358
+ if (registeredPlugin) {
2359
+ result = await registeredPlugin.callback(...args2);
2360
+ if (registeredPlugin.type === PluginTypeBuild) {
2361
+ const remappedResult = [];
2362
+ result.forEach(({ outputName, contents }) => {
2363
+ contents = typeof contents === "string" ? te3.encode(contents) : contents;
2364
+ remappedResult.push(outputName, contents);
2365
+ });
2366
+ result = remappedResult;
2367
+ }
2368
+ } else {
2369
+ throw new Error(
2370
+ `No registered plugin found for id: ${pluginId}`
2371
+ );
2372
+ }
2373
+ } catch (err) {
2374
+ errorMsg = err.message || String(err);
2375
+ }
2376
+ if (Array.isArray(result)) {
2377
+ eventEmitter.writeEvent(
2378
+ "plugin-response",
2379
+ pluginId,
2380
+ requestId,
2381
+ errorMsg,
2382
+ ...result
2383
+ );
2384
+ } else {
2385
+ eventEmitter.writeEvent(
2386
+ "plugin-response",
2387
+ pluginId,
2388
+ requestId,
2389
+ errorMsg,
2390
+ result
2391
+ );
2392
+ }
2393
+ }
2394
+ );
2327
2395
  }
2328
- async function load(onStreamData2) {
2329
- const binLocation = findBinLocation();
2330
- if (!binLocation) {
2331
- throw `Cannot find core library. Tried:
2332
- ${binLocations.join("\n")}`;
2333
- }
2334
- if (!verifyVersion(binLocation)) {
2335
- throw `Core library version mismatch. Retry installing fullstacked.`;
2396
+ async function register(type2, plugin2) {
2397
+ if (!connectionPromise) {
2398
+ connectionPromise = connect();
2336
2399
  }
2337
- const libPath = path2.resolve(binLocation, binBasename);
2338
- const bindingPath = path2.resolve(binLocation, bindingBasename);
2339
- core = __require(bindingPath);
2340
- core.load(libPath);
2341
- core.setOnStreamData(onStreamData2);
2342
- return core;
2400
+ await connectionPromise;
2401
+ const { name, ...pluginData } = plugin2.data || {};
2402
+ const id = await globalThis.fullstacked.bridge({
2403
+ mod: Plugin,
2404
+ fn: Register,
2405
+ data: [type2, name || "plugin-" + type2, pluginData]
2406
+ });
2407
+ plugins.set(id, { type: type2, callback: plugin2.callback });
2408
+ return {
2409
+ unregister: async () => {
2410
+ plugins.delete(id);
2411
+ await globalThis.fullstacked.bridge({
2412
+ mod: Plugin,
2413
+ fn: Unregister,
2414
+ data: [id]
2415
+ });
2416
+ }
2417
+ };
2343
2418
  }
2419
+ var plugin = {
2420
+ register
2421
+ };
2422
+ var plugin_default = plugin;
2344
2423
 
2345
- // src/webview.ts
2346
- import http from "node:http";
2347
- import net from "node:net";
2348
- import open from "open";
2349
- import { WebSocketServer } from "ws";
2350
- init_base64();
2351
- var args = process.argv;
2352
- var portIndex = args.findIndex((arg) => arg === "-p" || arg === "--port");
2353
- var mainPort = 9e3;
2354
- if (portIndex !== -1 && args[portIndex + 1]) {
2355
- mainPort = parseInt(args[portIndex + 1]);
2356
- if (isNaN(mainPort)) {
2357
- mainPort = 9e3;
2358
- }
2424
+ // ../../core/internal/bundle/lib/@types/packages.ts
2425
+ var Install = 0;
2426
+ var Uninstall = 1;
2427
+ var Audit = 2;
2428
+ var ResolvePackages = 3;
2429
+ var AddResolveNodePath = 4;
2430
+
2431
+ // ../../core/internal/bundle/lib/packages/index.ts
2432
+ async function install(directory, saveDev, ...packages2) {
2433
+ return (await globalThis.fullstacked.bridge({
2434
+ mod: Packages,
2435
+ fn: Install,
2436
+ data: [directory, saveDev, ...packages2 || []]
2437
+ })).eventEmitter();
2438
+ }
2439
+ async function uninstall(directory, ...packages2) {
2440
+ return (await globalThis.fullstacked.bridge({
2441
+ mod: Packages,
2442
+ fn: Uninstall,
2443
+ data: [directory, ...packages2 || []]
2444
+ })).eventEmitter();
2445
+ }
2446
+ function audit(directory) {
2447
+ return globalThis.fullstacked.bridge({
2448
+ mod: Packages,
2449
+ fn: Audit,
2450
+ data: [directory]
2451
+ });
2359
2452
  }
2360
- var te3 = new TextEncoder();
2361
- async function createWebView(core3, ctx, opts) {
2362
- const port = await getNextAvailablePort(mainPort);
2363
- const server = http.createServer(createHandler(core3, ctx));
2364
- const close = () => {
2365
- core3.stop(ctx);
2366
- server.close();
2367
- opts.didClose?.();
2368
- };
2369
- const webSockets = createWebSocketServer(core3, ctx, server, close);
2370
- const callback = (id, buffer) => {
2371
- const payload = new Uint8Array(buffer.byteLength + 1);
2372
- payload[0] = id;
2373
- payload.set(new Uint8Array(buffer), 1);
2374
- webSockets.forEach((ws) => ws.send(payload));
2375
- };
2376
- server.listen(port);
2377
- if (!opts.quiet) {
2378
- console.log(`Listening at http://localhost:${port}`);
2379
- }
2380
- if (opts.openBrowser) {
2381
- open(`http://localhost:${port}`);
2382
- }
2453
+ function resolve2(moduleName, startDir) {
2454
+ return globalThis.fullstacked.bridge({
2455
+ mod: Packages,
2456
+ fn: ResolvePackages,
2457
+ data: [moduleName, startDir ?? ""]
2458
+ });
2459
+ }
2460
+ function addNodePath(inputPath) {
2461
+ return globalThis.fullstacked.bridge({
2462
+ mod: Packages,
2463
+ fn: AddResolveNodePath,
2464
+ data: [inputPath]
2465
+ });
2466
+ }
2467
+ var packages = {
2468
+ install,
2469
+ uninstall,
2470
+ audit,
2471
+ resolve: resolve2,
2472
+ addNodePath
2473
+ };
2474
+ var packages_default = packages;
2475
+
2476
+ // ../../core/internal/bundle/lib/fullstacked/index.ts
2477
+ function createConsoleStream(consoleFn) {
2478
+ let buffer = "";
2383
2479
  return {
2384
- close,
2385
- port,
2386
- callback
2480
+ write(chunk) {
2481
+ const str = typeof chunk === "string" ? chunk : new TextDecoder().decode(chunk);
2482
+ buffer += str;
2483
+ const lines = buffer.split("\n");
2484
+ buffer = lines.pop() || "";
2485
+ for (const line of lines) {
2486
+ consoleFn(line);
2487
+ }
2488
+ },
2489
+ writeln(msg) {
2490
+ if (buffer) {
2491
+ consoleFn(buffer + msg);
2492
+ buffer = "";
2493
+ } else {
2494
+ consoleFn(msg);
2495
+ }
2496
+ }
2387
2497
  };
2388
2498
  }
2389
- var nextCallId = 0;
2390
- async function coreCall(core3, req) {
2391
- const payload = await readBody(req);
2392
- if (payload.length >= 2) {
2393
- nextCallId = nextCallId % 255 + 1;
2394
- payload[1] = nextCallId;
2499
+ function getWriter(stream) {
2500
+ if (!stream) return (msg) => console.log(msg);
2501
+ if (typeof stream.writeln === "function") {
2502
+ return (msg) => stream.writeln(msg);
2395
2503
  }
2396
- const data = core3.call(payload.buffer);
2397
- return new Uint8Array(data);
2398
- }
2399
- var platform3 = te3.encode("node");
2400
- function createHandler(core3, ctx) {
2401
- return async (req, res) => {
2402
- let [pathname] = req.url.split("?");
2403
- pathname = decodeURI(pathname);
2404
- if (pathname === "/platform") {
2405
- res.writeHead(200, {
2406
- "content-type": "text/plain",
2407
- "content-length": platform3.length
2408
- });
2409
- return res.end(platform3);
2410
- } else if (pathname === "/ctx") {
2411
- const ctxStr = ctx.toString();
2412
- res.writeHead(200, {
2413
- "content-type": "text/plain",
2414
- "content-length": ctxStr.length
2415
- });
2416
- return res.end(ctxStr);
2417
- } else if (pathname === "/call") {
2418
- const payload = await coreCall(core3, req);
2419
- res.writeHead(200, {
2420
- "content-type": "application/octet-stream",
2421
- "content-length": payload.byteLength,
2422
- "cache-control": "no-cache"
2423
- });
2424
- return res.end(payload);
2425
- } else if (pathname === "/sync") {
2426
- const payload = await coreCall(core3, req);
2427
- const b64 = fromByteArray(payload);
2428
- res.writeHead(200, {
2429
- "content-type": "application/octet-stream",
2430
- "content-length": b64.length,
2431
- "cache-control": "no-cache"
2432
- });
2433
- return res.end(b64);
2434
- }
2435
- const staticFile = coreStaticFile(core3, ctx, pathname);
2436
- res.writeHead(staticFile.found ? 200 : 400, {
2437
- "content-type": staticFile.mimeType,
2438
- "content-length": staticFile.data.byteLength,
2439
- "cache-control": "no-cache"
2440
- });
2441
- res.end(staticFile.data);
2442
- };
2443
- }
2444
- function coreStaticFile(core3, ctx, pathname) {
2445
- const pathnameData = te3.encode(pathname);
2446
- const payload = new Uint8Array([
2447
- ctx,
2448
- 0,
2449
- // id
2450
- Core,
2451
- // Module
2452
- StaticFile,
2453
- // Fn
2454
- 0,
2455
- // Async
2456
- STRING,
2457
- ...numberToUint4Bytes(pathnameData.length),
2458
- // arg length
2459
- ...pathnameData
2460
- ]);
2461
- const responseData = core3.call(payload.buffer);
2462
- const response = deserialize(
2463
- responseData.slice(1)
2464
- );
2465
- if (response.data.byteLength === 0) {
2466
- return {
2467
- found: false,
2468
- mimeType: "text/plain",
2469
- data: te3.encode("not found")
2470
- };
2504
+ if (typeof stream.write === "function") {
2505
+ return (msg) => stream.write(
2506
+ typeof msg === "string" && !msg.endsWith("\n") ? msg + "\n" : msg
2507
+ );
2471
2508
  }
2472
- const [mimeType, data] = deserializeAll(response.data.buffer);
2473
- return {
2474
- found: true,
2475
- mimeType,
2476
- data
2477
- };
2478
- }
2479
- function readBody(req) {
2480
- return new Promise((resolve2) => {
2481
- const contentLengthStr = req.headers["content-length"] || "0";
2482
- const contentLength = parseInt(contentLengthStr);
2483
- if (!contentLength) {
2484
- return resolve2(new Uint8Array());
2485
- }
2486
- const body = new Uint8Array(contentLength);
2487
- let i = 0;
2488
- req.on("data", (chunk) => {
2489
- for (let j = 0; j < chunk.byteLength; j++) {
2490
- body[j + i] = chunk[j];
2509
+ return (msg) => console.log(msg);
2510
+ }
2511
+ function formatMessage(msg, isWarning = false) {
2512
+ const color = isWarning ? "\x1B[33m" : "\x1B[31m";
2513
+ const label = isWarning ? "WARNING" : "ERROR";
2514
+ if (typeof msg === "string") {
2515
+ return `${color}${msg}\x1B[0m
2516
+ `;
2517
+ }
2518
+ const text = msg.Text || msg.text;
2519
+ if (text) {
2520
+ let out = `\x1B[1m${color}[${label}]\x1B[0m \x1B[1m${text}\x1B[0m`;
2521
+ const loc = msg.Location || msg.location;
2522
+ if (loc) {
2523
+ const file = loc.File || loc.file;
2524
+ const line = loc.Line || loc.line;
2525
+ const col = loc.Column || loc.column;
2526
+ if (file) {
2527
+ out += `
2528
+ \x1B[90mat ${file}${line !== void 0 ? `:${line}` : ""}${col !== void 0 ? `:${col}` : ""}\x1B[0m`;
2491
2529
  }
2492
- i += chunk.length;
2493
- });
2494
- req.on("end", () => resolve2(body));
2495
- });
2496
- }
2497
- function getNextAvailablePort(port = 9e3, host = "0.0.0.0") {
2498
- return new Promise((resolve2, reject) => {
2499
- const socket = new net.Socket();
2500
- const timeout = () => {
2501
- resolve2(port);
2502
- socket.destroy();
2503
- };
2504
- const next = () => {
2505
- socket.destroy();
2506
- resolve2(getNextAvailablePort(++port));
2507
- };
2508
- setTimeout(timeout, 200);
2509
- socket.on("timeout", timeout);
2510
- socket.on("connect", function() {
2511
- next();
2512
- });
2513
- socket.on("error", function(exception) {
2514
- if (exception.code !== "ECONNREFUSED") {
2515
- reject(exception);
2516
- } else {
2517
- timeout();
2530
+ const lineText = loc.LineText || loc.lineText;
2531
+ if (lineText) {
2532
+ out += `
2533
+ ${lineText}`;
2534
+ if (typeof col === "number" && col > 0) {
2535
+ out += `
2536
+ ${" ".repeat(col - 1)}\x1B[32m^\x1B[0m`;
2537
+ }
2518
2538
  }
2519
- });
2520
- socket.connect(port, host);
2521
- });
2522
- }
2523
- function createWebSocketServer(core3, ctx, server, close) {
2524
- const webSockets = /* @__PURE__ */ new Set();
2525
- const wss = new WebSocketServer({ noServer: true });
2526
- let closeTimeout;
2527
- const onClose = (ws) => {
2528
- webSockets.delete(ws);
2529
- if (!core3.check(ctx)) {
2530
- close();
2531
- } else if (webSockets.size === 0) {
2532
- closeTimeout = setTimeout(close, 5e3);
2533
2539
  }
2534
- };
2535
- const handleUpgrade = (ws) => {
2536
- if (closeTimeout) {
2537
- clearTimeout(closeTimeout);
2538
- closeTimeout = void 0;
2540
+ const notes = msg.Notes || msg.notes;
2541
+ if (Array.isArray(notes)) {
2542
+ notes.forEach((note) => {
2543
+ const noteText = note.Text || note.text;
2544
+ if (noteText) {
2545
+ out += `
2546
+ \x1B[36mNote:\x1B[0m ${noteText}`;
2547
+ }
2548
+ });
2539
2549
  }
2540
- webSockets.add(ws);
2541
- ws.on("close", () => onClose(ws));
2542
- };
2543
- const onUpgrade = (...args2) => {
2544
- wss.handleUpgrade(...args2, handleUpgrade);
2545
- };
2546
- server.on("upgrade", onUpgrade);
2547
- return webSockets;
2550
+ return out + "\n";
2551
+ }
2552
+ return JSON.stringify(msg, null, 2) + "\n";
2548
2553
  }
2549
-
2550
- // ../../core/internal/bundle/lib/process/version.json
2551
- var version_default2 = { major: "1", minor: "0", patch: "0-alpha", branch: "v1", build: "1748", hash: "7c960ea337e7106b199163dff256a67ddd78f29d" };
2552
-
2553
- // src/args.ts
2554
- function findArg(aliases, hasValueOrArgs, customArgs) {
2555
- const hasValue = typeof hasValueOrArgs === "boolean" ? hasValueOrArgs : false;
2556
- const args2 = Array.isArray(hasValueOrArgs) ? hasValueOrArgs : customArgs || process.argv.slice(2);
2554
+ function findArgValues(aliases, args2) {
2557
2555
  const values = [];
2558
- let present = false;
2559
2556
  for (let i = 0; i < args2.length; i++) {
2560
2557
  const arg = args2[i];
2561
2558
  if (aliases.includes(arg)) {
2562
- present = true;
2563
- if (hasValue) {
2564
- const next = args2[i + 1];
2565
- if (next !== void 0 && !next.startsWith("-")) {
2566
- values.push(next);
2567
- i++;
2568
- } else {
2569
- values.push("");
2570
- }
2559
+ const next = args2[i + 1];
2560
+ if (next !== void 0 && !next.startsWith("-")) {
2561
+ values.push(next);
2562
+ i++;
2563
+ } else {
2564
+ values.push("");
2571
2565
  }
2572
- } else if (hasValue) {
2566
+ } else {
2573
2567
  for (const alias of aliases) {
2574
2568
  if (arg.startsWith(alias + "=")) {
2575
2569
  values.push(arg.slice(alias.length + 1));
2576
- present = true;
2577
2570
  break;
2578
2571
  }
2579
2572
  }
2580
2573
  }
2581
2574
  }
2582
- return hasValue ? values : present;
2575
+ return values;
2576
+ }
2577
+ function hasArgFlag(aliases, args2) {
2578
+ for (const arg of args2) {
2579
+ if (aliases.includes(arg)) return true;
2580
+ for (const alias of aliases) {
2581
+ if (arg.startsWith(alias + "=")) return true;
2582
+ }
2583
+ }
2584
+ return false;
2583
2585
  }
2584
- function getPositionalArgs(args2 = process.argv.slice(2)) {
2585
- const positional = [];
2586
+ function getPositionalArgs(args2) {
2587
+ const positionals = [];
2586
2588
  const valueFlags = [
2587
2589
  ["-e", "--env"],
2588
- ["-p", "--port"]
2590
+ ["-p", "--port"],
2591
+ ["-p", "--plugin"],
2592
+ ["-f", "--file"]
2589
2593
  ];
2590
2594
  const booleanFlags = [
2591
2595
  ["-h", "--help"],
2592
2596
  ["-v", "--version"],
2593
2597
  ["-o", "--open"],
2598
+ ["-n", "--no-open"],
2594
2599
  ["-b", "--build"]
2595
2600
  ];
2596
2601
  for (let i = 0; i < args2.length; i++) {
@@ -2620,279 +2625,536 @@ function getPositionalArgs(args2 = process.argv.slice(2)) {
2620
2625
  break;
2621
2626
  }
2622
2627
  }
2623
- if (isValueFlag) {
2624
- continue;
2625
- }
2626
- if (arg.startsWith("-")) {
2627
- continue;
2628
- }
2629
- positional.push(arg);
2628
+ if (isValueFlag) continue;
2629
+ if (arg.startsWith("-")) continue;
2630
+ positionals.push(arg);
2630
2631
  }
2631
- return positional;
2632
- }
2633
-
2634
- // src/run/file.ts
2635
- import path3 from "node:path";
2636
- import fs3 from "node:fs";
2637
- import { pathToFileURL } from "node:url";
2638
-
2639
- // ../../core/internal/bundle/lib/@types/bundle.ts
2640
- var BundleDir = 1;
2641
- var BundleFile = 2;
2642
-
2643
- // ../../core/internal/bundle/lib/bundle/index.ts
2644
- function bundle(entryPoint) {
2645
- const resolved = path_default.resolve(entryPoint ?? ".");
2646
- return new Promise(async (resolve2) => {
2647
- const ee = (await globalThis.fullstacked.bridge({
2648
- mod: Bundle,
2649
- fn: BundleDir,
2650
- data: [resolved]
2651
- })).eventEmitter();
2652
- ee.on("result", resolve2);
2653
- });
2654
- }
2655
- function bundleFile(entryPoint) {
2656
- const resolved = path_default.resolve(entryPoint);
2657
- return globalThis.fullstacked.bridge({
2658
- mod: Bundle,
2659
- fn: BundleFile,
2660
- data: [resolved]
2661
- });
2632
+ return positionals;
2662
2633
  }
2663
-
2664
- // src/run/file.ts
2665
- async function runFile(positionalArgs2, end2) {
2666
- if (positionalArgs2.length === 0) {
2667
- console.error("Error: no file specified.");
2668
- end2(1);
2669
- }
2670
- const scriptFile = positionalArgs2[0];
2671
- const targetFilePath = path3.resolve(scriptFile);
2672
- if (!fs3.existsSync(targetFilePath)) {
2673
- console.error(`Error: file not found: ${scriptFile}`);
2674
- end2(1);
2634
+ async function bundleAndImportFile(file, startDir, writeErr) {
2635
+ if (!file || file.trim() === "") {
2636
+ writeErr(formatMessage("Error: no file specified.", false));
2637
+ return null;
2638
+ }
2639
+ let resolvedPath;
2640
+ try {
2641
+ resolvedPath = await packages_default.resolve(file, startDir);
2642
+ } catch {
2643
+ resolvedPath = file;
2675
2644
  }
2645
+ const targetFilePath = path_default.resolve(resolvedPath);
2646
+ let fileExists = false;
2676
2647
  try {
2677
- const result = await bundleFile(
2678
- path3.relative(process.cwd(), targetFilePath)
2648
+ await fs_default.promises.stat(targetFilePath);
2649
+ fileExists = true;
2650
+ } catch {
2651
+ }
2652
+ if (!fileExists) {
2653
+ writeErr(formatMessage(`Error: file not found: ${file}`, false));
2654
+ return null;
2655
+ }
2656
+ const result = await bundleFile(targetFilePath);
2657
+ if (result.Errors?.length > 0) {
2658
+ result.Errors.forEach((e) => writeErr(formatMessage(e, false)));
2659
+ return null;
2660
+ }
2661
+ const outputFile = result.OutputFiles?.at(0);
2662
+ if (!outputFile) {
2663
+ writeErr(
2664
+ formatMessage(
2665
+ `Error: bundling ${file} produced no output files.`,
2666
+ false
2667
+ )
2679
2668
  );
2680
- if (result.Errors?.length > 0) {
2681
- result.Errors.forEach((e) => {
2682
- if (e.text) {
2683
- let out = e.text;
2684
- if (e.location) {
2685
- out += `
2686
- at ${e.location.file}:${e.location.line}:${e.location.column}`;
2687
- }
2688
- console.error(out);
2689
- } else {
2690
- console.error(e);
2691
- }
2692
- });
2693
- end2(1);
2694
- }
2695
- const outputFile = result.OutputFiles?.at(0);
2696
- if (!outputFile) {
2697
- console.error("Error: no output file generated.");
2698
- end2(1);
2669
+ return null;
2670
+ }
2671
+ let absoluteOutputFile = path_default.resolve(process.cwd(), outputFile);
2672
+ if (os_default.platform() === "win32") {
2673
+ absoluteOutputFile = absoluteOutputFile.replaceAll("\\", "/");
2674
+ absoluteOutputFile = absoluteOutputFile.at(1) === ":" ? absoluteOutputFile.slice(2) : absoluteOutputFile;
2675
+ }
2676
+ const cleanup = async () => {
2677
+ await fs_default.promises.rm(absoluteOutputFile).catch(() => {
2678
+ });
2679
+ };
2680
+ try {
2681
+ const module = await import(absoluteOutputFile);
2682
+ return { module, outputFile: absoluteOutputFile, cleanup };
2683
+ } catch (e) {
2684
+ writeErr(formatMessage(e.stack || e.message || String(e), false));
2685
+ await cleanup();
2686
+ return null;
2687
+ }
2688
+ }
2689
+ async function runFile(file, writeOut, writeErr) {
2690
+ const res = await bundleAndImportFile(file, process.cwd(), writeErr);
2691
+ if (!res) return 1;
2692
+ await res.cleanup();
2693
+ return 0;
2694
+ }
2695
+ async function runDirectory(positionals, pluginsArgs, buildOnly, noOpen, env2, writeOut, writeErr) {
2696
+ const targetDirectory = path_default.resolve(positionals.at(-1) || ".");
2697
+ const buildPlugins = [];
2698
+ const tempPluginFiles = [];
2699
+ const cleanupPlugins = async () => {
2700
+ for (const bp of buildPlugins) {
2701
+ try {
2702
+ await bp.unregister();
2703
+ } catch {
2704
+ }
2699
2705
  }
2700
- const absoluteOutputFile = path3.resolve(outputFile);
2701
- const cleanup = () => {
2706
+ for (const tempFile of tempPluginFiles) {
2702
2707
  try {
2703
- const resolved = __require.resolve(absoluteOutputFile);
2704
- delete __require.cache[resolved];
2708
+ await fs_default.promises.rm(tempFile).catch(() => {
2709
+ });
2705
2710
  } catch {
2706
2711
  }
2707
- return fs3.promises.rm(absoluteOutputFile).catch(() => {
2708
- });
2709
- };
2710
- process.argv = [
2711
- process.argv[0],
2712
- targetFilePath,
2713
- ...positionalArgs2.slice(1)
2714
- ];
2712
+ }
2713
+ };
2714
+ for (const pluginName of pluginsArgs) {
2715
+ if (!pluginName) continue;
2716
+ const res = await bundleAndImportFile(
2717
+ pluginName,
2718
+ targetDirectory,
2719
+ writeErr
2720
+ );
2721
+ if (!res) {
2722
+ await cleanupPlugins();
2723
+ return 1;
2724
+ }
2725
+ tempPluginFiles.push(res.outputFile);
2715
2726
  try {
2716
- await import(pathToFileURL(absoluteOutputFile).href);
2727
+ const pluginModule = res.module.default || res.module;
2728
+ const registeredPlugin = await plugin_default.register(
2729
+ "build",
2730
+ pluginModule
2731
+ );
2732
+ if (registeredPlugin) {
2733
+ buildPlugins.push(registeredPlugin);
2734
+ }
2717
2735
  } catch (e) {
2718
- console.error(e.stack || e.message || String(e));
2719
- await cleanup();
2720
- end2(1);
2736
+ writeErr(
2737
+ formatMessage(
2738
+ `Error loading plugin ${pluginName}: ${e.message}`,
2739
+ false
2740
+ )
2741
+ );
2742
+ await cleanupPlugins();
2743
+ return 1;
2721
2744
  }
2722
- await cleanup();
2723
- end2(0);
2724
- } catch (e) {
2725
- console.error(`Error: ${e.message}`);
2726
- end2(1);
2727
2745
  }
2746
+ const result = await bundle(targetDirectory);
2747
+ if (result.Warnings?.length) {
2748
+ result.Warnings.forEach((w) => writeErr(formatMessage(w, true)));
2749
+ }
2750
+ if (result.Errors?.length) {
2751
+ result.Errors.forEach((e) => writeErr(formatMessage(e)));
2752
+ await cleanupPlugins();
2753
+ return 1;
2754
+ }
2755
+ if (buildOnly) {
2756
+ writeOut("Build complete.");
2757
+ await cleanupPlugins();
2758
+ return 0;
2759
+ }
2760
+ const newCtx = await run_default({ directory: targetDirectory, env: env2 });
2761
+ if (!noOpen && typeof newCtx === "number") {
2762
+ globalThis.fullstacked.open?.(newCtx);
2763
+ }
2764
+ await cleanupPlugins();
2765
+ return 0;
2728
2766
  }
2767
+ function validateCommand(command) {
2768
+ let tokens = [];
2769
+ if (typeof command === "string") {
2770
+ tokens = command.trim().split(/\s+/).filter(Boolean);
2771
+ } else if (Array.isArray(command)) {
2772
+ tokens = [...command];
2773
+ }
2774
+ let fullstackedIndex = -1;
2775
+ for (let i = 0; i < tokens.length; i++) {
2776
+ const token = tokens[i];
2777
+ const base = token.split(/[/\\]/).pop() || token;
2778
+ if (token === "fullstacked" || base === "fullstacked") {
2779
+ fullstackedIndex = i;
2780
+ break;
2781
+ }
2782
+ }
2783
+ if (fullstackedIndex === -1) {
2784
+ return null;
2785
+ }
2786
+ return tokens.slice(fullstackedIndex);
2787
+ }
2788
+ async function execute(command, opts) {
2789
+ const stdoutStream = opts?.stdio?.at(1) || createConsoleStream(console.log);
2790
+ const stderrStream = opts?.stdio?.at(2) || createConsoleStream(console.error);
2791
+ const writeOut = getWriter(stdoutStream);
2792
+ const writeErr = getWriter(stderrStream);
2793
+ const tokens = validateCommand(command);
2794
+ if (!tokens) {
2795
+ writeErr(
2796
+ formatMessage(
2797
+ "Error: 'fullstacked' command not found in input.",
2798
+ false
2799
+ )
2800
+ );
2801
+ return 1;
2802
+ }
2803
+ const args2 = tokens.slice(1);
2804
+ const showVersion = hasArgFlag(["-v", "--version"], args2);
2805
+ const showHelp = hasArgFlag(["-h", "--help"], args2);
2806
+ if (showVersion) {
2807
+ writeOut(
2808
+ `FullStacked v${version_default.major}.${version_default.minor}.${version_default.patch} (build ${version_default.build}), branch ${version_default.branch}, hash ${version_default.hash.slice(0, 8)}`
2809
+ );
2810
+ return 0;
2811
+ }
2812
+ if (showHelp) {
2813
+ writeOut(`
2814
+ Usage:
2815
+ fullstacked [options] [directory]
2729
2816
 
2730
- // src/run/directory.ts
2731
- import path4 from "node:path";
2732
- import { createRequire as createRequire2 } from "node:module";
2733
- import { pathToFileURL as pathToFileURL2 } from "node:url";
2817
+ Description:
2818
+ This CLI compiles and runs projects designed for the FullStacked runtime.
2819
+ Unlike traditional JS/TS projects with separate frontend and backend layers:
2820
+ - NodeJS and Browser APIs are available seamlessly within the same files.
2821
+ - ES module syntax.
2822
+ - TypeScript support.
2823
+ - No HTML files.
2824
+ - Start with an entrypoint: index.js(x) or index.ts(x).
2734
2825
 
2735
- // ../../core/internal/bundle/lib/run/index.ts
2736
- function run(directoryOrOptions) {
2737
- const directory2 = typeof directoryOrOptions === "string" ? directoryOrOptions : directoryOrOptions?.directory;
2738
- const env3 = typeof directoryOrOptions === "object" ? directoryOrOptions.env : void 0;
2739
- const resolved = path_default.resolve(directory2 ?? ".");
2740
- return globalThis.fullstacked.bridge({
2741
- mod: Core,
2742
- fn: Run,
2743
- data: [resolved, env3]
2744
- });
2826
+ Options:
2827
+ -v, --version Display the current version
2828
+ -p, --port Define the main starting port (defaults to 9000)
2829
+ -p, --plugin Specify a plugin for the build process (can be used multiple times)
2830
+ -e, --env Define environment variables in KEY=VALUE format (can be used multiple times)
2831
+ -o, --open Directly open the browser
2832
+ -b, --build Only bundle the project, don't run it afterward
2833
+ -f, --file Bundle and execute a single script file
2834
+ -h, --help Display this help message
2835
+
2836
+ Directory:
2837
+ The directory to bundle (defaults to ".")
2838
+ `);
2839
+ return 0;
2840
+ }
2841
+ const fileFlags = findArgValues(["-f", "--file"], args2);
2842
+ const file = fileFlags.length > 0 ? fileFlags[0] : void 0;
2843
+ const buildOnly = hasArgFlag(["-b", "--build"], args2);
2844
+ const noOpen = hasArgFlag(["-n", "--no-open"], args2);
2845
+ const envArgs = findArgValues(["-e", "--env"], args2);
2846
+ const pluginsArgs = findArgValues(["-p", "--plugin"], args2);
2847
+ const positionals = getPositionalArgs(args2);
2848
+ const env2 = {};
2849
+ for (const val of envArgs) {
2850
+ const index = val.indexOf("=");
2851
+ if (index !== -1) {
2852
+ env2[val.slice(0, index)] = val.slice(index + 1);
2853
+ } else if (val) {
2854
+ env2[val] = "";
2855
+ }
2856
+ }
2857
+ if (file) {
2858
+ return runFile(file, writeOut, writeErr);
2859
+ }
2860
+ return runDirectory(
2861
+ positionals,
2862
+ pluginsArgs,
2863
+ buildOnly,
2864
+ noOpen,
2865
+ env2,
2866
+ writeOut,
2867
+ writeErr
2868
+ );
2745
2869
  }
2870
+ var fullstacked = {
2871
+ execute,
2872
+ validateCommand
2873
+ };
2874
+ var fullstacked_default = fullstacked;
2746
2875
 
2747
- // ../../core/internal/bundle/lib/@types/plugin.ts
2748
- var StartPluginStream = 0;
2749
- var Register = 1;
2750
- var Unregister = 2;
2876
+ // src/core.ts
2877
+ import path2 from "node:path";
2878
+ import { createRequire } from "node:module";
2751
2879
 
2752
- // ../../core/internal/bundle/lib/plugin/index.ts
2753
- var plugins = /* @__PURE__ */ new Map();
2754
- var duplexStream = null;
2755
- var eventEmitter = null;
2756
- var connectionPromise = null;
2757
- var te4 = new TextEncoder();
2758
- async function connect() {
2759
- if (duplexStream) {
2760
- return;
2761
- }
2762
- const duplex = await globalThis.fullstacked.bridge({
2763
- mod: Plugin,
2764
- fn: StartPluginStream
2765
- });
2766
- const emitter = duplex.eventEmitter();
2767
- const readyPromise = new Promise((resolve2) => {
2768
- emitter.on("ready", function onReady() {
2769
- emitter.off("ready", onReady);
2770
- resolve2();
2771
- });
2772
- });
2773
- await duplex.open();
2774
- await readyPromise;
2775
- duplexStream = duplex;
2776
- eventEmitter = emitter;
2777
- eventEmitter.on(
2778
- "plugin-call",
2779
- async (pluginId, requestId, ...args2) => {
2780
- let result = null;
2781
- let errorMsg = null;
2782
- try {
2783
- const registeredPlugin = plugins.get(pluginId);
2784
- if (registeredPlugin) {
2785
- result = await registeredPlugin.callback(...args2);
2786
- if (registeredPlugin.type === PluginTypeBuild) {
2787
- const remappedResult = [];
2788
- result.forEach(({ outputName, contents }) => {
2789
- contents = typeof contents === "string" ? te4.encode(contents) : contents;
2790
- remappedResult.push(outputName, contents);
2791
- });
2792
- result = remappedResult;
2793
- }
2794
- } else {
2795
- throw new Error(
2796
- `No registered plugin found for id: ${pluginId}`
2797
- );
2798
- }
2799
- } catch (err) {
2800
- errorMsg = err.message || String(err);
2801
- }
2802
- if (Array.isArray(result)) {
2803
- eventEmitter.writeEvent(
2804
- "plugin-response",
2805
- pluginId,
2806
- requestId,
2807
- errorMsg,
2808
- ...result
2809
- );
2810
- } else {
2811
- eventEmitter.writeEvent(
2812
- "plugin-response",
2813
- pluginId,
2814
- requestId,
2815
- errorMsg,
2816
- result
2817
- );
2818
- }
2880
+ // utils.ts
2881
+ import os from "node:os";
2882
+ import path from "node:path";
2883
+ import url from "node:url";
2884
+ import fs from "node:fs";
2885
+ var platform2 = os.platform();
2886
+ var archArgIndex = process.argv.indexOf("--arch");
2887
+ var arch2 = archArgIndex === -1 ? os.arch() : process.argv.at(archArgIndex + 1);
2888
+ var environment = `${platform2}-${arch2}`;
2889
+ var binExtension = platform2 === "win32" ? "dll" : "so";
2890
+ var binBasename = `fullstacked.${binExtension}`;
2891
+ var bindingBasename = "binding.node";
2892
+ var currentDirectory = path.dirname(
2893
+ url.fileURLToPath(import.meta.url)
2894
+ );
2895
+ var packageJson = JSON.parse(
2896
+ fs.readFileSync(path.resolve(currentDirectory, "package.json"), "utf-8")
2897
+ );
2898
+ var binLocations = [
2899
+ // flattened dependencies when installed in project
2900
+ path.resolve(currentDirectory, "..", "@fullstacked", environment),
2901
+ // when installed globally
2902
+ path.resolve(currentDirectory, "node_modules", "@fullstacked", environment)
2903
+ ];
2904
+
2905
+ // src/core.ts
2906
+ import fs2 from "node:fs";
2907
+ globalThis.require = createRequire(import.meta.url);
2908
+ var core;
2909
+ function findBinLocation() {
2910
+ for (const binLocation of binLocations) {
2911
+ if (fs2.existsSync(binLocation)) {
2912
+ return binLocation;
2819
2913
  }
2820
- );
2914
+ }
2915
+ return void 0;
2821
2916
  }
2822
- async function register(type2, plugin2) {
2823
- if (!connectionPromise) {
2824
- connectionPromise = connect();
2917
+ function verifyVersion(binLocation) {
2918
+ const packageJsonFileBin = path2.resolve(binLocation, "package.json");
2919
+ try {
2920
+ const packageJsonBin = JSON.parse(
2921
+ fs2.readFileSync(packageJsonFileBin, { encoding: "utf-8" })
2922
+ );
2923
+ return packageJsonBin.version === packageJson.version;
2924
+ } catch (e) {
2925
+ return false;
2926
+ }
2927
+ }
2928
+ async function load(onStreamData2) {
2929
+ const binLocation = findBinLocation();
2930
+ if (!binLocation) {
2931
+ throw `Cannot find core library. Tried:
2932
+ ${binLocations.join("\n")}`;
2933
+ }
2934
+ if (!verifyVersion(binLocation)) {
2935
+ throw `Core library version mismatch. Retry installing fullstacked.`;
2936
+ }
2937
+ const libPath = path2.resolve(binLocation, binBasename);
2938
+ const bindingPath = path2.resolve(binLocation, bindingBasename);
2939
+ core = __require(bindingPath);
2940
+ core.load(libPath);
2941
+ core.setOnStreamData(onStreamData2);
2942
+ return core;
2943
+ }
2944
+
2945
+ // src/webview.ts
2946
+ import http from "node:http";
2947
+ import net from "node:net";
2948
+ import open from "open";
2949
+ import { WebSocketServer } from "ws";
2950
+ init_base64();
2951
+ var args = process.argv;
2952
+ var portIndex = args.findIndex((arg) => arg === "-p" || arg === "--port");
2953
+ var mainPort = 9e3;
2954
+ if (portIndex !== -1 && args[portIndex + 1]) {
2955
+ mainPort = parseInt(args[portIndex + 1]);
2956
+ if (isNaN(mainPort)) {
2957
+ mainPort = 9e3;
2958
+ }
2959
+ }
2960
+ var te4 = new TextEncoder();
2961
+ async function createWebView(core3, ctx, opts) {
2962
+ const port = await getNextAvailablePort(mainPort);
2963
+ const server = http.createServer(createHandler(core3, ctx));
2964
+ const close = () => {
2965
+ core3.stop(ctx);
2966
+ server.close();
2967
+ opts.didClose?.();
2968
+ };
2969
+ const webSockets = createWebSocketServer(core3, ctx, server, close);
2970
+ const callback = (id, buffer) => {
2971
+ const payload = new Uint8Array(buffer.byteLength + 1);
2972
+ payload[0] = id;
2973
+ payload.set(new Uint8Array(buffer), 1);
2974
+ webSockets.forEach((ws) => ws.send(payload));
2975
+ };
2976
+ server.listen(port);
2977
+ if (!opts.quiet) {
2978
+ console.log(`Listening at http://localhost:${port}`);
2979
+ }
2980
+ if (!process.env.TEST) {
2981
+ open(`http://localhost:${port}`);
2825
2982
  }
2826
- await connectionPromise;
2827
- const { name, ...pluginData } = plugin2.data || {};
2828
- const id = await globalThis.fullstacked.bridge({
2829
- mod: Plugin,
2830
- fn: Register,
2831
- data: [type2, name || "plugin-" + type2, pluginData]
2832
- });
2833
- plugins.set(id, { type: type2, callback: plugin2.callback });
2834
2983
  return {
2835
- unregister: async () => {
2836
- plugins.delete(id);
2837
- await globalThis.fullstacked.bridge({
2838
- mod: Plugin,
2839
- fn: Unregister,
2840
- data: [id]
2841
- });
2842
- }
2984
+ close,
2985
+ port,
2986
+ callback
2843
2987
  };
2844
2988
  }
2845
- var plugin = {
2846
- register
2847
- };
2848
- var plugin_default = plugin;
2849
-
2850
- // src/run/directory.ts
2851
- async function importPlugin(p) {
2852
- if (p.startsWith(".") || path4.isAbsolute(p)) {
2853
- return (await import(pathToFileURL2(path4.resolve(p)).href)).default;
2989
+ var nextCallId = 0;
2990
+ async function coreCall(core3, req) {
2991
+ const payload = await readBody(req);
2992
+ if (payload.length >= 2) {
2993
+ nextCallId = nextCallId % 255 + 1;
2994
+ payload[1] = nextCallId;
2854
2995
  }
2855
- try {
2856
- const requireFromCwd = createRequire2(
2857
- path4.join(process.cwd(), "index.js")
2858
- );
2859
- const resolved = requireFromCwd.resolve(p);
2860
- return (await import(pathToFileURL2(resolved).href)).default;
2861
- } catch {
2862
- try {
2863
- const requireFromModule = createRequire2(import.meta.url);
2864
- const resolved = requireFromModule.resolve(p);
2865
- return (await import(pathToFileURL2(resolved).href)).default;
2866
- } catch {
2867
- return (await import(p)).default;
2996
+ const data = core3.call(payload.buffer);
2997
+ return new Uint8Array(data);
2998
+ }
2999
+ var platform3 = te4.encode("node");
3000
+ function createHandler(core3, ctx) {
3001
+ return async (req, res) => {
3002
+ let [pathname] = req.url.split("?");
3003
+ pathname = decodeURI(pathname);
3004
+ if (pathname === "/platform") {
3005
+ res.writeHead(200, {
3006
+ "content-type": "text/plain",
3007
+ "content-length": platform3.length
3008
+ });
3009
+ return res.end(platform3);
3010
+ } else if (pathname === "/ctx") {
3011
+ const ctxStr = ctx.toString();
3012
+ res.writeHead(200, {
3013
+ "content-type": "text/plain",
3014
+ "content-length": ctxStr.length
3015
+ });
3016
+ return res.end(ctxStr);
3017
+ } else if (pathname === "/open") {
3018
+ const newCtx = await readBody(req);
3019
+ globalThis.fullstacked.open(newCtx[0]);
3020
+ return res.end();
3021
+ } else if (pathname === "/call") {
3022
+ const payload = await coreCall(core3, req);
3023
+ res.writeHead(200, {
3024
+ "content-type": "application/octet-stream",
3025
+ "content-length": payload.byteLength,
3026
+ "cache-control": "no-cache"
3027
+ });
3028
+ return res.end(payload);
3029
+ } else if (pathname === "/sync") {
3030
+ const payload = await coreCall(core3, req);
3031
+ const b64 = fromByteArray(payload);
3032
+ res.writeHead(200, {
3033
+ "content-type": "application/octet-stream",
3034
+ "content-length": b64.length,
3035
+ "cache-control": "no-cache"
3036
+ });
3037
+ return res.end(b64);
2868
3038
  }
2869
- }
3039
+ const staticFile = coreStaticFile(core3, ctx, pathname);
3040
+ res.writeHead(staticFile.found ? 200 : 400, {
3041
+ "content-type": staticFile.mimeType,
3042
+ "content-length": staticFile.data.byteLength,
3043
+ "cache-control": "no-cache"
3044
+ });
3045
+ res.end(staticFile.data);
3046
+ };
2870
3047
  }
2871
- async function runDirectory(pluginsArgs2, buildOnly2, env3, end2) {
2872
- await Promise.all(
2873
- pluginsArgs2.map(
2874
- async (p) => plugin_default.register("build", await importPlugin(p))
2875
- )
3048
+ function coreStaticFile(core3, ctx, pathname) {
3049
+ const pathnameData = te4.encode(pathname);
3050
+ const payload = new Uint8Array([
3051
+ ctx,
3052
+ 0,
3053
+ // id
3054
+ Core,
3055
+ // Module
3056
+ StaticFile,
3057
+ // Fn
3058
+ 0,
3059
+ // Async
3060
+ STRING,
3061
+ ...numberToUint4Bytes(pathnameData.length),
3062
+ // arg length
3063
+ ...pathnameData
3064
+ ]);
3065
+ const responseData = core3.call(payload.buffer);
3066
+ const response = deserialize(
3067
+ responseData.slice(1)
2876
3068
  );
2877
- const result = await bundle();
2878
- if (result.Warnings?.length) {
2879
- console.warn("Warnings:", result.Warnings);
2880
- }
2881
- if (result.Errors?.length) {
2882
- console.error("Errors:", result.Errors);
2883
- end2(1);
2884
- } else if (!buildOnly2) {
2885
- run({ env: env3 });
2886
- } else {
2887
- console.log("Build complete.");
2888
- end2(0);
3069
+ if (response.data.byteLength === 0) {
3070
+ return {
3071
+ found: false,
3072
+ mimeType: "text/plain",
3073
+ data: te4.encode("not found")
3074
+ };
2889
3075
  }
3076
+ const [mimeType, data] = deserializeAll(response.data.buffer);
3077
+ return {
3078
+ found: true,
3079
+ mimeType,
3080
+ data
3081
+ };
3082
+ }
3083
+ function readBody(req) {
3084
+ return new Promise((resolve3) => {
3085
+ const contentLengthStr = req.headers["content-length"] || "0";
3086
+ const contentLength = parseInt(contentLengthStr);
3087
+ if (!contentLength) {
3088
+ return resolve3(new Uint8Array());
3089
+ }
3090
+ const body = new Uint8Array(contentLength);
3091
+ let i = 0;
3092
+ req.on("data", (chunk) => {
3093
+ for (let j = 0; j < chunk.byteLength; j++) {
3094
+ body[j + i] = chunk[j];
3095
+ }
3096
+ i += chunk.length;
3097
+ });
3098
+ req.on("end", () => resolve3(body));
3099
+ });
3100
+ }
3101
+ function getNextAvailablePort(port = 9e3, host = "0.0.0.0") {
3102
+ return new Promise((resolve3, reject) => {
3103
+ const socket = new net.Socket();
3104
+ const timeout = () => {
3105
+ resolve3(port);
3106
+ socket.destroy();
3107
+ };
3108
+ const next = () => {
3109
+ socket.destroy();
3110
+ resolve3(getNextAvailablePort(++port));
3111
+ };
3112
+ setTimeout(timeout, 200);
3113
+ socket.on("timeout", timeout);
3114
+ socket.on("connect", function() {
3115
+ next();
3116
+ });
3117
+ socket.on("error", function(exception) {
3118
+ if (exception.code !== "ECONNREFUSED") {
3119
+ reject(exception);
3120
+ } else {
3121
+ timeout();
3122
+ }
3123
+ });
3124
+ socket.connect(port, host);
3125
+ });
3126
+ }
3127
+ function createWebSocketServer(core3, ctx, server, close) {
3128
+ const webSockets = /* @__PURE__ */ new Set();
3129
+ const wss = new WebSocketServer({ noServer: true });
3130
+ let closeTimeout;
3131
+ const onClose = (ws) => {
3132
+ webSockets.delete(ws);
3133
+ if (!core3.check(ctx)) {
3134
+ close();
3135
+ } else if (webSockets.size === 0) {
3136
+ closeTimeout = setTimeout(close, 5e3);
3137
+ }
3138
+ };
3139
+ const handleUpgrade = (ws) => {
3140
+ if (closeTimeout) {
3141
+ clearTimeout(closeTimeout);
3142
+ closeTimeout = void 0;
3143
+ }
3144
+ webSockets.add(ws);
3145
+ ws.on("close", () => onClose(ws));
3146
+ };
3147
+ const onUpgrade = (...args2) => {
3148
+ wss.handleUpgrade(...args2, handleUpgrade);
3149
+ };
3150
+ server.on("upgrade", onUpgrade);
3151
+ return webSockets;
2890
3152
  }
2891
3153
 
2892
3154
  // src/index.ts
2893
- var end = (code2) => {
3155
+ var end = (code3) => {
2894
3156
  core2.end();
2895
- process.exit(code2);
3157
+ process.exit(code3);
2896
3158
  };
2897
3159
  ["SIGINT", "SIGTERM", "SIGQUIT"].forEach(
2898
3160
  (signal) => process.on(signal, () => end(0))
@@ -2909,93 +3171,30 @@ var core2 = await load(
2909
3171
  webview.callback(streamId, buffer);
2910
3172
  return;
2911
3173
  }
2912
- createWebView(core2, ctx, {
2913
- openBrowser: openBrowser || webviews.size >= 1,
2914
- didClose: () => {
2915
- webviews.delete(ctx);
2916
- }
2917
- }).then((webview2) => {
2918
- webviews.set(ctx, webview2);
2919
- });
3174
+ throw new Error(`Unknown context: ${ctx}`);
2920
3175
  }
2921
3176
  );
2922
- var help = findArg(["-h", "--help"]);
2923
- var showVersion = findArg(["-v", "--version"]);
2924
- var openBrowser = findArg(["-o", "--open"]);
2925
- var buildOnly = findArg(["-b", "--build"]);
2926
- var envArgs = findArg(["-e", "--env"], true);
2927
- var pluginsArgs = findArg(["-p", "--plugin"], true);
2928
- var fileFlag = findArg(["-f", "--file"]);
2929
- var env2 = {};
2930
- for (const val of envArgs) {
2931
- const index = val.indexOf("=");
2932
- if (index !== -1) {
2933
- const key = val.slice(0, index);
2934
- const value = val.slice(index + 1);
2935
- env2[key] = value;
2936
- } else if (val) {
2937
- env2[val] = "";
2938
- }
2939
- }
2940
- var positionalArgs = getPositionalArgs();
2941
- var directory = fileFlag ? process.cwd() : path5.resolve(positionalArgs.at(-1) || ".");
2942
- if (showVersion) {
2943
- console.log(
2944
- `FullStacked v${version_default2.major}.${version_default2.minor}.${version_default2.patch} (build ${version_default2.build}), branch ${version_default2.branch}, hash ${version_default2.hash.slice(0, 8)}`
2945
- );
2946
- process.exit(0);
2947
- }
2948
- if (help) {
2949
- console.log(`
2950
- Usage:
2951
- fullstacked [options] [directory]
2952
-
2953
- Description:
2954
- This CLI compiles and runs projects designed for the FullStacked runtime.
2955
- Unlike traditional JS/TS projects with separate frontend and backend layers:
2956
- - NodeJS and Browser APIs are available seamlessly within the same files.
2957
- - ES module syntax.
2958
- - TypeScript support.
2959
- - No HTML files.
2960
- - Start with an entrypoint: index.js(x) or index.ts(x).
2961
-
2962
- Example:
2963
- // index.jsx
2964
- import React from "react";
2965
- import { createRoot } from "react-dom/client";
2966
- import fs from "node:fs";
2967
-
2968
- const div = document.createElement("div");
2969
- document.body.append(div);
2970
-
2971
- const root = createRoot(div);
2972
- root.render(<h1>{await fs.promises.readFile("hello-world.txt")}</h1>);
2973
-
2974
- Options:
2975
- -v, --version Display the current version
2976
- -p, --port Define the main starting port (defaults to 9000)
2977
- -p, --plugin Specify a plugin for the build process (can be used multiple times)
2978
- -e, --env Define environment variables in KEY=VALUE format (can be used multiple times)
2979
- -o, --open Directly open the browser
2980
- -b, --build Only bundle the project, don't run it afterward
2981
- -f, --file Bundle and execute a single script file
2982
- -h, --help Display this help message
2983
-
2984
- Directory:
2985
- The directory to bundle (defaults to ".")
2986
- `);
2987
- process.exit(0);
2988
- }
2989
- process.chdir(directory);
2990
- var mainCtx = core2.start(directory, directory);
3177
+ var mainCtx = core2.start(process.cwd(), process.cwd());
2991
3178
  globalThis.ctxId = mainCtx;
2992
3179
  globalThis.bridges = {
2993
3180
  ctxId: mainCtx,
2994
3181
  Sync: (payload) => core2.call(payload),
2995
3182
  Async: async (payload) => core2.call(payload)
2996
3183
  };
2997
- if (fileFlag) {
2998
- await runFile(positionalArgs, end);
2999
- } else {
3000
- await runDirectory(pluginsArgs, buildOnly, env2, end);
3184
+ globalThis.fullstacked.open = (ctx) => {
3185
+ createWebView(core2, ctx, {
3186
+ didClose: () => {
3187
+ webviews.delete(ctx);
3188
+ }
3189
+ }).then((webview) => {
3190
+ webviews.set(ctx, webview);
3191
+ });
3192
+ };
3193
+ var code2 = await fullstacked_default.execute(process.argv);
3194
+ var argsThatExits = ["-b", "--build", "-f", "--file"];
3195
+ var shouldExit = !!process.argv.find(
3196
+ (arg) => argsThatExits.find((exitArg) => arg.startsWith(exitArg))
3197
+ );
3198
+ if (typeof code2 === "number" && code2 !== 0 || shouldExit) {
3199
+ end(code2);
3001
3200
  }