@swiftbrowser/native 0.10.4 → 0.12.0

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/README.md CHANGED
@@ -116,6 +116,32 @@ JavaScriptCore lacks. `test/fastRefresh.test.ts` runs the loop in Node.
116
116
  Xcode scheme or `simctl launch`), as the Fidelity example does to open one
117
117
  screen.
118
118
 
119
+ ## In the browser
120
+
121
+ ```sh
122
+ npx swiftbrowser-native site src/index.tsx --out dist # the app as a static site
123
+ npx swiftbrowser-native site src/index.tsx --out ../web/dist/native --base /native/
124
+ ```
125
+
126
+ The same bundle, drawn by the native views in a browser: the package ships
127
+ the SwiftBrowser Native Swift package compiled for WebAssembly against
128
+ SwiftBrowser's SwiftUI shim (`wasm/SwiftBrowserNative.wasm`, the round trip
129
+ of [docs/native.md](../../docs/native.md)), and `site` writes it, the bundle
130
+ and the web renderer's page as one static directory, the layout
131
+ `swiftbrowser build` writes for a Swift app. The page runs the module, the
132
+ module evaluates the bundle at the page's global scope (so `fetch`, timers
133
+ and `localStorage` are the browser's own, same origin and cookies included),
134
+ the native views draw the app's ops with the shim's SwiftUI, and the web
135
+ renderer draws what the shim emits. One app, three renderers: the browser's
136
+ DOM through `@swiftbrowser/react` directly, real SwiftUI in the iOS app, and
137
+ this: the iOS app's own views, in a page. `--base /path/` when the site is
138
+ served under a path of another site, `--module <file>` for a module built
139
+ from a checkout (`swift build --swift-sdk <wasm sdk> -c release --product
140
+ NativeRoundTrip`), `--name <App>` for the site's app name (the folder
141
+ holding `js/` by default), `--catalog <dir.xcassets>` (repeatable) for the
142
+ app's named images and colors (the Xcode target's catalog, or one kept for
143
+ the site: a `.symbolset` holding any SVG draws as a symbol there).
144
+
119
145
  ## The escape hatch
120
146
 
121
147
  ```tsx
@@ -3,22 +3,28 @@
3
3
  // same as `swiftbrowser native build`, from @swiftbrowser/cli, which also
4
4
  // writes a new project with `swiftbrowser native init`);
5
5
  // `swiftbrowser-native dev <entry> --out <file> [--port 5173]` serves it with
6
- // rebuild on save for `NativeApp.watch(url:)`.
6
+ // rebuild on save for `NativeApp.watch(url:)`; `swiftbrowser-native site
7
+ // <entry> --out <dir>` writes the app as a static site the web renderer runs
8
+ // (the native views built for WebAssembly, `--module <file>` for one other
9
+ // than the package's; `--base /path/` when the site is not a host's root;
10
+ // `--catalog <dir.xcassets>`, repeatable, for the app's named images).
7
11
 
8
- import { resolve } from 'node:path';
12
+ import { basename, resolve } from 'node:path';
9
13
  import { buildApp, serve } from '../dist/build.js';
10
14
 
11
15
  const [command, entry, ...rest] = process.argv.slice(2);
12
- const flags = {};
16
+ const flags = { catalog: [] };
13
17
  for (let i = 0; i < rest.length; i++) {
14
18
  const arg = rest[i];
15
- if (arg === '--out' || arg === '--port') flags[arg.slice(2)] = rest[++i];
19
+ if (arg === '--catalog') flags.catalog.push(rest[++i]);
20
+ else if (arg === '--out' || arg === '--port' || arg === '--module' || arg === '--base' || arg === '--name') flags[arg.slice(2)] = rest[++i];
16
21
  else if (arg.startsWith('--')) flags[arg.slice(2)] = true;
17
22
  }
18
23
 
19
- if (!command || !entry || !flags.out || !['build', 'dev'].includes(command)) {
24
+ if (!command || !entry || !flags.out || !['build', 'dev', 'site'].includes(command)) {
20
25
  console.error('usage: swiftbrowser-native build <entry.tsx> --out <App/app.js> [--minify] [--sourcemap]');
21
26
  console.error(' swiftbrowser-native dev <entry.tsx> --out <App/app.js> [--port 5173] [--sourcemap]');
27
+ console.error(' swiftbrowser-native site <entry.tsx> --out <dir> [--name <App>] [--module <file.wasm>] [--base /path/] [--catalog <dir.xcassets>]... [--minify]');
22
28
  process.exit(2);
23
29
  }
24
30
 
@@ -35,6 +41,20 @@ if (command === 'build') {
35
41
  const result = await buildApp(options);
36
42
  for (const warning of result.warnings) console.warn(warning);
37
43
  console.log(`${options.outfile}: ${kb(result.bytes)}`);
44
+ } else if (command === 'site') {
45
+ const { buildNativeSite } = await import('../dist/site.js');
46
+ const { outfile, ...bundleOptions } = options;
47
+ const result = await buildNativeSite({
48
+ ...bundleOptions,
49
+ outDir: outfile,
50
+ ...(flags.name ? { name: flags.name } : {}),
51
+ ...(flags.module ? { module: resolve(flags.module) } : {}),
52
+ ...(flags.base ? { base: flags.base } : {}),
53
+ ...(flags.catalog.length ? { catalogs: flags.catalog.map((dir) => resolve(dir)) } : {}),
54
+ });
55
+ for (const warning of result.warnings) console.warn(warning);
56
+ console.log(`${result.name}: app.js ${kb(result.bundleBytes)}, ${basename(result.module)} ${kb(result.moduleBytes)}`);
57
+ console.log(`site written to ${result.outDir}`);
38
58
  } else {
39
59
  const port = flags.port ? Number(flags.port) : 5173;
40
60
  await serve({
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;CACrC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAkCD,4CAA4C;AAC5C,wBAAsB,MAAM,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CASxE;AAMD,oCAAoC;AACpC,wBAAsB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAK1E;AAED,MAAM,WAAW,YAAa,SAAQ,YAAY;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,KAAK,IAAI,CAAC;CACjD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAuE/E"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;CACrC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA8CD,4CAA4C;AAC5C,wBAAsB,MAAM,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CASxE;AAMD,oCAAoC;AACpC,wBAAsB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAK1E;AAED,MAAM,WAAW,YAAa,SAAQ,YAAY;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,KAAK,IAAI,CAAC;CACjD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAuE/E"}
package/dist/build.js CHANGED
@@ -10,21 +10,32 @@ import { createHash } from 'node:crypto';
10
10
  import { existsSync } from 'node:fs';
11
11
  import { createServer } from 'node:http';
12
12
  import { mkdir, writeFile } from 'node:fs/promises';
13
- import { dirname } from 'node:path';
13
+ import { dirname, resolve, sep } from 'node:path';
14
14
  import { fileURLToPath } from 'node:url';
15
15
  const here = dirname(fileURLToPath(import.meta.url));
16
16
  /** The runtime's source; the package ships `src` so this resolves from `dist` too. */
17
17
  const runtimeEntry = fileURLToPath(new URL('../src/runtime.ts', import.meta.url));
18
18
  const reactSources = fileURLToPath(new URL('../../react/src/index.ts', import.meta.url));
19
+ /** The repository, when this runs from a checkout (installed, the package has no `packages/react` beside it). */
20
+ const repository = existsSync(reactSources) ? resolve(here, '../../..') : null;
19
21
  const stubs = {
20
22
  'react-dom/client': fileURLToPath(new URL('../src/stubs/react-dom-client.ts', import.meta.url)),
21
23
  'react-dom': fileURLToPath(new URL('../src/stubs/react-dom.ts', import.meta.url)),
22
24
  // This package from its sources, so a bundle never needs its `dist` built first.
23
25
  '@swiftbrowser/native/runtime': runtimeEntry,
24
26
  '@swiftbrowser/native': fileURLToPath(new URL('../src/index.ts', import.meta.url)),
25
- // In this repository, @swiftbrowser/react from its sources too (installed, it is a built package).
26
- ...(existsSync(reactSources) ? { '@swiftbrowser/react': reactSources } : {}),
27
27
  };
28
+ /**
29
+ * The aliases for an entry: in this repository, an app of the repository's
30
+ * (the examples) gets @swiftbrowser/react from its sources too (installed,
31
+ * it is a built package). An app outside it (a project built with the
32
+ * checkout's bundler) keeps its own installed copy: the sources would bring
33
+ * the repository's React along, a second copy beside the app's.
34
+ */
35
+ function aliases(entry) {
36
+ const inRepository = repository !== null && resolve(entry).startsWith(repository + sep);
37
+ return { ...stubs, ...(inRepository ? { '@swiftbrowser/react': reactSources } : {}) };
38
+ }
28
39
  function common(options) {
29
40
  const mode = options.mode ?? (options.minify ? 'production' : 'development');
30
41
  return {
@@ -45,7 +56,7 @@ function common(options) {
45
56
  /** Builds the two halves and joins them. */
46
57
  export async function bundle(options) {
47
58
  const runtime = await esbuild.build({ ...common(options), entryPoints: [runtimeEntry] });
48
- const app = await esbuild.build({ ...common(options), entryPoints: [options.entry], alias: stubs });
59
+ const app = await esbuild.build({ ...common(options), entryPoints: [options.entry], alias: aliases(options.entry) });
49
60
  const code = `${text(runtime)}\n${text(app)}`;
50
61
  return {
51
62
  code,
package/dist/build.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
package/dist/site.d.ts ADDED
@@ -0,0 +1,52 @@
1
+ /**
2
+ * The native app as a static site (`swiftbrowser-native site`): the same
3
+ * bundle `build` writes for the Xcode target, run in the browser by the
4
+ * SwiftBrowser Native module built for WebAssembly (docs/native.md, "The
5
+ * round trip"): the native views compiled against the SwiftUI shim, with the
6
+ * page's JavaScript as the engine. The web renderer draws what the shim
7
+ * emits, as it draws any Swift app. The site is what `swiftbrowser build`
8
+ * writes for a Swift app: the page at `/`, the module, the bundle as the
9
+ * app's one resource (`/bundle/app.js`, which the module evaluates at
10
+ * launch) and the manifest. Node only.
11
+ */
12
+ import { type BuildOptions } from './build.js';
13
+ /** The module as the package ships it (publish.yml builds it; `wasm/` is gitignored in the repository). */
14
+ export declare const PACKAGED_MODULE: string;
15
+ export interface SiteOptions extends Omit<BuildOptions, 'outfile'> {
16
+ /** The directory to write the site into (emptied first). */
17
+ outDir: string;
18
+ /**
19
+ * The site's app name (letters, digits, `_` and `-`): the module's file
20
+ * name and the document title. The entry's project folder's name by default
21
+ * (`js/src/index.tsx` → the folder holding `js`, as `native init` lays an
22
+ * app out), else `App`.
23
+ */
24
+ name?: string;
25
+ /** Shown as the document title and in the web manifest; `name` by default. */
26
+ displayName?: string;
27
+ /** The SwiftBrowser Native module built for WebAssembly; `PACKAGED_MODULE` by default. */
28
+ module?: string;
29
+ /** The path the site is served under when it is not a host's root (`/native/`); `/` by default. */
30
+ base?: string;
31
+ /**
32
+ * Asset catalogs (`*.xcassets` directories) the app's named images and
33
+ * colors come from, served as the site's catalog; the Xcode target's, or
34
+ * one kept for the site (a `.symbolset` holding any SVG draws as a symbol).
35
+ */
36
+ catalogs?: string[];
37
+ /** Vite's log level while building the site; `warn` by default. */
38
+ logLevel?: 'info' | 'warn' | 'error' | 'silent';
39
+ }
40
+ export interface SiteResult {
41
+ name: string;
42
+ outDir: string;
43
+ module: string;
44
+ moduleBytes: number;
45
+ bundleBytes: number;
46
+ warnings: string[];
47
+ }
48
+ /** The app name an entry suggests: the folder holding its `js/` project, else the entry's own folder. */
49
+ export declare function siteNameFor(entry: string): string;
50
+ /** Bundles the app and writes the site around the module. */
51
+ export declare function buildNativeSite(options: SiteOptions): Promise<SiteResult>;
52
+ //# sourceMappingURL=site.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAEvD,2GAA2G;AAC3G,eAAO,MAAM,eAAe,QAA6E,CAAC;AAE1G,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC;IAChE,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mGAAmG;IACnG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;CACjD;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAID,yGAAyG;AACzG,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOjD;AAED,6DAA6D;AAC7D,wBAAsB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAwC/E"}
package/dist/site.js ADDED
@@ -0,0 +1,74 @@
1
+ /**
2
+ * The native app as a static site (`swiftbrowser-native site`): the same
3
+ * bundle `build` writes for the Xcode target, run in the browser by the
4
+ * SwiftBrowser Native module built for WebAssembly (docs/native.md, "The
5
+ * round trip"): the native views compiled against the SwiftUI shim, with the
6
+ * page's JavaScript as the engine. The web renderer draws what the shim
7
+ * emits, as it draws any Swift app. The site is what `swiftbrowser build`
8
+ * writes for a Swift app: the page at `/`, the module, the bundle as the
9
+ * app's one resource (`/bundle/app.js`, which the module evaluates at
10
+ * launch) and the manifest. Node only.
11
+ */
12
+ import { existsSync, mkdtempSync, rmSync, statSync, writeFileSync } from 'node:fs';
13
+ import { tmpdir } from 'node:os';
14
+ import path from 'node:path';
15
+ import { fileURLToPath } from 'node:url';
16
+ import { buildSite } from '@swiftbrowser/web';
17
+ import { bundle } from './build.js';
18
+ /** The module as the package ships it (publish.yml builds it; `wasm/` is gitignored in the repository). */
19
+ export const PACKAGED_MODULE = fileURLToPath(new URL('../wasm/SwiftBrowserNative.wasm', import.meta.url));
20
+ const APP_NAME = /^[A-Za-z0-9_-]+$/;
21
+ /** The app name an entry suggests: the folder holding its `js/` project, else the entry's own folder. */
22
+ export function siteNameFor(entry) {
23
+ const dir = path.dirname(path.resolve(entry));
24
+ const parts = dir.split(path.sep);
25
+ const js = parts.lastIndexOf('js');
26
+ const candidate = js > 0 ? parts[js - 1] : path.basename(dir) === 'src' ? parts[parts.length - 2] : path.basename(dir);
27
+ const cleaned = (candidate ?? '').replace(/[^A-Za-z0-9_-]/g, '');
28
+ return cleaned && APP_NAME.test(cleaned) ? cleaned : 'App';
29
+ }
30
+ /** Bundles the app and writes the site around the module. */
31
+ export async function buildNativeSite(options) {
32
+ const name = options.name ?? siteNameFor(options.entry);
33
+ if (!APP_NAME.test(name))
34
+ throw new Error(`site: the app name must be letters, digits, "_" and "-": ${name}`);
35
+ const module = path.resolve(options.module ?? PACKAGED_MODULE);
36
+ if (!existsSync(module)) {
37
+ throw new Error(module === PACKAGED_MODULE
38
+ ? `site: this @swiftbrowser/native has no module at ${module}; pass one with --module (swift build --swift-sdk <wasm sdk> -c release --product NativeRoundTrip in a SwiftBrowser checkout)`
39
+ : `site: no module at ${module}`);
40
+ }
41
+ if (options.base !== undefined && !/^\/([^/].*\/)?$/.test(options.base))
42
+ throw new Error(`site: --base must start and end with "/": ${options.base}`);
43
+ const { outDir, name: _name, displayName, module: _module, base, logLevel, catalogs, ...bundleOptions } = options;
44
+ for (const catalog of catalogs ?? []) {
45
+ if (!existsSync(catalog))
46
+ throw new Error(`site: no asset catalog at ${catalog}`);
47
+ }
48
+ // The bundle is the app's one resource: published at `/bundle/<name>/app.js`
49
+ // and mounted at `/bundle/app.js`, where the module's launch reads it.
50
+ const resources = mkdtempSync(path.join(tmpdir(), 'swiftbrowser-native-site-'));
51
+ try {
52
+ const built = await bundle({ ...bundleOptions, outfile: path.join(resources, 'app.js') });
53
+ writeFileSync(path.join(resources, 'app.js'), built.code);
54
+ await buildSite({
55
+ apps: [{
56
+ name,
57
+ displayName: displayName ?? name,
58
+ description: 'A SwiftBrowser Native app in the browser',
59
+ wasm: module,
60
+ catalogs: (catalogs ?? []).map((catalog) => path.resolve(catalog)),
61
+ resources: [path.join(resources, 'app.js')],
62
+ }],
63
+ layout: 'app',
64
+ outDir: path.resolve(outDir),
65
+ ...(base !== undefined ? { base } : {}),
66
+ logLevel: logLevel ?? 'warn',
67
+ });
68
+ return { name, outDir: path.resolve(outDir), module, moduleBytes: statSync(module).size, bundleBytes: built.bytes, warnings: built.warnings };
69
+ }
70
+ finally {
71
+ rmSync(resources, { recursive: true, force: true });
72
+ }
73
+ }
74
+ //# sourceMappingURL=site.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site.js","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"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"}
@@ -1,35 +1,9 @@
1
1
  /**
2
- * The host's JavaScript as SwiftBrowser Native's engine (docs/native.md,
3
- * "The round trip"): for a module built with the round-trip target
4
- * (`Native/RoundTrip`, the native views compiled against the shim), this
5
- * answers its one import, `sb_native.request`, and exposes the native
6
- * functions Swift installs (`applyOps`, `log`, `now`, …) on `__sbNative`,
7
- * each a call of the module's `sb_native_invoke` export.
8
- *
9
- * Node (scripts/run-wasi.mjs) and a page use it the same way: merge
10
- * `imports` into the module's imports, instantiate, then `attach` the
11
- * instance. Strings cross linear memory as UTF-8; an answer to Swift is a
12
- * buffer from `sb_alloc` holding a little-endian 4-byte length and the
13
- * bytes, which Swift frees, and a result from Swift is the same layout,
14
- * freed with `sb_native_free` once read.
2
+ * `@swiftbrowser/native/wasm-host`: the host's JavaScript as SwiftBrowser
3
+ * Native's engine for a module built with the round-trip target (docs/native.md,
4
+ * "The round trip"). The implementation lives in the web renderer
5
+ * (Web/src/nativeHost.ts), which attaches it to any module that imports
6
+ * `sb_native`; this entry is for Node (scripts/run-wasi.mjs) and tests.
15
7
  */
16
- export interface WasmNativeHostOptions {
17
- /** Runs a script at the global scope (default: an indirect `eval`). */
18
- evaluate?: (script: string, name: string) => void;
19
- /** The global object the bundle's globals live on (default `globalThis`). */
20
- global?: Record<string, unknown>;
21
- }
22
- export interface WasmNativeHost {
23
- /** Merge into the module's import object before instantiating. */
24
- imports: {
25
- sb_native: {
26
- request: (kind: number, kindLength: number, a: number, aLength: number, b: number, bLength: number) => number;
27
- };
28
- };
29
- /** The instance, once instantiated: its memory and the exports the host calls. */
30
- attach(instance: WebAssembly.Instance): void;
31
- /** The `__sbNative` object as it stands (replaced by a reset). */
32
- readonly native: Record<string, (...args: unknown[]) => unknown>;
33
- }
34
- export declare function wasmNativeHost(options?: WasmNativeHostOptions): WasmNativeHost;
8
+ export { wasmNativeHost, type WasmNativeHost, type WasmNativeHostOptions } from '@swiftbrowser/web';
35
9
  //# sourceMappingURL=wasmHost.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wasmHost.d.ts","sourceRoot":"","sources":["../src/wasmHost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,qBAAqB;IACpC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,OAAO,EAAE;QACP,SAAS,EAAE;YACT,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;SAC/G,CAAC;KACH,CAAC;IACF,kFAAkF;IAClF,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC7C,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC;CAClE;AAYD,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,cAAc,CAoGlF"}
1
+ {"version":3,"file":"wasmHost.d.ts","sourceRoot":"","sources":["../src/wasmHost.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/wasmHost.js CHANGED
@@ -1,120 +1,9 @@
1
1
  /**
2
- * The host's JavaScript as SwiftBrowser Native's engine (docs/native.md,
3
- * "The round trip"): for a module built with the round-trip target
4
- * (`Native/RoundTrip`, the native views compiled against the shim), this
5
- * answers its one import, `sb_native.request`, and exposes the native
6
- * functions Swift installs (`applyOps`, `log`, `now`, …) on `__sbNative`,
7
- * each a call of the module's `sb_native_invoke` export.
8
- *
9
- * Node (scripts/run-wasi.mjs) and a page use it the same way: merge
10
- * `imports` into the module's imports, instantiate, then `attach` the
11
- * instance. Strings cross linear memory as UTF-8; an answer to Swift is a
12
- * buffer from `sb_alloc` holding a little-endian 4-byte length and the
13
- * bytes, which Swift frees, and a result from Swift is the same layout,
14
- * freed with `sb_native_free` once read.
2
+ * `@swiftbrowser/native/wasm-host`: the host's JavaScript as SwiftBrowser
3
+ * Native's engine for a module built with the round-trip target (docs/native.md,
4
+ * "The round trip"). The implementation lives in the web renderer
5
+ * (Web/src/nativeHost.ts), which attaches it to any module that imports
6
+ * `sb_native`; this entry is for Node (scripts/run-wasi.mjs) and tests.
15
7
  */
16
- /** The globals a bundle defines, dropped by a reset (`JSHost.reset`). */
17
- const BUNDLE_GLOBALS = ['__sbDispatch', '__sbTimerFired', '__sbFetchResult', '__sbRefresh', '__sbVendor'];
18
- export function wasmNativeHost(options = {}) {
19
- const g = options.global ?? globalThis;
20
- const evaluate = options.evaluate ?? ((script) => (0, eval)(script));
21
- const encoder = new TextEncoder();
22
- const decoder = new TextDecoder();
23
- let exports = null;
24
- let native = {};
25
- const need = () => {
26
- if (!exports)
27
- throw new Error('wasmNativeHost: attach(instance) before the module runs');
28
- return exports;
29
- };
30
- const read = (pointer, length) => decoder.decode(new Uint8Array(need().memory.buffer, pointer, length));
31
- /** A buffer from `sb_alloc` with the text's length and bytes; Swift frees it. */
32
- const answer = (value) => {
33
- const bytes = encoder.encode(JSON.stringify(value));
34
- const pointer = need().sb_alloc(bytes.length + 4);
35
- // The allocation may have grown the memory: take the view after it.
36
- const view = new DataView(need().memory.buffer);
37
- view.setUint32(pointer, bytes.length, true);
38
- new Uint8Array(need().memory.buffer, pointer + 4, bytes.length).set(bytes);
39
- return pointer;
40
- };
41
- const describe = (error) => (error instanceof Error ? (error.stack ?? error.message) : String(error));
42
- /** A native function's call: into Swift and back with its JSON result. */
43
- const invoke = (name, args) => {
44
- const nameBytes = encoder.encode(name);
45
- const argsBytes = encoder.encode(JSON.stringify(args));
46
- const namePointer = need().sb_alloc(nameBytes.length || 1);
47
- new Uint8Array(need().memory.buffer, namePointer, nameBytes.length).set(nameBytes);
48
- const argsPointer = need().sb_alloc(argsBytes.length || 1);
49
- new Uint8Array(need().memory.buffer, argsPointer, argsBytes.length).set(argsBytes);
50
- const result = need().sb_native_invoke(namePointer, nameBytes.length, argsPointer, argsBytes.length);
51
- if (result === 0)
52
- return undefined;
53
- const length = new DataView(need().memory.buffer).getUint32(result, true);
54
- const text = read(result + 4, length);
55
- need().sb_native_free(result);
56
- const value = JSON.parse(text);
57
- if (value && typeof value === 'object' && 'error' in value && Object.keys(value).length === 1) {
58
- throw new Error(String(value.error));
59
- }
60
- return value;
61
- };
62
- const reset = () => {
63
- for (const name of BUNDLE_GLOBALS)
64
- delete g[name];
65
- native = {};
66
- g['__sbNative'] = native;
67
- };
68
- const request = (kind, kindLength, a, aLength, b, bLength) => {
69
- const what = read(kind, kindLength);
70
- const first = read(a, aLength);
71
- const second = read(b, bLength);
72
- switch (what) {
73
- case 'reset':
74
- reset();
75
- return 0;
76
- case 'install':
77
- native[first] = (...args) => invoke(first, args);
78
- return 0;
79
- case 'eval':
80
- try {
81
- evaluate(first, second);
82
- return 0;
83
- }
84
- catch (error) {
85
- return answer({ error: describe(error) });
86
- }
87
- case 'call': {
88
- const fn = g[first];
89
- if (typeof fn !== 'function')
90
- return answer({ error: `${first} is not defined` });
91
- try {
92
- const result = fn(...JSON.parse(second));
93
- return answer({ ok: result === undefined ? null : result });
94
- }
95
- catch (error) {
96
- return answer({ error: describe(error) });
97
- }
98
- }
99
- case 'has':
100
- return answer({ ok: first in g });
101
- default:
102
- return answer({ error: `unknown request ${what}` });
103
- }
104
- };
105
- reset();
106
- return {
107
- imports: { sb_native: { request } },
108
- attach(instance) {
109
- for (const name of ['memory', 'sb_alloc', 'sb_native_invoke', 'sb_native_free']) {
110
- if (!(name in instance.exports))
111
- throw new Error(`wasmNativeHost: the module does not export ${name}`);
112
- }
113
- exports = instance.exports;
114
- },
115
- get native() {
116
- return native;
117
- },
118
- };
119
- }
8
+ export { wasmNativeHost } from '@swiftbrowser/web';
120
9
  //# sourceMappingURL=wasmHost.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"wasmHost.js","sourceRoot":"","sources":["../src/wasmHost.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wasmHost.js","sourceRoot":"","sources":["../src/wasmHost.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,cAAc,EAAmD,MAAM,mBAAmB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swiftbrowser/native",
3
- "version": "0.10.4",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "description": "Run a @swiftbrowser/react app natively: the runtime a JavaScriptCore-hosted app needs (timers, console, fetch and the other web globals over the SwiftBrowser Native bridge), the `run` entry that renders into the native SwiftUI renderer, and the bundler that builds app.js for the Xcode target.",
6
6
  "repository": {
@@ -23,6 +23,10 @@
23
23
  "types": "./dist/build.d.ts",
24
24
  "default": "./dist/build.js"
25
25
  },
26
+ "./site": {
27
+ "types": "./dist/site.d.ts",
28
+ "default": "./dist/site.js"
29
+ },
26
30
  "./wasm-host": {
27
31
  "types": "./dist/wasmHost.d.ts",
28
32
  "default": "./dist/wasmHost.js"
@@ -36,6 +40,7 @@
36
40
  "src",
37
41
  "bin",
38
42
  "swift",
43
+ "wasm",
39
44
  "README.md"
40
45
  ],
41
46
  "sideEffects": [
@@ -54,8 +59,8 @@
54
59
  },
55
60
  "dependencies": {
56
61
  "@babel/core": "^7.29.7",
57
- "@swiftbrowser/react": "0.10.4",
58
- "@swiftbrowser/web": "0.10.4",
62
+ "@swiftbrowser/react": "0.12.0",
63
+ "@swiftbrowser/web": "0.12.0",
59
64
  "esbuild": "^0.28.2",
60
65
  "react-refresh": "^0.17.0"
61
66
  },
package/src/build.ts CHANGED
@@ -11,7 +11,7 @@ import { createHash } from 'node:crypto';
11
11
  import { existsSync } from 'node:fs';
12
12
  import { createServer } from 'node:http';
13
13
  import { mkdir, writeFile } from 'node:fs/promises';
14
- import { dirname } from 'node:path';
14
+ import { dirname, resolve, sep } from 'node:path';
15
15
  import { fileURLToPath } from 'node:url';
16
16
 
17
17
  export interface BuildOptions {
@@ -35,16 +35,28 @@ const here = dirname(fileURLToPath(import.meta.url));
35
35
  /** The runtime's source; the package ships `src` so this resolves from `dist` too. */
36
36
  const runtimeEntry = fileURLToPath(new URL('../src/runtime.ts', import.meta.url));
37
37
  const reactSources = fileURLToPath(new URL('../../react/src/index.ts', import.meta.url));
38
+ /** The repository, when this runs from a checkout (installed, the package has no `packages/react` beside it). */
39
+ const repository = existsSync(reactSources) ? resolve(here, '../../..') : null;
38
40
  const stubs: Record<string, string> = {
39
41
  'react-dom/client': fileURLToPath(new URL('../src/stubs/react-dom-client.ts', import.meta.url)),
40
42
  'react-dom': fileURLToPath(new URL('../src/stubs/react-dom.ts', import.meta.url)),
41
43
  // This package from its sources, so a bundle never needs its `dist` built first.
42
44
  '@swiftbrowser/native/runtime': runtimeEntry,
43
45
  '@swiftbrowser/native': fileURLToPath(new URL('../src/index.ts', import.meta.url)),
44
- // In this repository, @swiftbrowser/react from its sources too (installed, it is a built package).
45
- ...(existsSync(reactSources) ? { '@swiftbrowser/react': reactSources } : {}),
46
46
  };
47
47
 
48
+ /**
49
+ * The aliases for an entry: in this repository, an app of the repository's
50
+ * (the examples) gets @swiftbrowser/react from its sources too (installed,
51
+ * it is a built package). An app outside it (a project built with the
52
+ * checkout's bundler) keeps its own installed copy: the sources would bring
53
+ * the repository's React along, a second copy beside the app's.
54
+ */
55
+ function aliases(entry: string): Record<string, string> {
56
+ const inRepository = repository !== null && resolve(entry).startsWith(repository + sep);
57
+ return { ...stubs, ...(inRepository ? { '@swiftbrowser/react': reactSources } : {}) };
58
+ }
59
+
48
60
  function common(options: BuildOptions): esbuild.BuildOptions {
49
61
  const mode = options.mode ?? (options.minify ? 'production' : 'development');
50
62
  return {
@@ -66,7 +78,7 @@ function common(options: BuildOptions): esbuild.BuildOptions {
66
78
  /** Builds the two halves and joins them. */
67
79
  export async function bundle(options: BuildOptions): Promise<BuildResult> {
68
80
  const runtime = await esbuild.build({ ...common(options), entryPoints: [runtimeEntry] });
69
- const app = await esbuild.build({ ...common(options), entryPoints: [options.entry], alias: stubs });
81
+ const app = await esbuild.build({ ...common(options), entryPoints: [options.entry], alias: aliases(options.entry) });
70
82
  const code = `${text(runtime)}\n${text(app)}`;
71
83
  return {
72
84
  code,