@tokamakdev/tok 0.1.1-beta.58 → 0.1.1-beta.60

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/dist/vite.d.mts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { type Plugin } from "vite";
2
2
  /**
3
3
  * Reports the build's tokamak configuration and development server address to
4
- * `tok`. Without `TOKAMAK_VITE_OUTPUT`, which `tok` sets, it adds no hooks.
4
+ * `tok`, and makes the entry Worker import the configuration file. Without
5
+ * `TOKAMAK_VITE_OUTPUT`, which `tok` sets, it adds no hooks.
5
6
  */
6
7
  export declare function tokamak(): Plugin[];
package/dist/vite.mjs CHANGED
@@ -1,13 +1,14 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { normalizePath, runnerImport } from "vite";
3
+ import { normalizePath, runnerImport, } from "vite";
4
4
  /** Configuration files tried in order when `tok` names none. */
5
5
  const CONFIG_FILES = ["src/tokamak.ts", "src/tokamak.js"];
6
6
  /** The files each output directory's `config.json` was read from, once written. */
7
7
  const written = new Map();
8
8
  /**
9
9
  * Reports the build's tokamak configuration and development server address to
10
- * `tok`. Without `TOKAMAK_VITE_OUTPUT`, which `tok` sets, it adds no hooks.
10
+ * `tok`, and makes the entry Worker import the configuration file. Without
11
+ * `TOKAMAK_VITE_OUTPUT`, which `tok` sets, it adds no hooks.
11
12
  */
12
13
  export function tokamak() {
13
14
  const output = process.env.TOKAMAK_VITE_OUTPUT;
@@ -15,8 +16,12 @@ export function tokamak() {
15
16
  return [];
16
17
  }
17
18
  let config;
19
+ let file;
20
+ /** The module IDs of each entry environment's inputs. */
21
+ const entryIds = new Map();
22
+ /** The entry environments whose input imports the configuration file. */
23
+ const importing = new Set();
18
24
  const write = () => {
19
- const file = findConfigFile(config.root);
20
25
  const files = writeConfig(output, file, config);
21
26
  // A file that fails to load stays watched, so fixing it rewrites `config.json`.
22
27
  written.set(output, files.catch(() => (file ? [file] : [])));
@@ -27,6 +32,7 @@ export function tokamak() {
27
32
  name: "tokamak",
28
33
  async configResolved(resolved) {
29
34
  config = resolved;
35
+ file = findConfigFile(resolved.root);
30
36
  await (written.has(output) ? written.get(output) : write());
31
37
  },
32
38
  async watchChange(id) {
@@ -41,6 +47,34 @@ export function tokamak() {
41
47
  });
42
48
  },
43
49
  },
50
+ {
51
+ name: "tokamak:entry",
52
+ // Server environments with a manifest are built from the entry Worker:
53
+ // Cloudflare's plugin gives one to the entry and prerender Workers, and
54
+ // Astro to its server and prerender environments.
55
+ applyToEnvironment: ({ config }) => file !== undefined && config.consumer === "server" && Boolean(config.build.manifest),
56
+ async transform(code, id) {
57
+ if (id === file) {
58
+ return withoutConfig(this, code);
59
+ }
60
+ const environment = this.environment;
61
+ const ids = entryIds.get(environment.name) ??
62
+ Promise.all(inputs(environment.config.build).map(async (input) => (await this.resolve(input))?.id));
63
+ entryIds.set(environment.name, ids);
64
+ if (!(await ids).includes(id)) {
65
+ return;
66
+ }
67
+ importing.add(environment.name);
68
+ // In Cloudflare's Worker entry, which dev and build both start from,
69
+ // this follows the imports of its polyfills and of the app's entry.
70
+ return { code: `${code}\nimport ${JSON.stringify(file)};\n`, map: null };
71
+ },
72
+ generateBundle() {
73
+ if (!importing.has(this.environment.name)) {
74
+ this.error(`the input of the ${this.environment.name} environment did not import ${file}`);
75
+ }
76
+ },
77
+ },
44
78
  ];
45
79
  }
46
80
  /** The configuration file `TOKAMAK_CONFIG` names, or the first default under `root` that exists. */
@@ -71,7 +105,43 @@ async function writeConfig(output, file, config) {
71
105
  writeJson(output, "config.json", { file, config: module.config ?? {} });
72
106
  return [file, ...dependencies.map(normalizePath)];
73
107
  }
108
+ /** The modules an environment's build starts from. */
109
+ function inputs(build) {
110
+ const { input } = build.rollupOptions;
111
+ return typeof input === "string" ? [input] : Object.values(input ?? {});
112
+ }
113
+ /**
114
+ * `code` without its `export const config = ...` statement, which is blanked
115
+ * so that every other position, and so the source map, is unchanged.
116
+ */
117
+ function withoutConfig(context, code) {
118
+ const statements = context.parse(code).body;
119
+ const statement = statements.find(exportsConfig);
120
+ if (!statement) {
121
+ return;
122
+ }
123
+ if (statement.declaration?.declarations?.length !== 1) {
124
+ context.error("declare config in its own `export const config = ...` statement");
125
+ }
126
+ const blank = code.slice(statement.start, statement.end).replace(/[^\n]/g, " ");
127
+ return { code: code.slice(0, statement.start) + blank + code.slice(statement.end), map: null };
128
+ }
129
+ function exportsConfig(statement) {
130
+ if (statement.type !== "ExportNamedDeclaration") {
131
+ return false;
132
+ }
133
+ const declaration = statement.declaration;
134
+ const names = [
135
+ declaration?.id?.name,
136
+ ...(declaration?.declarations ?? []).map((declarator) => declarator.id.name),
137
+ ...(statement.specifiers ?? []).map((specifier) => specifier.exported.name),
138
+ ];
139
+ return names.includes("config");
140
+ }
141
+ /** Writes `value` to `name` whole, as `tok` reads the file as soon as it exists. */
74
142
  function writeJson(output, name, value) {
143
+ const file = path.join(output, name);
75
144
  fs.mkdirSync(output, { recursive: true });
76
- fs.writeFileSync(path.join(output, name), `${JSON.stringify(value, null, 2)}\n`);
145
+ fs.writeFileSync(`${file}.tmp`, `${JSON.stringify(value, null, 2)}\n`);
146
+ fs.renameSync(`${file}.tmp`, file);
77
147
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokamakdev/tok",
3
- "version": "0.1.1-beta.58",
3
+ "version": "0.1.1-beta.60",
4
4
  "description": "The tokamak CLI, Vite plugin and app API: build native apps from a Cloudflare Workers codebase",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,7 +35,7 @@
35
35
  "node": ">=18"
36
36
  },
37
37
  "peerDependencies": {
38
- "@cloudflare/vite-plugin": "^1.0.0",
38
+ "@cloudflare/vite-plugin": "^1.54.0",
39
39
  "vite": "^7.0.0 || ^8.0.0"
40
40
  },
41
41
  "peerDependenciesMeta": {
@@ -50,17 +50,17 @@
50
50
  "vite": "8.3.2"
51
51
  },
52
52
  "optionalDependencies": {
53
- "@tokamakdev/platform-android-arm64": "0.1.1-beta.58",
54
- "@tokamakdev/platform-ios-arm64": "0.1.1-beta.58",
55
- "@tokamakdev/platform-ios-simulator-arm64": "0.1.1-beta.58",
56
- "@tokamakdev/platform-ios-simulator-x64": "0.1.1-beta.58",
57
- "@tokamakdev/platform-macos-arm64": "0.1.1-beta.58",
58
- "@tokamakdev/platform-macos-x64": "0.1.1-beta.58",
59
- "@tokamakdev/platform-windows-x64": "0.1.1-beta.58",
60
- "@tokamakdev/tok-darwin-arm64": "0.1.1-beta.58",
61
- "@tokamakdev/tok-darwin-x64": "0.1.1-beta.58",
62
- "@tokamakdev/tok-linux-x64": "0.1.1-beta.58",
63
- "@tokamakdev/tok-win32-x64": "0.1.1-beta.58"
53
+ "@tokamakdev/platform-android-arm64": "0.1.1-beta.60",
54
+ "@tokamakdev/platform-ios-arm64": "0.1.1-beta.60",
55
+ "@tokamakdev/platform-ios-simulator-arm64": "0.1.1-beta.60",
56
+ "@tokamakdev/platform-ios-simulator-x64": "0.1.1-beta.60",
57
+ "@tokamakdev/platform-macos-arm64": "0.1.1-beta.60",
58
+ "@tokamakdev/platform-macos-x64": "0.1.1-beta.60",
59
+ "@tokamakdev/platform-windows-x64": "0.1.1-beta.60",
60
+ "@tokamakdev/tok-darwin-arm64": "0.1.1-beta.60",
61
+ "@tokamakdev/tok-darwin-x64": "0.1.1-beta.60",
62
+ "@tokamakdev/tok-linux-x64": "0.1.1-beta.60",
63
+ "@tokamakdev/tok-win32-x64": "0.1.1-beta.60"
64
64
  },
65
65
  "publishConfig": {
66
66
  "access": "public"