@swiftuijs/twill 0.3.0 → 0.3.1

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.
Files changed (57) hide show
  1. package/README.md +3 -3
  2. package/bin/run.mjs +2 -2
  3. package/dist/cli.js +5 -5
  4. package/dist/{compiler-CbNSBUI2.js → compiler-BdkU4Ruh.js} +32 -12
  5. package/dist/compiler-BdkU4Ruh.js.map +1 -0
  6. package/dist/config-la_KkjCS.js +1 -0
  7. package/dist/config.js +1 -0
  8. package/dist/declarations-BTAS8Mb_.js +132 -0
  9. package/dist/declarations-BTAS8Mb_.js.map +1 -0
  10. package/dist/declarations.js +1 -131
  11. package/dist/doctor-Co_pdZtt.js +202 -0
  12. package/dist/doctor-Co_pdZtt.js.map +1 -0
  13. package/dist/doctor.js +1 -201
  14. package/dist/editor.js +1 -1
  15. package/dist/esbuild.js +1 -1
  16. package/dist/index.js +1 -1
  17. package/dist/{loader-compiler-D1teTrXw.js → loader-compiler.js} +2 -2
  18. package/dist/loader-compiler.js.map +1 -0
  19. package/dist/loader-registration-B1ST9h1e.js +15 -0
  20. package/dist/loader-registration-B1ST9h1e.js.map +1 -0
  21. package/dist/loader-registration.d.ts +4 -0
  22. package/dist/loader-registration.js +2 -0
  23. package/dist/loader-state-DE2ArGYl.js +61 -0
  24. package/dist/loader-state-DE2ArGYl.js.map +1 -0
  25. package/dist/loader-state.d.ts +34 -0
  26. package/dist/loader-sync.d.ts +3 -0
  27. package/dist/loader-sync.js +28 -0
  28. package/dist/loader-sync.js.map +1 -0
  29. package/dist/loader.d.ts +2 -4
  30. package/dist/loader.js +9 -46
  31. package/dist/loader.js.map +1 -1
  32. package/dist/{plugin-BHfiQ2L-.js → plugin-DdTVagIU.js} +2 -2
  33. package/dist/{plugin-BHfiQ2L-.js.map → plugin-DdTVagIU.js.map} +1 -1
  34. package/dist/project-ZmlpFooa.js +444 -0
  35. package/dist/project-ZmlpFooa.js.map +1 -0
  36. package/dist/project.js +1 -442
  37. package/dist/register.js +2 -2
  38. package/dist/register.js.map +1 -1
  39. package/dist/rollup.js +1 -1
  40. package/dist/rspack.js +1 -1
  41. package/dist/syntax.js +1 -1
  42. package/dist/{transpile-D8P8Lsbx.js → transpile-CLNavDUr.js} +2 -2
  43. package/dist/{transpile-D8P8Lsbx.js.map → transpile-CLNavDUr.js.map} +1 -1
  44. package/dist/typescript-plugin.cjs +31 -11
  45. package/dist/typescript-plugin.cjs.map +1 -1
  46. package/dist/vite-BI-5KRgr.js +7 -0
  47. package/dist/vite-BI-5KRgr.js.map +1 -0
  48. package/dist/vite-react.js +1 -1
  49. package/dist/vite.js +1 -6
  50. package/dist/webpack.js +1 -1
  51. package/package.json +2 -2
  52. package/dist/compiler-CbNSBUI2.js.map +0 -1
  53. package/dist/declarations.js.map +0 -1
  54. package/dist/doctor.js.map +0 -1
  55. package/dist/loader-compiler-D1teTrXw.js.map +0 -1
  56. package/dist/project.js.map +0 -1
  57. package/dist/vite.js.map +0 -1
package/dist/doctor.js CHANGED
@@ -1,202 +1,2 @@
1
- import { n as isTwillFile } from "./extensions-B1xTkoYP.js";
2
- import ts from "typescript";
3
- var package_default = {
4
- name: "@swiftuijs/twill",
5
- version: "0.3.0",
6
- description: "Twill extends TypeScript with Swift-inspired syntax: trailing closures, guards, defer and checked switch expressions. Compiles to ordinary JavaScript.",
7
- main: "./dist/typescript-plugin.cjs",
8
- repository: {
9
- "type": "git",
10
- "url": "git+https://github.com/swiftuijs/twill.git",
11
- "directory": "packages/twill"
12
- },
13
- keywords: [
14
- "javascript",
15
- "typescript",
16
- "trailing-closures",
17
- "swift",
18
- "vite",
19
- "unplugin",
20
- "react",
21
- "vue",
22
- "twill",
23
- "guard",
24
- "defer"
25
- ],
26
- author: {
27
- "name": "forth.ink",
28
- "url": "https://forth.ink"
29
- },
30
- license: "MIT",
31
- type: "module",
32
- bugs: { "url": "https://github.com/swiftuijs/twill/issues" },
33
- homepage: "https://twill.evecalm.com/",
34
- dependencies: {
35
- "@ampproject/remapping": "^2.3.0",
36
- "@jridgewell/trace-mapping": "^0.3.31",
37
- "acorn": "8.18.0",
38
- "acorn-jsx": "^5.3.2",
39
- "acorn-typescript": "1.4.13",
40
- "magic-string": "^1.4.2",
41
- "typescript": "catalog:",
42
- "unplugin": "^3.4.0"
43
- },
44
- sideEffects: false,
45
- engines: { "node": "^20.19.0 || >=22.12.0" },
46
- files: [
47
- "bin",
48
- "dist/**/*.js",
49
- "dist/**/*.js.map",
50
- "dist/**/*.d.ts",
51
- "schemas",
52
- "README.md",
53
- "LICENSE",
54
- "dist/**/*.cjs",
55
- "dist/**/*.cjs.map",
56
- "dist/*.LICENSE.txt"
57
- ],
58
- bin: { "twill": "./bin/twill.mjs" },
59
- exports: {
60
- ".": {
61
- "types": "./dist/index.d.ts",
62
- "import": "./dist/index.js"
63
- },
64
- "./vite": {
65
- "types": "./dist/vite.d.ts",
66
- "import": "./dist/vite.js"
67
- },
68
- "./rollup": {
69
- "types": "./dist/rollup.d.ts",
70
- "import": "./dist/rollup.js"
71
- },
72
- "./esbuild": {
73
- "types": "./dist/esbuild.d.ts",
74
- "import": "./dist/esbuild.js"
75
- },
76
- "./webpack": {
77
- "types": "./dist/webpack.d.ts",
78
- "import": "./dist/webpack.js"
79
- },
80
- "./rspack": {
81
- "types": "./dist/rspack.d.ts",
82
- "import": "./dist/rspack.js"
83
- },
84
- "./project": {
85
- "types": "./dist/project.d.ts",
86
- "import": "./dist/project.js"
87
- },
88
- "./editor": {
89
- "types": "./dist/editor.d.ts",
90
- "import": "./dist/editor.js"
91
- },
92
- "./register": {
93
- "types": "./dist/register.d.ts",
94
- "import": "./dist/register.js"
95
- },
96
- "./schema": "./schemas/twill.schema.json",
97
- "./typescript-plugin": {
98
- "types": "./dist/typescript-plugin.d.ts",
99
- "require": "./dist/typescript-plugin.cjs",
100
- "default": "./dist/typescript-plugin.cjs"
101
- },
102
- "./doctor": {
103
- "types": "./dist/doctor.d.ts",
104
- "import": "./dist/doctor.js"
105
- },
106
- "./syntax": {
107
- "types": "./dist/syntax.d.ts",
108
- "import": "./dist/syntax.js"
109
- },
110
- "./config": {
111
- "types": "./dist/config.d.ts",
112
- "import": "./dist/config.js"
113
- },
114
- "./declarations": {
115
- "types": "./dist/declarations.d.ts",
116
- "import": "./dist/declarations.js"
117
- },
118
- "./vite-react": {
119
- "types": "./dist/vite-react.d.ts",
120
- "import": "./dist/vite-react.js"
121
- }
122
- },
123
- peerDependencies: {
124
- "react": "^18.2.0 || ^19.0.0",
125
- "vue": "^3.3.0",
126
- "@vitejs/plugin-react": "^6.1.1"
127
- },
128
- peerDependenciesMeta: {
129
- "react": { "optional": true },
130
- "vue": { "optional": true },
131
- "@vitejs/plugin-react": { "optional": true }
132
- },
133
- types: "./dist/index.d.ts",
134
- publishConfig: { "access": "public" },
135
- module: "./dist/index.js",
136
- scripts: {
137
- "build": "node ../../scripts/generate-runtime-helper.mjs && vite build && vite build --config vite.plugin.config.ts && node scripts/prepare-core.mjs",
138
- "typecheck": "tsc --noEmit -p tsconfig.json",
139
- "prepack": "pnpm run build",
140
- "test:unit": "vitest run",
141
- "test:watch": "vitest",
142
- "test:coverage": "vitest run --coverage",
143
- "test:package": "node tests/consumer.mjs",
144
- "test:size": "node tests/bundle-size.mjs",
145
- "test:browser": "playwright test",
146
- "benchmark": "node benchmarks/compiler.mjs",
147
- "test": "pnpm run test:unit",
148
- "benchmark:branching": "node benchmarks/branching.mjs",
149
- "benchmark:enum-patterns": "node benchmarks/enum-patterns.mjs",
150
- "benchmark:runtime": "node benchmarks/runtime-helpers.mjs",
151
- "benchmark:if-bindings": "node benchmarks/if-bindings.mjs"
152
- },
153
- devDependencies: {
154
- "vite": "catalog:",
155
- "vite-plugin-dts": "^5.1.2",
156
- "@types/node": "catalog:",
157
- "@vitejs/plugin-react": "catalog:",
158
- "vitest": "catalog:",
159
- "@vitest/coverage-v8": "catalog:",
160
- "@rspack/core": "catalog:",
161
- "@types/react": "catalog:",
162
- "@types/react-dom": "catalog:",
163
- "@vue/server-renderer": "catalog:",
164
- "esbuild": "catalog:",
165
- "react": "catalog:",
166
- "react-dom": "catalog:",
167
- "rollup": "catalog:",
168
- "vue": "catalog:",
169
- "webpack": "catalog:",
170
- "@playwright/test": "catalog:",
171
- "@swiftuijs/twill-runtime": "workspace:*"
172
- }
173
- };
174
- //#endregion
175
- //#region src/doctor.ts
176
- /** Shareable diagnostics without source contents or environment-variable values. */
177
- function inspectProject(project, filename) {
178
- const started = performance.now();
179
- const diagnostics = project.diagnostics(filename);
180
- const files = project.sourceFiles();
181
- return {
182
- twillVersion: package_default.version,
183
- typescriptVersion: ts.version,
184
- nodeVersion: process.version,
185
- root: project.root,
186
- configFiles: project.configFiles,
187
- compilerOptions: project.compilerOptions,
188
- files: {
189
- total: files.length,
190
- twill: files.filter(isTwillFile).length,
191
- native: files.filter((file) => !isTwillFile(file)).length
192
- },
193
- sourceFiles: files,
194
- diagnostics,
195
- diagnosticTimeMs: performance.now() - started,
196
- ok: !diagnostics.some((diagnostic) => diagnostic.category === "error")
197
- };
198
- }
199
- //#endregion
1
+ import { t as inspectProject } from "./doctor-Co_pdZtt.js";
200
2
  export { inspectProject };
201
-
202
- //# sourceMappingURL=doctor.js.map
package/dist/editor.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { n as isTwillFile } from "./extensions-B1xTkoYP.js";
2
- import { sourceFilename, virtualFilename } from "./project.js";
2
+ import { n as sourceFilename, r as virtualFilename } from "./project-ZmlpFooa.js";
3
3
  import ts from "typescript";
4
4
  //#region src/editor.ts
5
5
  /** Shared semantic requests and conservative source edits for both editor hosts. */
package/dist/esbuild.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as twillPlugin } from "./plugin-BHfiQ2L-.js";
1
+ import { t as twillPlugin } from "./plugin-DdTVagIU.js";
2
2
  //#region src/esbuild.ts
3
3
  var esbuild_default = twillPlugin.esbuild;
4
4
  //#endregion
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { a as transform, i as originalPosition, n as generatedPosition, r as inferLanguage, t as TwillSyntaxError } from "./compiler-CbNSBUI2.js";
1
+ import { a as transform, i as originalPosition, n as generatedPosition, r as inferLanguage, t as TwillSyntaxError } from "./compiler-BdkU4Ruh.js";
2
2
  import { n as isTwillFile, t as extensions } from "./extensions-B1xTkoYP.js";
3
3
  export { TwillSyntaxError, extensions, generatedPosition, inferLanguage, isTwillFile, originalPosition, transform };
@@ -1,5 +1,5 @@
1
1
  import { r as loaderConfiguration } from "./configuration-BVMf6Q_j.js";
2
- import { n as transpileNative, t as transpile } from "./transpile-D8P8Lsbx.js";
2
+ import { n as transpileNative, t as transpile } from "./transpile-CLNavDUr.js";
3
3
  import ts from "typescript";
4
4
  //#region src/loader-compiler.ts
5
5
  function compileModule(source, filename, dialect) {
@@ -16,4 +16,4 @@ function compileModule(source, filename, dialect) {
16
16
  //#endregion
17
17
  export { compileModule };
18
18
 
19
- //# sourceMappingURL=loader-compiler-D1teTrXw.js.map
19
+ //# sourceMappingURL=loader-compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-compiler.js","names":[],"sources":["../src/loader-compiler.ts"],"sourcesContent":["import ts from 'typescript';\nimport { transpile, transpileNative } from './transpile.js';\nimport { loaderConfiguration } from './configuration.js';\n\nexport function compileModule(source: string, filename: string, dialect: boolean) {\n const { config, observations } = loaderConfiguration(filename);\n const result = dialect\n ? transpile(source, { ...config, filename }, ts.ScriptTarget.ES2022)\n : transpileNative(\n source,\n filename,\n undefined,\n undefined,\n config.jsxImportSource,\n ts.ScriptTarget.ES2022,\n );\n return {\n source:\n result.code +\n '\\n//# sourceMappingURL=data:application/json;base64,' +\n Buffer.from(result.map).toString('base64'),\n observations,\n };\n}\n"],"mappings":";;;;AAIA,SAAgB,cAAc,QAAgB,UAAkB,SAAkB;CAChF,MAAM,EAAE,QAAQ,iBAAiB,oBAAoB,QAAQ;CAC7D,MAAM,SAAS,UACX,UAAU,QAAQ;EAAE,GAAG;EAAQ;CAAS,GAAG,GAAG,aAAa,MAAM,IACjE,gBACE,QACA,UACA,KAAA,GACA,KAAA,GACA,OAAO,iBACP,GAAG,aAAa,MAClB;CACJ,OAAO;EACL,QACE,OAAO,OACP,yDACA,OAAO,KAAK,OAAO,GAAG,CAAC,CAAC,SAAS,QAAQ;EAC3C;CACF;AACF"}
@@ -0,0 +1,15 @@
1
+ import * as nodeModule from "node:module";
2
+ //#region src/loader-registration.ts
3
+ /** Internal registrar shared by the CLI and the public --import entry. */
4
+ async function registerLoader(data = {}) {
5
+ if (typeof nodeModule.registerHooks !== "function") {
6
+ nodeModule.register("./loader.js", import.meta.url, { data });
7
+ return;
8
+ }
9
+ const { createHooks } = await import("./loader-sync.js");
10
+ return nodeModule.registerHooks(createHooks(data));
11
+ }
12
+ //#endregion
13
+ export { registerLoader as t };
14
+
15
+ //# sourceMappingURL=loader-registration-B1ST9h1e.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-registration-B1ST9h1e.js","names":[],"sources":["../src/loader-registration.ts"],"sourcesContent":["import * as nodeModule from 'node:module';\nimport type { LoaderOptions } from './loader-state.js';\n\n/** Internal registrar shared by the CLI and the public --import entry. */\nexport async function registerLoader(data: LoaderOptions = {}) {\n if (typeof nodeModule.registerHooks !== 'function') {\n nodeModule.register('./loader.js', import.meta.url, { data });\n return;\n }\n const { createHooks } = await import('./loader-sync.js');\n return nodeModule.registerHooks(createHooks(data));\n}\n"],"mappings":";;;AAIA,eAAsB,eAAe,OAAsB,CAAC,GAAG;CAC7D,IAAI,OAAO,WAAW,kBAAkB,YAAY;EAClD,WAAW,SAAS,eAAe,YAAY,KAAK,EAAE,KAAK,CAAC;EAC5D;CACF;CACA,MAAM,EAAE,gBAAgB,MAAM,OAAO;CACrC,OAAO,WAAW,cAAc,YAAY,IAAI,CAAC;AACnD"}
@@ -0,0 +1,4 @@
1
+ import { LoaderOptions } from './loader-state.js';
2
+ import * as nodeModule from 'node:module';
3
+ /** Internal registrar shared by the CLI and the public --import entry. */
4
+ export declare function registerLoader(data?: LoaderOptions): Promise<nodeModule.ModuleHooks | undefined>;
@@ -0,0 +1,2 @@
1
+ import { t as registerLoader } from "./loader-registration-B1ST9h1e.js";
2
+ export { registerLoader };
@@ -0,0 +1,61 @@
1
+ import { n as isTwillFile } from "./extensions-B1xTkoYP.js";
2
+ import { i as openCompilationCache } from "./compilation-cache-7SugqJ4n.js";
3
+ import { n as needsTypeEmission, r as resolveSourceFile, t as isDependency } from "./files-BW9geU0_.js";
4
+ import { readFileSync } from "node:fs";
5
+ import { fileURLToPath, pathToFileURL } from "node:url";
6
+ //#region src/loader-state.ts
7
+ function resolveMissing(specifier, parentURL, error) {
8
+ if (["ERR_MODULE_NOT_FOUND", "ERR_UNSUPPORTED_DIR_IMPORT"].includes(error?.code ?? "") && specifier.startsWith(".") && parentURL?.startsWith("file:")) {
9
+ const target = new URL(specifier, parentURL);
10
+ const candidate = resolveSourceFile(fileURLToPath(target));
11
+ if (candidate) return {
12
+ url: pathToFileURL(candidate).href + target.search + target.hash,
13
+ shortCircuit: true
14
+ };
15
+ }
16
+ throw error;
17
+ }
18
+ function moduleSource(source) {
19
+ return {
20
+ format: "module",
21
+ source,
22
+ shortCircuit: true
23
+ };
24
+ }
25
+ /** Shared I/O and cache policy; only the small Node hook adapters differ. */
26
+ var LoaderState = class {
27
+ entries;
28
+ cacheEnabled;
29
+ cache;
30
+ cacheInitialized = false;
31
+ constructor(data = {}) {
32
+ this.entries = new Set(data.entries);
33
+ this.cacheEnabled = data.cache === true && process.env.TWILL_CACHE !== "0";
34
+ }
35
+ prepare(url) {
36
+ if (!url.startsWith("file:")) return;
37
+ const filename = fileURLToPath(url);
38
+ const dialect = isTwillFile(url) || this.entries.has(url);
39
+ if (!dialect && (isDependency(filename) || !needsTypeEmission(filename))) return;
40
+ const source = readFileSync(filename, "utf8");
41
+ if (this.cacheEnabled && !this.cacheInitialized) {
42
+ this.cache = openCompilationCache();
43
+ this.cacheInitialized = true;
44
+ }
45
+ return {
46
+ url,
47
+ filename,
48
+ source,
49
+ dialect,
50
+ cached: this.cache?.read(url, source, dialect)
51
+ };
52
+ }
53
+ complete(plan, result) {
54
+ this.cache?.write(plan.url, plan.source, plan.dialect, result.source, result.observations);
55
+ return moduleSource(result.source);
56
+ }
57
+ };
58
+ //#endregion
59
+ export { moduleSource as n, resolveMissing as r, LoaderState as t };
60
+
61
+ //# sourceMappingURL=loader-state-DE2ArGYl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-state-DE2ArGYl.js","names":[],"sources":["../src/loader-state.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport { isTwillFile } from './extensions.js';\nimport { isDependency, needsTypeEmission, resolveSourceFile } from './files.js';\nimport { openCompilationCache, type CompilationCache } from './compilation-cache.js';\n\nexport type LoaderOptions = { entries?: string[]; cache?: boolean };\nexport type PreparedModule = {\n url: string;\n filename: string;\n source: string;\n dialect: boolean;\n cached: string | undefined;\n};\n\nexport function resolveMissing(specifier: string, parentURL: string | undefined, error: unknown) {\n if (\n ['ERR_MODULE_NOT_FOUND', 'ERR_UNSUPPORTED_DIR_IMPORT'].includes(\n (error as NodeJS.ErrnoException | undefined)?.code ?? '',\n ) &&\n specifier.startsWith('.') &&\n parentURL?.startsWith('file:')\n ) {\n const target = new URL(specifier, parentURL);\n const candidate = resolveSourceFile(fileURLToPath(target));\n if (candidate)\n return {\n url: pathToFileURL(candidate).href + target.search + target.hash,\n shortCircuit: true,\n };\n }\n throw error;\n}\n\nexport function moduleSource(source: string) {\n return { format: 'module' as const, source, shortCircuit: true };\n}\n\n/** Shared I/O and cache policy; only the small Node hook adapters differ. */\nexport class LoaderState {\n private entries: Set<string>;\n private cacheEnabled: boolean;\n private cache: CompilationCache | undefined;\n private cacheInitialized = false;\n\n constructor(data: LoaderOptions = {}) {\n this.entries = new Set(data.entries);\n this.cacheEnabled = data.cache === true && process.env.TWILL_CACHE !== '0';\n }\n\n prepare(url: string): PreparedModule | undefined {\n if (!url.startsWith('file:')) return;\n const filename = fileURLToPath(url);\n const dialect = isTwillFile(url) || this.entries.has(url);\n if (!dialect && (isDependency(filename) || !needsTypeEmission(filename))) return;\n const source = readFileSync(filename, 'utf8');\n if (this.cacheEnabled && !this.cacheInitialized) {\n this.cache = openCompilationCache();\n this.cacheInitialized = true;\n }\n return { url, filename, source, dialect, cached: this.cache?.read(url, source, dialect) };\n }\n\n complete(\n plan: PreparedModule,\n result: ReturnType<typeof import('./loader-compiler.js').compileModule>,\n ) {\n this.cache?.write(plan.url, plan.source, plan.dialect, result.source, result.observations);\n return moduleSource(result.source);\n }\n}\n"],"mappings":";;;;;;AAeA,SAAgB,eAAe,WAAmB,WAA+B,OAAgB;CAC/F,IACE,CAAC,wBAAwB,4BAA4B,CAAC,CAAC,SACpD,OAA6C,QAAQ,EACxD,KACA,UAAU,WAAW,GAAG,KACxB,WAAW,WAAW,OAAO,GAC7B;EACA,MAAM,SAAS,IAAI,IAAI,WAAW,SAAS;EAC3C,MAAM,YAAY,kBAAkB,cAAc,MAAM,CAAC;EACzD,IAAI,WACF,OAAO;GACL,KAAK,cAAc,SAAS,CAAC,CAAC,OAAO,OAAO,SAAS,OAAO;GAC5D,cAAc;EAChB;CACJ;CACA,MAAM;AACR;AAEA,SAAgB,aAAa,QAAgB;CAC3C,OAAO;EAAE,QAAQ;EAAmB;EAAQ,cAAc;CAAK;AACjE;;AAGA,IAAa,cAAb,MAAyB;CACvB;CACA;CACA;CACA,mBAA2B;CAE3B,YAAY,OAAsB,CAAC,GAAG;EACpC,KAAK,UAAU,IAAI,IAAI,KAAK,OAAO;EACnC,KAAK,eAAe,KAAK,UAAU,QAAQ,QAAQ,IAAI,gBAAgB;CACzE;CAEA,QAAQ,KAAyC;EAC/C,IAAI,CAAC,IAAI,WAAW,OAAO,GAAG;EAC9B,MAAM,WAAW,cAAc,GAAG;EAClC,MAAM,UAAU,YAAY,GAAG,KAAK,KAAK,QAAQ,IAAI,GAAG;EACxD,IAAI,CAAC,YAAY,aAAa,QAAQ,KAAK,CAAC,kBAAkB,QAAQ,IAAI;EAC1E,MAAM,SAAS,aAAa,UAAU,MAAM;EAC5C,IAAI,KAAK,gBAAgB,CAAC,KAAK,kBAAkB;GAC/C,KAAK,QAAQ,qBAAqB;GAClC,KAAK,mBAAmB;EAC1B;EACA,OAAO;GAAE;GAAK;GAAU;GAAQ;GAAS,QAAQ,KAAK,OAAO,KAAK,KAAK,QAAQ,OAAO;EAAE;CAC1F;CAEA,SACE,MACA,QACA;EACA,KAAK,OAAO,MAAM,KAAK,KAAK,KAAK,QAAQ,KAAK,SAAS,OAAO,QAAQ,OAAO,YAAY;EACzF,OAAO,aAAa,OAAO,MAAM;CACnC;AACF"}
@@ -0,0 +1,34 @@
1
+ export type LoaderOptions = {
2
+ entries?: string[];
3
+ cache?: boolean;
4
+ };
5
+ export type PreparedModule = {
6
+ url: string;
7
+ filename: string;
8
+ source: string;
9
+ dialect: boolean;
10
+ cached: string | undefined;
11
+ };
12
+ export declare function resolveMissing(specifier: string, parentURL: string | undefined, error: unknown): {
13
+ url: string;
14
+ shortCircuit: boolean;
15
+ };
16
+ export declare function moduleSource(source: string): {
17
+ format: "module";
18
+ source: string;
19
+ shortCircuit: boolean;
20
+ };
21
+ /** Shared I/O and cache policy; only the small Node hook adapters differ. */
22
+ export declare class LoaderState {
23
+ private entries;
24
+ private cacheEnabled;
25
+ private cache;
26
+ private cacheInitialized;
27
+ constructor(data?: LoaderOptions);
28
+ prepare(url: string): PreparedModule | undefined;
29
+ complete(plan: PreparedModule, result: ReturnType<typeof import('./loader-compiler.js').compileModule>): {
30
+ format: "module";
31
+ source: string;
32
+ shortCircuit: boolean;
33
+ };
34
+ }
@@ -0,0 +1,3 @@
1
+ import { RegisterHooksOptions } from 'node:module';
2
+ import { LoaderOptions } from './loader-state.js';
3
+ export declare function createHooks(data?: LoaderOptions): RegisterHooksOptions;
@@ -0,0 +1,28 @@
1
+ import { n as moduleSource, r as resolveMissing, t as LoaderState } from "./loader-state-DE2ArGYl.js";
2
+ import { createRequire } from "node:module";
3
+ //#region src/loader-sync.ts
4
+ var require = createRequire(import.meta.url);
5
+ function createHooks(data = {}) {
6
+ const state = new LoaderState(data);
7
+ let compileModule;
8
+ return {
9
+ resolve(specifier, context, nextResolve) {
10
+ try {
11
+ return nextResolve(specifier, context);
12
+ } catch (error) {
13
+ return resolveMissing(specifier, context.parentURL, error);
14
+ }
15
+ },
16
+ load(url, context, nextLoad) {
17
+ const plan = state.prepare(url);
18
+ if (!plan) return nextLoad(url, context);
19
+ if (plan.cached !== void 0) return moduleSource(plan.cached);
20
+ compileModule ??= require("./loader-compiler.js").compileModule;
21
+ return state.complete(plan, compileModule(plan.source, plan.filename, plan.dialect));
22
+ }
23
+ };
24
+ }
25
+ //#endregion
26
+ export { createHooks };
27
+
28
+ //# sourceMappingURL=loader-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-sync.js","names":[],"sources":["../src/loader-sync.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport type { RegisterHooksOptions } from 'node:module';\nimport { LoaderState, moduleSource, resolveMissing, type LoaderOptions } from './loader-state.js';\n\nconst require = createRequire(import.meta.url);\n\nexport function createHooks(data: LoaderOptions = {}): RegisterHooksOptions {\n const state = new LoaderState(data);\n let compileModule: typeof import('./loader-compiler.js').compileModule | undefined;\n return {\n resolve(specifier, context, nextResolve) {\n try {\n return nextResolve(specifier, context);\n } catch (error) {\n return resolveMissing(specifier, context.parentURL, error);\n }\n },\n load(url, context, nextLoad) {\n const plan = state.prepare(url);\n if (!plan) return nextLoad(url, context);\n if (plan.cached !== undefined) return moduleSource(plan.cached);\n // require(ESM) is available on every Node version with registerHooks.\n // Never evaluate the compiler on native delegation or a disk-cache hit.\n compileModule ??= (require('./loader-compiler.js') as typeof import('./loader-compiler.js'))\n .compileModule;\n return state.complete(plan, compileModule(plan.source, plan.filename, plan.dialect));\n },\n };\n}\n"],"mappings":";;;AAIA,IAAM,UAAU,cAAc,YAAY,GAAG;AAE7C,SAAgB,YAAY,OAAsB,CAAC,GAAyB;CAC1E,MAAM,QAAQ,IAAI,YAAY,IAAI;CAClC,IAAI;CACJ,OAAO;EACL,QAAQ,WAAW,SAAS,aAAa;GACvC,IAAI;IACF,OAAO,YAAY,WAAW,OAAO;GACvC,SAAS,OAAO;IACd,OAAO,eAAe,WAAW,QAAQ,WAAW,KAAK;GAC3D;EACF;EACA,KAAK,KAAK,SAAS,UAAU;GAC3B,MAAM,OAAO,MAAM,QAAQ,GAAG;GAC9B,IAAI,CAAC,MAAM,OAAO,SAAS,KAAK,OAAO;GACvC,IAAI,KAAK,WAAW,KAAA,GAAW,OAAO,aAAa,KAAK,MAAM;GAG9D,kBAAmB,QAAQ,sBAAsB,CAAC,CAC/C;GACH,OAAO,MAAM,SAAS,MAAM,cAAc,KAAK,QAAQ,KAAK,UAAU,KAAK,OAAO,CAAC;EACrF;CACF;AACF"}
package/dist/loader.d.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  import { ResolveHook, LoadHook } from 'node:module';
2
- export declare function initialize(data: {
3
- entries?: string[];
4
- cache?: boolean;
5
- } | undefined): void;
2
+ import { LoaderOptions } from './loader-state.js';
3
+ export declare function initialize(data: LoaderOptions | undefined): void;
6
4
  export declare const resolve: ResolveHook;
7
5
  export declare const load: LoadHook;
package/dist/loader.js CHANGED
@@ -1,59 +1,22 @@
1
- import { n as isTwillFile } from "./extensions-B1xTkoYP.js";
2
- import { i as openCompilationCache } from "./compilation-cache-7SugqJ4n.js";
3
- import { n as needsTypeEmission, r as resolveSourceFile, t as isDependency } from "./files-BW9geU0_.js";
4
- import { readFileSync } from "node:fs";
5
- import { fileURLToPath, pathToFileURL } from "node:url";
1
+ import { n as moduleSource, r as resolveMissing, t as LoaderState } from "./loader-state-DE2ArGYl.js";
6
2
  //#region src/loader.ts
7
- var entries = /* @__PURE__ */ new Set();
8
- var cacheEnabled = false;
9
- var cache;
10
- var cacheInitialized = false;
3
+ var state = new LoaderState();
11
4
  function initialize(data) {
12
- entries = new Set(data?.entries);
13
- cacheEnabled = data?.cache === true && process.env.TWILL_CACHE !== "0";
14
- cache = void 0;
15
- cacheInitialized = false;
5
+ state = new LoaderState(data);
16
6
  }
17
7
  var resolve = async (specifier, context, nextResolve) => {
18
8
  try {
19
9
  return await nextResolve(specifier, context);
20
10
  } catch (error) {
21
- if (["ERR_MODULE_NOT_FOUND", "ERR_UNSUPPORTED_DIR_IMPORT"].includes(error.code ?? "") && specifier.startsWith(".") && context.parentURL?.startsWith("file:")) {
22
- const target = new URL(specifier, context.parentURL);
23
- const base = fileURLToPath(target);
24
- const candidate = resolveSourceFile(base);
25
- if (candidate) return {
26
- url: pathToFileURL(candidate).href + target.search + target.hash,
27
- shortCircuit: true
28
- };
29
- }
30
- throw error;
11
+ return resolveMissing(specifier, context.parentURL, error);
31
12
  }
32
13
  };
33
14
  var load = async (url, context, nextLoad) => {
34
- if (!url.startsWith("file:")) return nextLoad(url, context);
35
- const filename = fileURLToPath(url);
36
- const dialect = isTwillFile(filename) || entries.has(url);
37
- if (!dialect && (isDependency(filename) || !needsTypeEmission(filename))) return nextLoad(url, context);
38
- const source = readFileSync(filename, "utf8");
39
- if (cacheEnabled && !cacheInitialized) {
40
- cache = openCompilationCache();
41
- cacheInitialized = true;
42
- }
43
- const cached = cache?.read(url, source, dialect);
44
- if (cached !== void 0) return {
45
- format: "module",
46
- source: cached,
47
- shortCircuit: true
48
- };
49
- const { compileModule } = await import("./loader-compiler-D1teTrXw.js");
50
- const result = compileModule(source, filename, dialect);
51
- cache?.write(url, source, dialect, result.source, result.observations);
52
- return {
53
- format: "module",
54
- source: result.source,
55
- shortCircuit: true
56
- };
15
+ const plan = state.prepare(url);
16
+ if (!plan) return nextLoad(url, context);
17
+ if (plan.cached !== void 0) return moduleSource(plan.cached);
18
+ const { compileModule } = await import("./loader-compiler.js");
19
+ return state.complete(plan, compileModule(plan.source, plan.filename, plan.dialect));
57
20
  };
58
21
  //#endregion
59
22
  export { initialize, load, resolve };
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","names":[],"sources":["../src/loader.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport type { ResolveHook, LoadHook } from 'node:module';\nimport { isTwillFile } from './extensions.js';\nimport { isDependency, needsTypeEmission, resolveSourceFile } from './files.js';\nimport { openCompilationCache, type CompilationCache } from './compilation-cache.js';\n\nlet entries = new Set<string>();\nlet cacheEnabled = false;\nlet cache: CompilationCache | undefined;\nlet cacheInitialized = false;\nexport function initialize(data: { entries?: string[]; cache?: boolean } | undefined) {\n entries = new Set(data?.entries);\n cacheEnabled = data?.cache === true && process.env.TWILL_CACHE !== '0';\n cache = undefined;\n cacheInitialized = false;\n}\n\nexport const resolve: ResolveHook = async (specifier, context, nextResolve) => {\n try {\n return await nextResolve(specifier, context);\n } catch (error) {\n if (\n ['ERR_MODULE_NOT_FOUND', 'ERR_UNSUPPORTED_DIR_IMPORT'].includes(\n (error as NodeJS.ErrnoException).code ?? '',\n ) &&\n specifier.startsWith('.') &&\n context.parentURL?.startsWith('file:')\n ) {\n const target = new URL(specifier, context.parentURL);\n const base = fileURLToPath(target);\n const candidate = resolveSourceFile(base);\n if (candidate)\n return {\n url: pathToFileURL(candidate).href + target.search + target.hash,\n shortCircuit: true,\n };\n }\n throw error;\n }\n};\n\nexport const load: LoadHook = async (url, context, nextLoad) => {\n if (!url.startsWith('file:')) return nextLoad(url, context);\n const filename = fileURLToPath(url);\n const dialect = isTwillFile(filename) || entries.has(url);\n if (!dialect && (isDependency(filename) || !needsTypeEmission(filename)))\n return nextLoad(url, context);\n const source = readFileSync(filename, 'utf8');\n if (cacheEnabled && !cacheInitialized) {\n cache = openCompilationCache();\n cacheInitialized = true;\n }\n const cached = cache?.read(url, source, dialect);\n if (cached !== undefined) return { format: 'module', source: cached, shortCircuit: true };\n const { compileModule } = await import('./loader-compiler.js');\n const result = compileModule(source, filename, dialect);\n cache?.write(url, source, dialect, result.source, result.observations);\n return { format: 'module', source: result.source, shortCircuit: true };\n};\n"],"mappings":";;;;;;AAOA,IAAI,0BAAU,IAAI,IAAY;AAC9B,IAAI,eAAe;AACnB,IAAI;AACJ,IAAI,mBAAmB;AACvB,SAAgB,WAAW,MAA2D;CACpF,UAAU,IAAI,IAAI,MAAM,OAAO;CAC/B,eAAe,MAAM,UAAU,QAAQ,QAAQ,IAAI,gBAAgB;CACnE,QAAQ,KAAA;CACR,mBAAmB;AACrB;AAEA,IAAa,UAAuB,OAAO,WAAW,SAAS,gBAAgB;CAC7E,IAAI;EACF,OAAO,MAAM,YAAY,WAAW,OAAO;CAC7C,SAAS,OAAO;EACd,IACE,CAAC,wBAAwB,4BAA4B,CAAC,CAAC,SACpD,MAAgC,QAAQ,EAC3C,KACA,UAAU,WAAW,GAAG,KACxB,QAAQ,WAAW,WAAW,OAAO,GACrC;GACA,MAAM,SAAS,IAAI,IAAI,WAAW,QAAQ,SAAS;GACnD,MAAM,OAAO,cAAc,MAAM;GACjC,MAAM,YAAY,kBAAkB,IAAI;GACxC,IAAI,WACF,OAAO;IACL,KAAK,cAAc,SAAS,CAAC,CAAC,OAAO,OAAO,SAAS,OAAO;IAC5D,cAAc;GAChB;EACJ;EACA,MAAM;CACR;AACF;AAEA,IAAa,OAAiB,OAAO,KAAK,SAAS,aAAa;CAC9D,IAAI,CAAC,IAAI,WAAW,OAAO,GAAG,OAAO,SAAS,KAAK,OAAO;CAC1D,MAAM,WAAW,cAAc,GAAG;CAClC,MAAM,UAAU,YAAY,QAAQ,KAAK,QAAQ,IAAI,GAAG;CACxD,IAAI,CAAC,YAAY,aAAa,QAAQ,KAAK,CAAC,kBAAkB,QAAQ,IACpE,OAAO,SAAS,KAAK,OAAO;CAC9B,MAAM,SAAS,aAAa,UAAU,MAAM;CAC5C,IAAI,gBAAgB,CAAC,kBAAkB;EACrC,QAAQ,qBAAqB;EAC7B,mBAAmB;CACrB;CACA,MAAM,SAAS,OAAO,KAAK,KAAK,QAAQ,OAAO;CAC/C,IAAI,WAAW,KAAA,GAAW,OAAO;EAAE,QAAQ;EAAU,QAAQ;EAAQ,cAAc;CAAK;CACxF,MAAM,EAAE,kBAAkB,MAAM,OAAO;CACvC,MAAM,SAAS,cAAc,QAAQ,UAAU,OAAO;CACtD,OAAO,MAAM,KAAK,QAAQ,SAAS,OAAO,QAAQ,OAAO,YAAY;CACrE,OAAO;EAAE,QAAQ;EAAU,QAAQ,OAAO;EAAQ,cAAc;CAAK;AACvE"}
1
+ {"version":3,"file":"loader.js","names":[],"sources":["../src/loader.ts"],"sourcesContent":["import type { ResolveHook, LoadHook } from 'node:module';\nimport { LoaderState, moduleSource, resolveMissing, type LoaderOptions } from './loader-state.js';\n\nlet state = new LoaderState();\nexport function initialize(data: LoaderOptions | undefined) {\n state = new LoaderState(data);\n}\n\nexport const resolve: ResolveHook = async (specifier, context, nextResolve) => {\n try {\n return await nextResolve(specifier, context);\n } catch (error) {\n return resolveMissing(specifier, context.parentURL, error);\n }\n};\n\nexport const load: LoadHook = async (url, context, nextLoad) => {\n const plan = state.prepare(url);\n if (!plan) return nextLoad(url, context);\n if (plan.cached !== undefined) return moduleSource(plan.cached);\n const { compileModule } = await import('./loader-compiler.js');\n return state.complete(plan, compileModule(plan.source, plan.filename, plan.dialect));\n};\n"],"mappings":";;AAGA,IAAI,QAAQ,IAAI,YAAY;AAC5B,SAAgB,WAAW,MAAiC;CAC1D,QAAQ,IAAI,YAAY,IAAI;AAC9B;AAEA,IAAa,UAAuB,OAAO,WAAW,SAAS,gBAAgB;CAC7E,IAAI;EACF,OAAO,MAAM,YAAY,WAAW,OAAO;CAC7C,SAAS,OAAO;EACd,OAAO,eAAe,WAAW,QAAQ,WAAW,KAAK;CAC3D;AACF;AAEA,IAAa,OAAiB,OAAO,KAAK,SAAS,aAAa;CAC9D,MAAM,OAAO,MAAM,QAAQ,GAAG;CAC9B,IAAI,CAAC,MAAM,OAAO,SAAS,KAAK,OAAO;CACvC,IAAI,KAAK,WAAW,KAAA,GAAW,OAAO,aAAa,KAAK,MAAM;CAC9D,MAAM,EAAE,kBAAkB,MAAM,OAAO;CACvC,OAAO,MAAM,SAAS,MAAM,cAAc,KAAK,QAAQ,KAAK,UAAU,KAAK,OAAO,CAAC;AACrF"}
@@ -1,7 +1,7 @@
1
1
  import { n as isTwillFile } from "./extensions-B1xTkoYP.js";
2
2
  import { n as loadConfig, t as configurationFiles } from "./configuration-BVMf6Q_j.js";
3
3
  import { a as splitId, i as sourceExtensions, n as needsTypeEmission, r as resolveSourceFile, t as isDependency } from "./files-BW9geU0_.js";
4
- import { n as transpileNative, t as transpile } from "./transpile-D8P8Lsbx.js";
4
+ import { n as transpileNative, t as transpile } from "./transpile-CLNavDUr.js";
5
5
  import { existsSync } from "node:fs";
6
6
  import { dirname, isAbsolute, resolve } from "node:path";
7
7
  import { createUnplugin } from "unplugin";
@@ -138,4 +138,4 @@ var twillPlugin = createUnplugin((options = {}, meta) => {
138
138
  //#endregion
139
139
  export { twillPlugin as t };
140
140
 
141
- //# sourceMappingURL=plugin-BHfiQ2L-.js.map
141
+ //# sourceMappingURL=plugin-DdTVagIU.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-BHfiQ2L-.js","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["import { dirname, isAbsolute, resolve } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { createUnplugin } from 'unplugin';\nimport { isTwillFile, type TransformOptions } from './compiler.js';\nimport { loadConfig, configurationFiles } from './config.js';\nimport { transpile, transpileNative } from './transpile.js';\nimport {\n isDependency,\n needsTypeEmission,\n splitId,\n resolveSourceFile,\n sourceExtensions,\n} from './files.js';\n\nexport interface PluginOptions extends Omit<TransformOptions, 'filename' | 'language'> {\n root?: string;\n /** Resolve relative extensionless native/Twill sources. Defaults to true. */\n resolveExtensions?: boolean;\n /** Native TS/JSX emission: defaults off for Vite/esbuild, on for Rollup/webpack/rspack. */\n nativeSources?: boolean;\n}\n\nexport const twillPlugin = createUnplugin<PluginOptions | undefined, false>(\n (options = {}, meta) => {\n let root = options.root ?? process.cwd();\n let config = { ...loadConfig(root), ...options };\n let configFiles = configurationFiles(root);\n let configError: unknown;\n let servingVite = false;\n // Reuse native host emission where it already exists.\n const nativeSources = options.nativeSources ?? !['vite', 'esbuild'].includes(meta.framework);\n return {\n name: 'twill',\n enforce: 'pre',\n buildStart() {\n // Refresh once per build, including incremental contexts. Vite dev\n // uses its server watcher to report errors and invalidate the graph.\n if (!servingVite) {\n configError = undefined;\n try {\n config = { ...loadConfig(root), ...options };\n configFiles = configurationFiles(root);\n } catch (cause) {\n // Report through transformed modules, retaining their watch\n // dependencies. A fatal make/start error can stop host watching.\n configError = cause;\n }\n }\n },\n webpack(compiler) {\n if (nativeSources)\n compiler.options.module.rules.push({\n include: (file) => !isDependency(file) && needsTypeEmission(file),\n // Twill already emits JS. Webpack's automatic TS stripper rejects\n // .tsx by extension even when a loader has lowered all JSX.\n parser: { typescript: false },\n });\n },\n esbuild: {\n setup(build) {\n // unplugin tags its resolved files with a custom namespace. Native\n // dependencies of those files must re-enter esbuild's normal resolver.\n build.onResolve({ filter: /.*/, namespace: 'twill' }, (args) =>\n build.resolve(args.path, {\n resolveDir: dirname(args.importer),\n kind: args.kind,\n }),\n );\n },\n },\n vite: {\n configResolved(viteConfig) {\n root = options.root ?? viteConfig.root;\n config = { ...loadConfig(root), ...options };\n servingVite = viteConfig.command === 'serve';\n },\n config() {\n return {\n resolve: {\n extensions: sourceExtensions,\n },\n };\n },\n configureServer(server) {\n let files = new Set(configurationFiles(root).map((file) => resolve(file)));\n // Watch the parent of an absent file. Registering a missing path\n // directly can narrow Chokidar's directory filter and lose additions.\n const watch = () =>\n server.watcher.add([...files].map((file) => (existsSync(file) ? file : dirname(file))));\n watch();\n let update: ReturnType<typeof setTimeout> | undefined;\n const changed = (filename: string) => {\n if (files.has(resolve(filename))) {\n clearTimeout(update);\n // Chokidar throttles rapid changes for 50 ms. Read after that\n // window so consecutive saves use the final contents, and a\n // correction after an error overlay produces another event.\n update = setTimeout(() => {\n try {\n config = { ...loadConfig(root), ...options };\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n server.config.logger.error(error.message);\n server.ws.send({\n type: 'error',\n err: { message: error.message, stack: error.stack ?? '', plugin: 'twill' },\n });\n return;\n }\n files = new Set(configurationFiles(root).map((file) => resolve(file)));\n watch();\n if (server.environments)\n for (const environment of Object.values(server.environments))\n environment.moduleGraph.invalidateAll();\n else server.moduleGraph.invalidateAll();\n server.ws.send({ type: 'full-reload' });\n }, 75);\n }\n };\n server.watcher.on('change', changed).on('add', changed).on('unlink', changed);\n server.httpServer?.once('close', () => clearTimeout(update));\n // Chokidar removes listeners when the watcher closes. HTTP can close\n // and reopen independently of the watcher during server setup.\n },\n },\n resolveId(id, importer) {\n if (options.resolveExtensions === false || (!id.startsWith('.') && !isAbsolute(id)))\n return null;\n const [path, query] = splitId(id);\n const base = isAbsolute(path!)\n ? path!\n : resolve(importer ? dirname(splitId(importer)[0]) : root, path!);\n const candidate = resolveSourceFile(base);\n if (!candidate || candidate === base) return null;\n if (meta.framework === 'esbuild' && !isTwillFile(candidate)) return null;\n return candidate + query;\n },\n transformInclude(id) {\n const filename = splitId(id)[0];\n return (\n !isDependency(filename) &&\n (isTwillFile(filename) || (nativeSources && needsTypeEmission(filename)))\n );\n },\n transform(source, id) {\n const filename = splitId(id)[0];\n if (isDependency(filename)) return null;\n const dialect = isTwillFile(filename);\n if (!dialect && !(nativeSources && needsTypeEmission(filename))) return null;\n // Vite's dev import analysis treats addWatchFile as a browser import.\n // Watch config with the server instead; a missing optional config\n // must never become an unresolved browser module.\n if (!servingVite) for (const file of configFiles) this.addWatchFile(file);\n try {\n if (configError !== undefined) throw configError;\n return dialect\n ? transpile(source, { ...config, filename })\n : transpileNative(source, filename, undefined, undefined, config.jsxImportSource);\n } catch (cause) {\n if (meta.framework !== 'esbuild') throw cause;\n // Throwing from esbuild's onLoad discards its watchFiles. Report a\n // failed build while returning dependency metadata for recovery.\n this.error(cause instanceof Error ? cause : String(cause));\n return { code: ';', map: null };\n }\n },\n };\n },\n);\n"],"mappings":";;;;;;;;AAsBA,IAAa,cAAc,gBACxB,UAAU,CAAC,GAAG,SAAS;CACtB,IAAI,OAAO,QAAQ,QAAQ,QAAQ,IAAI;CACvC,IAAI,SAAS;EAAE,GAAG,WAAW,IAAI;EAAG,GAAG;CAAQ;CAC/C,IAAI,cAAc,mBAAmB,IAAI;CACzC,IAAI;CACJ,IAAI,cAAc;CAElB,MAAM,gBAAgB,QAAQ,iBAAiB,CAAC,CAAC,QAAQ,SAAS,CAAC,CAAC,SAAS,KAAK,SAAS;CAC3F,OAAO;EACL,MAAM;EACN,SAAS;EACT,aAAa;GAGX,IAAI,CAAC,aAAa;IAChB,cAAc,KAAA;IACd,IAAI;KACF,SAAS;MAAE,GAAG,WAAW,IAAI;MAAG,GAAG;KAAQ;KAC3C,cAAc,mBAAmB,IAAI;IACvC,SAAS,OAAO;KAGd,cAAc;IAChB;GACF;EACF;EACA,QAAQ,UAAU;GAChB,IAAI,eACF,SAAS,QAAQ,OAAO,MAAM,KAAK;IACjC,UAAU,SAAS,CAAC,aAAa,IAAI,KAAK,kBAAkB,IAAI;IAGhE,QAAQ,EAAE,YAAY,MAAM;GAC9B,CAAC;EACL;EACA,SAAS,EACP,MAAM,OAAO;GAGX,MAAM,UAAU;IAAE,QAAQ;IAAM,WAAW;GAAQ,IAAI,SACrD,MAAM,QAAQ,KAAK,MAAM;IACvB,YAAY,QAAQ,KAAK,QAAQ;IACjC,MAAM,KAAK;GACb,CAAC,CACH;EACF,EACF;EACA,MAAM;GACJ,eAAe,YAAY;IACzB,OAAO,QAAQ,QAAQ,WAAW;IAClC,SAAS;KAAE,GAAG,WAAW,IAAI;KAAG,GAAG;IAAQ;IAC3C,cAAc,WAAW,YAAY;GACvC;GACA,SAAS;IACP,OAAO,EACL,SAAS,EACP,YAAY,iBACd,EACF;GACF;GACA,gBAAgB,QAAQ;IACtB,IAAI,QAAQ,IAAI,IAAI,mBAAmB,IAAI,CAAC,CAAC,KAAK,SAAS,QAAQ,IAAI,CAAC,CAAC;IAGzE,MAAM,cACJ,OAAO,QAAQ,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,SAAU,WAAW,IAAI,IAAI,OAAO,QAAQ,IAAI,CAAE,CAAC;IACxF,MAAM;IACN,IAAI;IACJ,MAAM,WAAW,aAAqB;KACpC,IAAI,MAAM,IAAI,QAAQ,QAAQ,CAAC,GAAG;MAChC,aAAa,MAAM;MAInB,SAAS,iBAAiB;OACxB,IAAI;QACF,SAAS;SAAE,GAAG,WAAW,IAAI;SAAG,GAAG;QAAQ;OAC7C,SAAS,OAAO;QACd,MAAM,QAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;QACtE,OAAO,OAAO,OAAO,MAAM,MAAM,OAAO;QACxC,OAAO,GAAG,KAAK;SACb,MAAM;SACN,KAAK;UAAE,SAAS,MAAM;UAAS,OAAO,MAAM,SAAS;UAAI,QAAQ;SAAQ;QAC3E,CAAC;QACD;OACF;OACA,QAAQ,IAAI,IAAI,mBAAmB,IAAI,CAAC,CAAC,KAAK,SAAS,QAAQ,IAAI,CAAC,CAAC;OACrE,MAAM;OACN,IAAI,OAAO,cACT,KAAK,MAAM,eAAe,OAAO,OAAO,OAAO,YAAY,GACzD,YAAY,YAAY,cAAc;YACrC,OAAO,YAAY,cAAc;OACtC,OAAO,GAAG,KAAK,EAAE,MAAM,cAAc,CAAC;MACxC,GAAG,EAAE;KACP;IACF;IACA,OAAO,QAAQ,GAAG,UAAU,OAAO,CAAC,CAAC,GAAG,OAAO,OAAO,CAAC,CAAC,GAAG,UAAU,OAAO;IAC5E,OAAO,YAAY,KAAK,eAAe,aAAa,MAAM,CAAC;GAG7D;EACF;EACA,UAAU,IAAI,UAAU;GACtB,IAAI,QAAQ,sBAAsB,SAAU,CAAC,GAAG,WAAW,GAAG,KAAK,CAAC,WAAW,EAAE,GAC/E,OAAO;GACT,MAAM,CAAC,MAAM,SAAS,QAAQ,EAAE;GAChC,MAAM,OAAO,WAAW,IAAK,IACzB,OACA,QAAQ,WAAW,QAAQ,QAAQ,QAAQ,CAAC,CAAC,EAAE,IAAI,MAAM,IAAK;GAClE,MAAM,YAAY,kBAAkB,IAAI;GACxC,IAAI,CAAC,aAAa,cAAc,MAAM,OAAO;GAC7C,IAAI,KAAK,cAAc,aAAa,CAAC,YAAY,SAAS,GAAG,OAAO;GACpE,OAAO,YAAY;EACrB;EACA,iBAAiB,IAAI;GACnB,MAAM,WAAW,QAAQ,EAAE,CAAC,CAAC;GAC7B,OACE,CAAC,aAAa,QAAQ,MACrB,YAAY,QAAQ,KAAM,iBAAiB,kBAAkB,QAAQ;EAE1E;EACA,UAAU,QAAQ,IAAI;GACpB,MAAM,WAAW,QAAQ,EAAE,CAAC,CAAC;GAC7B,IAAI,aAAa,QAAQ,GAAG,OAAO;GACnC,MAAM,UAAU,YAAY,QAAQ;GACpC,IAAI,CAAC,WAAW,EAAE,iBAAiB,kBAAkB,QAAQ,IAAI,OAAO;GAIxE,IAAI,CAAC,aAAa,KAAK,MAAM,QAAQ,aAAa,KAAK,aAAa,IAAI;GACxE,IAAI;IACF,IAAI,gBAAgB,KAAA,GAAW,MAAM;IACrC,OAAO,UACH,UAAU,QAAQ;KAAE,GAAG;KAAQ;IAAS,CAAC,IACzC,gBAAgB,QAAQ,UAAU,KAAA,GAAW,KAAA,GAAW,OAAO,eAAe;GACpF,SAAS,OAAO;IACd,IAAI,KAAK,cAAc,WAAW,MAAM;IAGxC,KAAK,MAAM,iBAAiB,QAAQ,QAAQ,OAAO,KAAK,CAAC;IACzD,OAAO;KAAE,MAAM;KAAK,KAAK;IAAK;GAChC;EACF;CACF;AACF,CACF"}
1
+ {"version":3,"file":"plugin-DdTVagIU.js","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["import { dirname, isAbsolute, resolve } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { createUnplugin } from 'unplugin';\nimport { isTwillFile, type TransformOptions } from './compiler.js';\nimport { loadConfig, configurationFiles } from './config.js';\nimport { transpile, transpileNative } from './transpile.js';\nimport {\n isDependency,\n needsTypeEmission,\n splitId,\n resolveSourceFile,\n sourceExtensions,\n} from './files.js';\n\nexport interface PluginOptions extends Omit<TransformOptions, 'filename' | 'language'> {\n root?: string;\n /** Resolve relative extensionless native/Twill sources. Defaults to true. */\n resolveExtensions?: boolean;\n /** Native TS/JSX emission: defaults off for Vite/esbuild, on for Rollup/webpack/rspack. */\n nativeSources?: boolean;\n}\n\nexport const twillPlugin = createUnplugin<PluginOptions | undefined, false>(\n (options = {}, meta) => {\n let root = options.root ?? process.cwd();\n let config = { ...loadConfig(root), ...options };\n let configFiles = configurationFiles(root);\n let configError: unknown;\n let servingVite = false;\n // Reuse native host emission where it already exists.\n const nativeSources = options.nativeSources ?? !['vite', 'esbuild'].includes(meta.framework);\n return {\n name: 'twill',\n enforce: 'pre',\n buildStart() {\n // Refresh once per build, including incremental contexts. Vite dev\n // uses its server watcher to report errors and invalidate the graph.\n if (!servingVite) {\n configError = undefined;\n try {\n config = { ...loadConfig(root), ...options };\n configFiles = configurationFiles(root);\n } catch (cause) {\n // Report through transformed modules, retaining their watch\n // dependencies. A fatal make/start error can stop host watching.\n configError = cause;\n }\n }\n },\n webpack(compiler) {\n if (nativeSources)\n compiler.options.module.rules.push({\n include: (file) => !isDependency(file) && needsTypeEmission(file),\n // Twill already emits JS. Webpack's automatic TS stripper rejects\n // .tsx by extension even when a loader has lowered all JSX.\n parser: { typescript: false },\n });\n },\n esbuild: {\n setup(build) {\n // unplugin tags its resolved files with a custom namespace. Native\n // dependencies of those files must re-enter esbuild's normal resolver.\n build.onResolve({ filter: /.*/, namespace: 'twill' }, (args) =>\n build.resolve(args.path, {\n resolveDir: dirname(args.importer),\n kind: args.kind,\n }),\n );\n },\n },\n vite: {\n configResolved(viteConfig) {\n root = options.root ?? viteConfig.root;\n config = { ...loadConfig(root), ...options };\n servingVite = viteConfig.command === 'serve';\n },\n config() {\n return {\n resolve: {\n extensions: sourceExtensions,\n },\n };\n },\n configureServer(server) {\n let files = new Set(configurationFiles(root).map((file) => resolve(file)));\n // Watch the parent of an absent file. Registering a missing path\n // directly can narrow Chokidar's directory filter and lose additions.\n const watch = () =>\n server.watcher.add([...files].map((file) => (existsSync(file) ? file : dirname(file))));\n watch();\n let update: ReturnType<typeof setTimeout> | undefined;\n const changed = (filename: string) => {\n if (files.has(resolve(filename))) {\n clearTimeout(update);\n // Chokidar throttles rapid changes for 50 ms. Read after that\n // window so consecutive saves use the final contents, and a\n // correction after an error overlay produces another event.\n update = setTimeout(() => {\n try {\n config = { ...loadConfig(root), ...options };\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n server.config.logger.error(error.message);\n server.ws.send({\n type: 'error',\n err: { message: error.message, stack: error.stack ?? '', plugin: 'twill' },\n });\n return;\n }\n files = new Set(configurationFiles(root).map((file) => resolve(file)));\n watch();\n if (server.environments)\n for (const environment of Object.values(server.environments))\n environment.moduleGraph.invalidateAll();\n else server.moduleGraph.invalidateAll();\n server.ws.send({ type: 'full-reload' });\n }, 75);\n }\n };\n server.watcher.on('change', changed).on('add', changed).on('unlink', changed);\n server.httpServer?.once('close', () => clearTimeout(update));\n // Chokidar removes listeners when the watcher closes. HTTP can close\n // and reopen independently of the watcher during server setup.\n },\n },\n resolveId(id, importer) {\n if (options.resolveExtensions === false || (!id.startsWith('.') && !isAbsolute(id)))\n return null;\n const [path, query] = splitId(id);\n const base = isAbsolute(path!)\n ? path!\n : resolve(importer ? dirname(splitId(importer)[0]) : root, path!);\n const candidate = resolveSourceFile(base);\n if (!candidate || candidate === base) return null;\n if (meta.framework === 'esbuild' && !isTwillFile(candidate)) return null;\n return candidate + query;\n },\n transformInclude(id) {\n const filename = splitId(id)[0];\n return (\n !isDependency(filename) &&\n (isTwillFile(filename) || (nativeSources && needsTypeEmission(filename)))\n );\n },\n transform(source, id) {\n const filename = splitId(id)[0];\n if (isDependency(filename)) return null;\n const dialect = isTwillFile(filename);\n if (!dialect && !(nativeSources && needsTypeEmission(filename))) return null;\n // Vite's dev import analysis treats addWatchFile as a browser import.\n // Watch config with the server instead; a missing optional config\n // must never become an unresolved browser module.\n if (!servingVite) for (const file of configFiles) this.addWatchFile(file);\n try {\n if (configError !== undefined) throw configError;\n return dialect\n ? transpile(source, { ...config, filename })\n : transpileNative(source, filename, undefined, undefined, config.jsxImportSource);\n } catch (cause) {\n if (meta.framework !== 'esbuild') throw cause;\n // Throwing from esbuild's onLoad discards its watchFiles. Report a\n // failed build while returning dependency metadata for recovery.\n this.error(cause instanceof Error ? cause : String(cause));\n return { code: ';', map: null };\n }\n },\n };\n },\n);\n"],"mappings":";;;;;;;;AAsBA,IAAa,cAAc,gBACxB,UAAU,CAAC,GAAG,SAAS;CACtB,IAAI,OAAO,QAAQ,QAAQ,QAAQ,IAAI;CACvC,IAAI,SAAS;EAAE,GAAG,WAAW,IAAI;EAAG,GAAG;CAAQ;CAC/C,IAAI,cAAc,mBAAmB,IAAI;CACzC,IAAI;CACJ,IAAI,cAAc;CAElB,MAAM,gBAAgB,QAAQ,iBAAiB,CAAC,CAAC,QAAQ,SAAS,CAAC,CAAC,SAAS,KAAK,SAAS;CAC3F,OAAO;EACL,MAAM;EACN,SAAS;EACT,aAAa;GAGX,IAAI,CAAC,aAAa;IAChB,cAAc,KAAA;IACd,IAAI;KACF,SAAS;MAAE,GAAG,WAAW,IAAI;MAAG,GAAG;KAAQ;KAC3C,cAAc,mBAAmB,IAAI;IACvC,SAAS,OAAO;KAGd,cAAc;IAChB;GACF;EACF;EACA,QAAQ,UAAU;GAChB,IAAI,eACF,SAAS,QAAQ,OAAO,MAAM,KAAK;IACjC,UAAU,SAAS,CAAC,aAAa,IAAI,KAAK,kBAAkB,IAAI;IAGhE,QAAQ,EAAE,YAAY,MAAM;GAC9B,CAAC;EACL;EACA,SAAS,EACP,MAAM,OAAO;GAGX,MAAM,UAAU;IAAE,QAAQ;IAAM,WAAW;GAAQ,IAAI,SACrD,MAAM,QAAQ,KAAK,MAAM;IACvB,YAAY,QAAQ,KAAK,QAAQ;IACjC,MAAM,KAAK;GACb,CAAC,CACH;EACF,EACF;EACA,MAAM;GACJ,eAAe,YAAY;IACzB,OAAO,QAAQ,QAAQ,WAAW;IAClC,SAAS;KAAE,GAAG,WAAW,IAAI;KAAG,GAAG;IAAQ;IAC3C,cAAc,WAAW,YAAY;GACvC;GACA,SAAS;IACP,OAAO,EACL,SAAS,EACP,YAAY,iBACd,EACF;GACF;GACA,gBAAgB,QAAQ;IACtB,IAAI,QAAQ,IAAI,IAAI,mBAAmB,IAAI,CAAC,CAAC,KAAK,SAAS,QAAQ,IAAI,CAAC,CAAC;IAGzE,MAAM,cACJ,OAAO,QAAQ,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,SAAU,WAAW,IAAI,IAAI,OAAO,QAAQ,IAAI,CAAE,CAAC;IACxF,MAAM;IACN,IAAI;IACJ,MAAM,WAAW,aAAqB;KACpC,IAAI,MAAM,IAAI,QAAQ,QAAQ,CAAC,GAAG;MAChC,aAAa,MAAM;MAInB,SAAS,iBAAiB;OACxB,IAAI;QACF,SAAS;SAAE,GAAG,WAAW,IAAI;SAAG,GAAG;QAAQ;OAC7C,SAAS,OAAO;QACd,MAAM,QAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;QACtE,OAAO,OAAO,OAAO,MAAM,MAAM,OAAO;QACxC,OAAO,GAAG,KAAK;SACb,MAAM;SACN,KAAK;UAAE,SAAS,MAAM;UAAS,OAAO,MAAM,SAAS;UAAI,QAAQ;SAAQ;QAC3E,CAAC;QACD;OACF;OACA,QAAQ,IAAI,IAAI,mBAAmB,IAAI,CAAC,CAAC,KAAK,SAAS,QAAQ,IAAI,CAAC,CAAC;OACrE,MAAM;OACN,IAAI,OAAO,cACT,KAAK,MAAM,eAAe,OAAO,OAAO,OAAO,YAAY,GACzD,YAAY,YAAY,cAAc;YACrC,OAAO,YAAY,cAAc;OACtC,OAAO,GAAG,KAAK,EAAE,MAAM,cAAc,CAAC;MACxC,GAAG,EAAE;KACP;IACF;IACA,OAAO,QAAQ,GAAG,UAAU,OAAO,CAAC,CAAC,GAAG,OAAO,OAAO,CAAC,CAAC,GAAG,UAAU,OAAO;IAC5E,OAAO,YAAY,KAAK,eAAe,aAAa,MAAM,CAAC;GAG7D;EACF;EACA,UAAU,IAAI,UAAU;GACtB,IAAI,QAAQ,sBAAsB,SAAU,CAAC,GAAG,WAAW,GAAG,KAAK,CAAC,WAAW,EAAE,GAC/E,OAAO;GACT,MAAM,CAAC,MAAM,SAAS,QAAQ,EAAE;GAChC,MAAM,OAAO,WAAW,IAAK,IACzB,OACA,QAAQ,WAAW,QAAQ,QAAQ,QAAQ,CAAC,CAAC,EAAE,IAAI,MAAM,IAAK;GAClE,MAAM,YAAY,kBAAkB,IAAI;GACxC,IAAI,CAAC,aAAa,cAAc,MAAM,OAAO;GAC7C,IAAI,KAAK,cAAc,aAAa,CAAC,YAAY,SAAS,GAAG,OAAO;GACpE,OAAO,YAAY;EACrB;EACA,iBAAiB,IAAI;GACnB,MAAM,WAAW,QAAQ,EAAE,CAAC,CAAC;GAC7B,OACE,CAAC,aAAa,QAAQ,MACrB,YAAY,QAAQ,KAAM,iBAAiB,kBAAkB,QAAQ;EAE1E;EACA,UAAU,QAAQ,IAAI;GACpB,MAAM,WAAW,QAAQ,EAAE,CAAC,CAAC;GAC7B,IAAI,aAAa,QAAQ,GAAG,OAAO;GACnC,MAAM,UAAU,YAAY,QAAQ;GACpC,IAAI,CAAC,WAAW,EAAE,iBAAiB,kBAAkB,QAAQ,IAAI,OAAO;GAIxE,IAAI,CAAC,aAAa,KAAK,MAAM,QAAQ,aAAa,KAAK,aAAa,IAAI;GACxE,IAAI;IACF,IAAI,gBAAgB,KAAA,GAAW,MAAM;IACrC,OAAO,UACH,UAAU,QAAQ;KAAE,GAAG;KAAQ;IAAS,CAAC,IACzC,gBAAgB,QAAQ,UAAU,KAAA,GAAW,KAAA,GAAW,OAAO,eAAe;GACpF,SAAS,OAAO;IACd,IAAI,KAAK,cAAc,WAAW,MAAM;IAGxC,KAAK,MAAM,iBAAiB,QAAQ,QAAQ,OAAO,KAAK,CAAC;IACzD,OAAO;KAAE,MAAM;KAAK,KAAK;IAAK;GAChC;EACF;CACF;AACF,CACF"}