@tokamakdev/tok 0.1.1-beta.80 → 0.1.1-beta.81

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
@@ -11,18 +11,21 @@ npx tok targets
11
11
 
12
12
  | Entry | Contents |
13
13
  | --- | --- |
14
- | `@tokamakdev/tok` | The `Config` type of `src/tokamak.ts` |
14
+ | `@tokamakdev/tok` | The `Config` type of the Vite plugin's options |
15
15
  | `@tokamakdev/tok/vite` | The Vite plugin, `tokamak()` |
16
16
  | `tok` | The CLI |
17
17
 
18
- The Vite plugin goes next to Cloudflare's:
18
+ The Vite plugin goes next to Cloudflare's, and its options are the app's
19
+ tokamak configuration:
19
20
 
20
21
  ```ts
21
22
  import { cloudflare } from "@cloudflare/vite-plugin";
22
23
  import { tokamak } from "@tokamakdev/tok/vite";
23
24
  import { defineConfig } from "vite";
24
25
 
25
- export default defineConfig({ plugins: [cloudflare(), tokamak()] });
26
+ export default defineConfig({
27
+ plugins: [cloudflare(), tokamak({ name: "My App", version: "1.0.0" })],
28
+ });
26
29
  ```
27
30
 
28
31
  It does nothing unless `tok` runs the build or development command.
package/dist/index.d.mts CHANGED
@@ -6,18 +6,18 @@ export interface PlatformConfig {
6
6
  name?: string;
7
7
  /** Application identifier. */
8
8
  identifier?: string;
9
- /** Icon in the platform's format, relative to the configuration file. */
9
+ /** Icon in the platform's format, relative to the Vite root. */
10
10
  icon?: string;
11
11
  /** A setting the platform pack declares; `tok` validates it. */
12
12
  [key: string]: Value | undefined;
13
13
  }
14
- /** The app's tokamak configuration, exported as `config` from `src/tokamak.ts`. */
14
+ /** The app's tokamak configuration: the tokamak Vite plugin's options other than `module`. */
15
15
  export interface Config {
16
16
  /** Display name for every platform. */
17
17
  name?: string;
18
18
  /** Application identifier for every platform. */
19
19
  identifier?: string;
20
- /** Icon for every platform, relative to the configuration file. */
20
+ /** Icon for every platform, relative to the Vite root. */
21
21
  icon?: string;
22
22
  /** App version. */
23
23
  version?: string;
package/dist/vite.d.mts CHANGED
@@ -1,8 +1,14 @@
1
1
  import { type Plugin } from "vite";
2
+ import type { Config } from "./index.mjs";
2
3
  /**
3
- * Reports the build's tokamak configuration, and the development server's
4
- * address and Worker name, to `tok`, and makes the entry Worker import the
5
- * configuration file. Without `TOKAMAK_VITE_OUTPUT`, which `tok` sets, it adds
6
- * no hooks.
4
+ * Reports the app's tokamak configuration, and the development server's
5
+ * address and Worker name, to `tok`, and makes the entry Worker import
6
+ * `module`. Without `TOKAMAK_VITE_OUTPUT`, which `tok` sets, it adds no hooks.
7
7
  */
8
- export declare function tokamak(): Plugin[];
8
+ export declare function tokamak({ module, ...config }?: Config & {
9
+ /**
10
+ * The module the entry Worker imports, relative to the Vite root; by
11
+ * default `src/tokamak.ts`, then `src/tokamak.js`, when one exists.
12
+ */
13
+ module?: string;
14
+ }): Plugin[];
package/dist/vite.mjs CHANGED
@@ -1,47 +1,31 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { normalizePath, runnerImport, } from "vite";
4
- /** Configuration files tried in order when `tok` names none. */
5
- const CONFIG_FILES = ["src/tokamak.ts", "src/tokamak.js"];
3
+ import { normalizePath } from "vite";
4
+ /** Modules tried in order when the options name none. */
5
+ const DEFAULT_MODULES = ["src/tokamak.ts", "src/tokamak.js"];
6
6
  /** Wrangler configuration files Cloudflare's plugin tries in order. */
7
7
  const WRANGLER_FILES = ["wrangler.jsonc", "wrangler.json", "wrangler.toml"];
8
- /** The files each output directory's `config.json` was read from, once written. */
9
- const written = new Map();
10
8
  /**
11
- * Reports the build's tokamak configuration, and the development server's
12
- * address and Worker name, to `tok`, and makes the entry Worker import the
13
- * configuration file. Without `TOKAMAK_VITE_OUTPUT`, which `tok` sets, it adds
14
- * no hooks.
9
+ * Reports the app's tokamak configuration, and the development server's
10
+ * address and Worker name, to `tok`, and makes the entry Worker import
11
+ * `module`. Without `TOKAMAK_VITE_OUTPUT`, which `tok` sets, it adds no hooks.
15
12
  */
16
- export function tokamak() {
13
+ export function tokamak({ module, ...config } = {}) {
17
14
  const output = process.env.TOKAMAK_VITE_OUTPUT;
18
15
  if (!output) {
19
16
  return [];
20
17
  }
21
- let config;
22
18
  let file;
23
19
  /** The module IDs of each entry environment's inputs. */
24
20
  const entryIds = new Map();
25
- /** The entry environments whose input imports the configuration file. */
21
+ /** The entry environments whose input imports the module. */
26
22
  const importing = new Set();
27
- const write = () => {
28
- const files = writeConfig(output, file, config);
29
- // A file that fails to load stays watched, so fixing it rewrites `config.json`.
30
- written.set(output, files.catch(() => (file ? [file] : [])));
31
- return files;
32
- };
33
23
  return [
34
24
  {
35
25
  name: "tokamak",
36
- async configResolved(resolved) {
37
- config = resolved;
38
- file = findConfigFile(resolved.root);
39
- await (written.has(output) ? written.get(output) : write());
40
- },
41
- async watchChange(id) {
42
- if ((await written.get(output))?.includes(id)) {
43
- await write();
44
- }
26
+ configResolved({ root }) {
27
+ file = findModule(root, module);
28
+ writeJson(output, "config.json", { root, config });
45
29
  },
46
30
  async configureServer(server) {
47
31
  const httpServer = server.httpServer;
@@ -65,9 +49,6 @@ export function tokamak() {
65
49
  name: "tokamak:entry",
66
50
  applyToEnvironment: ({ config }) => file !== undefined && buildsEntryWorker(config),
67
51
  async transform(code, id) {
68
- if (id === file) {
69
- return withoutConfig(this, code);
70
- }
71
52
  const environment = this.environment;
72
53
  const ids = entryIds.get(environment.name) ??
73
54
  Promise.all(inputs(environment.config.build).map(async (input) => (await this.resolve(input))?.id));
@@ -88,33 +69,14 @@ export function tokamak() {
88
69
  },
89
70
  ];
90
71
  }
91
- /** The configuration file `TOKAMAK_CONFIG` names, or the first default under `root` that exists. */
92
- function findConfigFile(root) {
93
- const named = process.env.TOKAMAK_CONFIG;
94
- if (named) {
95
- if (!fs.existsSync(named)) {
96
- throw new Error(`tokamak configuration file not found: ${named}`);
97
- }
98
- return normalizePath(path.resolve(named));
99
- }
100
- const file = CONFIG_FILES.map((name) => path.resolve(root, name)).find((candidate) => fs.existsSync(candidate));
101
- return file && normalizePath(file);
102
- }
103
- /**
104
- * Writes the file's `config` export, with the file's path, to `config.json`,
105
- * returning the files it was read from.
106
- */
107
- async function writeConfig(output, file, config) {
108
- if (!file) {
109
- writeJson(output, "config.json", { config: {} });
110
- return [];
72
+ /** The module `name` under `root`, or else the first default under `root` that exists. */
73
+ function findModule(root, name) {
74
+ const candidates = (name ? [name] : DEFAULT_MODULES).map((candidate) => normalizePath(path.resolve(root, candidate)));
75
+ const file = candidates.find((candidate) => fs.existsSync(candidate));
76
+ if (name && !file) {
77
+ throw new Error(`tokamak module not found: ${candidates[0]}`);
111
78
  }
112
- const { module, dependencies } = await runnerImport(file, {
113
- root: config.root,
114
- resolve: { alias: config.resolve.alias, tsconfigPaths: config.resolve.tsconfigPaths },
115
- });
116
- writeJson(output, "config.json", { file, config: module.config ?? {} });
117
- return [file, ...dependencies.map(normalizePath)];
79
+ return file;
118
80
  }
119
81
  /**
120
82
  * The name of the Worker in the Wrangler configuration file in `root`, found
@@ -143,50 +105,6 @@ function inputs(build) {
143
105
  const { input } = build.rollupOptions;
144
106
  return typeof input === "string" ? [input] : Object.values(input ?? {});
145
107
  }
146
- /**
147
- * `code` without its `config` export: the `export const config = ...`
148
- * statement is blanked, or only its `export` keyword while other statements
149
- * mention `config`, so that every other position, and so the source map, is
150
- * unchanged.
151
- */
152
- function withoutConfig(context, code) {
153
- const statements = context.parse(code).body;
154
- const statement = statements.find(exportsConfig);
155
- if (!statement) {
156
- return;
157
- }
158
- const declaration = statement.declaration;
159
- if (declaration?.declarations?.length !== 1) {
160
- return context.error("declare config in its own `export const config = ...` statement");
161
- }
162
- const mentioned = statements.some((other) => other !== statement && mentions(other, "config"));
163
- const end = mentioned ? declaration.start : statement.end;
164
- const blank = code.slice(statement.start, end).replace(/[^\n]/g, " ");
165
- return { code: code.slice(0, statement.start) + blank + code.slice(end), map: null };
166
- }
167
- /** Whether `node` contains an identifier named `name`, property names included. */
168
- function mentions(node, name) {
169
- if (typeof node !== "object" || node === null) {
170
- return false;
171
- }
172
- const identifier = node;
173
- if (identifier.type === "Identifier" && identifier.name === name) {
174
- return true;
175
- }
176
- return Object.values(node).some((child) => mentions(child, name));
177
- }
178
- function exportsConfig(statement) {
179
- if (statement.type !== "ExportNamedDeclaration") {
180
- return false;
181
- }
182
- const declaration = statement.declaration;
183
- const names = [
184
- declaration?.id?.name,
185
- ...(declaration?.declarations ?? []).map((declarator) => declarator.id.name),
186
- ...(statement.specifiers ?? []).map((specifier) => specifier.exported.name),
187
- ];
188
- return names.includes("config");
189
- }
190
108
  /** Writes `value` to `name` whole, as `tok` reads the file as soon as it exists. */
191
109
  function writeJson(output, name, value) {
192
110
  const file = path.join(output, name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokamakdev/tok",
3
- "version": "0.1.1-beta.80",
3
+ "version": "0.1.1-beta.81",
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",
@@ -55,17 +55,17 @@
55
55
  "wrangler": "4.147.0"
56
56
  },
57
57
  "optionalDependencies": {
58
- "@tokamakdev/platform-android-arm64": "0.1.1-beta.80",
59
- "@tokamakdev/platform-ios-arm64": "0.1.1-beta.80",
60
- "@tokamakdev/platform-ios-simulator-arm64": "0.1.1-beta.80",
61
- "@tokamakdev/platform-ios-simulator-x64": "0.1.1-beta.80",
62
- "@tokamakdev/platform-macos-arm64": "0.1.1-beta.80",
63
- "@tokamakdev/platform-macos-x64": "0.1.1-beta.80",
64
- "@tokamakdev/platform-windows-x64": "0.1.1-beta.80",
65
- "@tokamakdev/tok-darwin-arm64": "0.1.1-beta.80",
66
- "@tokamakdev/tok-darwin-x64": "0.1.1-beta.80",
67
- "@tokamakdev/tok-linux-x64": "0.1.1-beta.80",
68
- "@tokamakdev/tok-win32-x64": "0.1.1-beta.80"
58
+ "@tokamakdev/platform-android-arm64": "0.1.1-beta.81",
59
+ "@tokamakdev/platform-ios-arm64": "0.1.1-beta.81",
60
+ "@tokamakdev/platform-ios-simulator-arm64": "0.1.1-beta.81",
61
+ "@tokamakdev/platform-ios-simulator-x64": "0.1.1-beta.81",
62
+ "@tokamakdev/platform-macos-arm64": "0.1.1-beta.81",
63
+ "@tokamakdev/platform-macos-x64": "0.1.1-beta.81",
64
+ "@tokamakdev/platform-windows-x64": "0.1.1-beta.81",
65
+ "@tokamakdev/tok-darwin-arm64": "0.1.1-beta.81",
66
+ "@tokamakdev/tok-darwin-x64": "0.1.1-beta.81",
67
+ "@tokamakdev/tok-linux-x64": "0.1.1-beta.81",
68
+ "@tokamakdev/tok-win32-x64": "0.1.1-beta.81"
69
69
  },
70
70
  "publishConfig": {
71
71
  "access": "public"