xanix 1.0.9 → 1.0.11

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 (39) hide show
  1. package/dist/bin/bundler/buildClient.js +4 -3
  2. package/dist/bin/bundler/buildServer.js +4 -3
  3. package/dist/bin/bundler/cacheNpmModules.js +2 -1
  4. package/dist/bin/bundler/config/output.d.ts +0 -4
  5. package/dist/bin/bundler/config/output.js +3 -7
  6. package/dist/bin/bundler/plugins/XanixEntryFinder/finder.js +2 -1
  7. package/dist/bin/bundler/plugins/XanixPageTransform/index.d.ts +2 -0
  8. package/dist/bin/bundler/plugins/XanixPageTransform/index.js +19 -0
  9. package/dist/bin/bundler/plugins/XanixPageTransform/transformer.d.ts +16 -0
  10. package/dist/bin/bundler/plugins/XanixPageTransform/transformer.js +501 -0
  11. package/dist/bin/bundler/plugins/XanixPageTransform.d.ts +0 -0
  12. package/dist/bin/bundler/plugins/XanixPageTransform.js +1 -0
  13. package/dist/bin/bundler/plugins/XanixResolveCacheDeps/index.js +6 -2
  14. package/dist/bin/bundler/plugins/XanixServerTransform.d.ts +5 -0
  15. package/dist/bin/bundler/plugins/XanixServerTransform.js +130 -0
  16. package/dist/bin/bundler/plugins/XanixTransform/index.d.ts +1 -4
  17. package/dist/bin/bundler/plugins/XanixTransform/index.js +2 -2
  18. package/dist/bin/bundler/plugins/XanixTransform/transformer.d.ts +1 -1
  19. package/dist/bin/bundler/plugins/XanixTransform/transformer.js +1 -131
  20. package/dist/bin/bundler/plugins/plugins.js +4 -3
  21. package/dist/bin/bundler/watchClient.js +4 -3
  22. package/dist/bin/bundler/watchServer.js +4 -4
  23. package/dist/bin/cli/dev.js +2 -2
  24. package/dist/bin/cli/start.js +2 -2
  25. package/dist/bin/include/manifest.js +2 -1
  26. package/dist/client-runtime.js +2 -1
  27. package/dist/components/Head.js +2 -1
  28. package/dist/dirs.d.ts +0 -0
  29. package/dist/dirs.js +1 -0
  30. package/dist/hooks/useData.js +2 -1
  31. package/dist/index.d.ts +1 -0
  32. package/dist/outdir.d.ts +8 -0
  33. package/dist/outdir.js +9 -0
  34. package/dist/outdirs.d.ts +8 -0
  35. package/dist/outdirs.js +9 -0
  36. package/dist/server/runtime/createServer.js +7 -6
  37. package/dist/server/runtime/readManifest.js +2 -1
  38. package/dist/types/globals.d.ts +0 -1
  39. package/package.json +1 -1
@@ -1,8 +1,9 @@
1
1
  import { rollup } from "rollup";
2
2
  import fs from "node:fs";
3
- import bundlerOutput, { outDir } from "./config/output.js";
3
+ import bundlerOutput from "./config/output.js";
4
4
  import { getClientRuntimeFile, getClientRuntimeFileName, } from "../include/utils.js";
5
5
  import { xanixDefaultPlugins } from "./plugins/plugins.js";
6
+ import outdirs from "../../outdirs.js";
6
7
  const buildClient = async (entries) => {
7
8
  const input = {};
8
9
  for (const entry of entries) {
@@ -10,11 +11,11 @@ const buildClient = async (entries) => {
10
11
  }
11
12
  const runtimeFileName = getClientRuntimeFileName("production");
12
13
  input[runtimeFileName] = getClientRuntimeFile();
13
- fs.rmSync(outDir.client, {
14
+ fs.rmSync(outdirs.client, {
14
15
  recursive: true,
15
16
  force: true,
16
17
  });
17
- fs.mkdirSync(outDir.client, {
18
+ fs.mkdirSync(outdirs.client, {
18
19
  recursive: true,
19
20
  });
20
21
  const build = await rollup({
@@ -1,17 +1,18 @@
1
1
  import { rollup } from "rollup";
2
2
  import path from "node:path";
3
- import bundlerOutput, { outDir } from "./config/output.js";
3
+ import bundlerOutput from "./config/output.js";
4
4
  import fs from "node:fs";
5
5
  import { createManifest } from "../include/manifest.js";
6
6
  import generateClientEntries from "./generateClientEntries.js";
7
7
  import { xanixDefaultPlugins } from "./plugins/plugins.js";
8
+ import outdirs from "../../outdirs.js";
8
9
  const root = process.cwd();
9
10
  const BuildServer = async ({ rootEntry, onBuildEnd }) => {
10
- fs.rmSync(outDir.server, {
11
+ fs.rmSync(outdirs.server, {
11
12
  recursive: true,
12
13
  force: true,
13
14
  });
14
- fs.mkdirSync(outDir.server, {
15
+ fs.mkdirSync(outdirs.server, {
15
16
  recursive: true,
16
17
  });
17
18
  const entries = await generateClientEntries();
@@ -7,6 +7,7 @@ import { getClientRuntimeFile } from "../include/utils.js";
7
7
  import esbuild from "rollup-plugin-esbuild";
8
8
  import url from "@rollup/plugin-url";
9
9
  import XanixDocument from "./plugins/XanixDocument/index.js";
10
+ import outdirs from "../../outdirs.js";
10
11
  const require = createRequire(import.meta.url);
11
12
  const GenerateGraph = async (entries) => {
12
13
  const collector = new Map();
@@ -154,7 +155,7 @@ const BuildCache = async (entries) => {
154
155
  file: `${entryName}.js`,
155
156
  });
156
157
  }
157
- const cacheDir = path.resolve(process.cwd(), ".xanix/cache");
158
+ const cacheDir = path.resolve(outdirs.server, "cache");
158
159
  await bundleDeps(input, cacheDir);
159
160
  return metadata;
160
161
  };
@@ -1,9 +1,5 @@
1
1
  import { OutputOptions } from "rollup";
2
2
  import { XanixClientEntry } from "../../types";
3
- export declare const outDir: {
4
- server: string;
5
- client: string;
6
- };
7
3
  type Options = {
8
4
  isDev?: boolean;
9
5
  };
@@ -1,16 +1,12 @@
1
- import path from "node:path";
1
+ import outdirs from "../../../outdirs.js";
2
2
  const root = process.cwd();
3
- export const outDir = {
4
- server: path.resolve(root, ".xanix"),
5
- client: path.resolve(root, ".xanix/client"),
6
- };
7
3
  const client = (entries, { isDev }) => {
8
4
  const _entries = {};
9
5
  for (const entry of entries) {
10
6
  _entries[entry.name] = entry;
11
7
  }
12
8
  const opt = {
13
- dir: outDir.client,
9
+ dir: outdirs.client,
14
10
  format: "esm",
15
11
  entryFileNames: (id) => {
16
12
  const entry = _entries[id.name];
@@ -33,7 +29,7 @@ const client = (entries, { isDev }) => {
33
29
  };
34
30
  const server = (opt) => {
35
31
  return {
36
- dir: outDir.server,
32
+ dir: outdirs.server,
37
33
  format: "esm",
38
34
  sourcemap: opt.isDev ?? true,
39
35
  entryFileNames: "[name].js",
@@ -4,6 +4,7 @@ import crypto from "node:crypto";
4
4
  import { parse } from "@babel/parser";
5
5
  import traverse from "@babel/traverse";
6
6
  import * as t from "@babel/types";
7
+ import outdirs from "../../../../outdirs.js";
7
8
  const SOURCE_EXTENSIONS = [".tsx", ".ts", ".jsx", ".js", ".mjs", ".cjs"];
8
9
  function normalizeFilePath(file) {
9
10
  return path.resolve(file).split(path.sep).join("/");
@@ -140,7 +141,7 @@ export function entryFinder(code, id) {
140
141
  const root = process.cwd();
141
142
  const relativeSource = path.relative(root, componentFile);
142
143
  const parsed = path.parse(relativeSource);
143
- const buildPath = normalizeFilePath(path.resolve(root, ".xanix", parsed.dir, `${parsed.name}.js`));
144
+ const buildPath = normalizeFilePath(path.resolve(root, outdirs.root, parsed.dir, `${parsed.name}.js`));
144
145
  const entry = {
145
146
  id: clientId,
146
147
  name: componentName,
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from "rollup";
2
+ export default function XanixPageTransform(): Plugin;
@@ -0,0 +1,19 @@
1
+ import { transformer } from "./transformer.js";
2
+ export default function XanixPageTransform() {
3
+ return {
4
+ name: "xanix-page-transform",
5
+ async transform(code, id) {
6
+ if (id.includes("node_modules") || !/\.(tsx?|jsx?)$/.test(id)) {
7
+ return null;
8
+ }
9
+ const result = transformer(code, id);
10
+ if (!result) {
11
+ return null;
12
+ }
13
+ return {
14
+ code: result.code,
15
+ map: result.map,
16
+ };
17
+ },
18
+ };
19
+ }
@@ -0,0 +1,16 @@
1
+ import * as t from "@babel/types";
2
+ export interface XanixTransformResult {
3
+ code: string;
4
+ map: any;
5
+ }
6
+ export declare function resolveFile(file: string): string;
7
+ export declare function resolveComponentFile(importer: string, importPath: string): string;
8
+ export declare function createPageId(file: string): string;
9
+ export declare function getJSXComponentName(node: t.JSXElement): string | null;
10
+ export declare function findComponentImport(ast: t.File, componentName: string): {
11
+ file: string;
12
+ export: string;
13
+ declaration: t.ImportDeclaration;
14
+ specifier: t.ImportSpecifier | t.ImportDefaultSpecifier;
15
+ } | null;
16
+ export declare function transformer(code: string, id: string): XanixTransformResult | null;
@@ -0,0 +1,501 @@
1
+ import path from "node:path";
2
+ import fs from "node:fs";
3
+ import crypto from "node:crypto";
4
+ import { parse } from "@babel/parser";
5
+ import traverse from "@babel/traverse";
6
+ import generate from "@babel/generator";
7
+ import * as t from "@babel/types";
8
+ const RUNTIME_IMPORT = "xanix/runtime";
9
+ const SOURCE_EXTENSIONS = [".tsx", ".ts", ".jsx", ".js", ".mjs", ".cjs"];
10
+ function normalizeFilePath(file) {
11
+ return path.resolve(file).split(path.sep).join("/");
12
+ }
13
+ export function resolveFile(file) {
14
+ const absolute = path.resolve(file);
15
+ if (fs.existsSync(absolute)) {
16
+ const stat = fs.statSync(absolute);
17
+ if (stat.isFile()) {
18
+ return absolute;
19
+ }
20
+ }
21
+ for (const ext of SOURCE_EXTENSIONS) {
22
+ const candidate = `${absolute}${ext}`;
23
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
24
+ return path.resolve(candidate);
25
+ }
26
+ }
27
+ if (fs.existsSync(absolute) && fs.statSync(absolute).isDirectory()) {
28
+ for (const ext of SOURCE_EXTENSIONS) {
29
+ const candidate = path.join(absolute, `index${ext}`);
30
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
31
+ return path.resolve(candidate);
32
+ }
33
+ }
34
+ }
35
+ return absolute;
36
+ }
37
+ export function resolveComponentFile(importer, importPath) {
38
+ if (!importPath.startsWith(".")) {
39
+ return importPath;
40
+ }
41
+ const base = path.resolve(path.dirname(importer), importPath);
42
+ return resolveFile(base);
43
+ }
44
+ export function createPageId(file) {
45
+ return `c_${crypto
46
+ .createHash("sha256")
47
+ .update(path.normalize(file))
48
+ .digest("hex")
49
+ .slice(0, 12)}`;
50
+ }
51
+ export function getJSXComponentName(node) {
52
+ const name = node.openingElement.name;
53
+ if (t.isJSXIdentifier(name)) {
54
+ return name.name;
55
+ }
56
+ if (t.isJSXMemberExpression(name)) {
57
+ if (t.isJSXIdentifier(name.object) && t.isJSXIdentifier(name.property)) {
58
+ return `${name.object.name}.${name.property.name}`;
59
+ }
60
+ }
61
+ return null;
62
+ }
63
+ export function findComponentImport(ast, componentName) {
64
+ for (const node of ast.program.body) {
65
+ if (!t.isImportDeclaration(node)) {
66
+ continue;
67
+ }
68
+ for (const specifier of node.specifiers) {
69
+ if (t.isImportDefaultSpecifier(specifier) &&
70
+ specifier.local.name === componentName) {
71
+ return {
72
+ file: node.source.value,
73
+ export: "default",
74
+ declaration: node,
75
+ specifier,
76
+ };
77
+ }
78
+ if (t.isImportSpecifier(specifier) &&
79
+ specifier.local.name === componentName) {
80
+ const imported = specifier.imported;
81
+ return {
82
+ file: node.source.value,
83
+ export: t.isIdentifier(imported) ? imported.name : imported.value,
84
+ declaration: node,
85
+ specifier,
86
+ };
87
+ }
88
+ }
89
+ }
90
+ return null;
91
+ }
92
+ /**
93
+ * Remove a specific component from:
94
+ *
95
+ * import Home from "./Home";
96
+ *
97
+ * or:
98
+ *
99
+ * import Home, { foo } from "./Home";
100
+ *
101
+ * or:
102
+ *
103
+ * import { Home, foo } from "./Home";
104
+ */
105
+ function removeComponentImport(componentImport) {
106
+ const { declaration, specifier } = componentImport;
107
+ const index = declaration.specifiers.indexOf(specifier);
108
+ if (index !== -1) {
109
+ declaration.specifiers.splice(index, 1);
110
+ }
111
+ }
112
+ function removeEmptyImportDeclarations(ast) {
113
+ ast.program.body = ast.program.body.filter((statement) => {
114
+ if (!t.isImportDeclaration(statement)) {
115
+ return true;
116
+ }
117
+ return statement.specifiers.length > 0;
118
+ });
119
+ }
120
+ /**
121
+ * Create:
122
+ *
123
+ * const Home =
124
+ * (await import("./Home")).default;
125
+ *
126
+ * or:
127
+ *
128
+ * const Home =
129
+ * (await import("./Home")).Home;
130
+ */
131
+ function createDynamicComponentImport(componentName, importPath, exportName) {
132
+ const importCall = t.callExpression(t.import(), [
133
+ t.stringLiteral(importPath),
134
+ ]);
135
+ const awaitedImport = t.awaitExpression(importCall);
136
+ const property = exportName === "default"
137
+ ? t.identifier("default")
138
+ : t.identifier(exportName);
139
+ const value = t.memberExpression(awaitedImport, property);
140
+ return t.variableDeclaration("const", [
141
+ t.variableDeclarator(t.identifier(componentName), value),
142
+ ]);
143
+ }
144
+ /**
145
+ * Convert a JSX name into an expression.
146
+ *
147
+ * Example:
148
+ *
149
+ * <Home />
150
+ *
151
+ * becomes:
152
+ *
153
+ * Home
154
+ */
155
+ function jsxNameToExpression(name) {
156
+ if (t.isJSXIdentifier(name)) {
157
+ return t.identifier(name.name);
158
+ }
159
+ if (t.isJSXMemberExpression(name)) {
160
+ const object = jsxNameToExpressionFromJSXName(name.object);
161
+ const property = jsxNameToExpressionFromJSXName(name.property);
162
+ if (!object || !property) {
163
+ return null;
164
+ }
165
+ return t.memberExpression(object, property);
166
+ }
167
+ return null;
168
+ }
169
+ function jsxNameToExpressionFromJSXName(name) {
170
+ if (t.isJSXIdentifier(name)) {
171
+ return t.identifier(name.name);
172
+ }
173
+ if (t.isJSXMemberExpression(name)) {
174
+ const object = jsxNameToExpressionFromJSXName(name.object);
175
+ const property = jsxNameToExpressionFromJSXName(name.property);
176
+ if (!object || !property) {
177
+ return null;
178
+ }
179
+ return t.memberExpression(object, property);
180
+ }
181
+ return null;
182
+ }
183
+ /**
184
+ * Convert JSX attributes into an object expression.
185
+ *
186
+ * Example:
187
+ *
188
+ * <Home
189
+ * name="Naxrul"
190
+ * age={30}
191
+ * active
192
+ * {...user}
193
+ * />
194
+ *
195
+ * becomes:
196
+ *
197
+ * {
198
+ * name: "Naxrul",
199
+ * age: 30,
200
+ * active: true,
201
+ * ...user
202
+ * }
203
+ */
204
+ function jsxAttributesToProps(jsx) {
205
+ const properties = [];
206
+ for (const attribute of jsx.openingElement.attributes) {
207
+ /**
208
+ * Handle:
209
+ *
210
+ * {...props}
211
+ */
212
+ if (t.isJSXSpreadAttribute(attribute)) {
213
+ properties.push(t.spreadElement(attribute.argument));
214
+ continue;
215
+ }
216
+ /**
217
+ * Normal JSX attribute:
218
+ *
219
+ * name="value"
220
+ * name={value}
221
+ * active
222
+ */
223
+ if (!t.isJSXAttribute(attribute)) {
224
+ continue;
225
+ }
226
+ function jsxAttributeNameToExpression(name) {
227
+ if (t.isJSXIdentifier(name)) {
228
+ return t.identifier(name.name);
229
+ }
230
+ return t.stringLiteral(`${name.namespace.name}:${name.name.name}`);
231
+ }
232
+ const key = jsxAttributeNameToExpression(attribute.name);
233
+ /**
234
+ * Boolean JSX prop:
235
+ *
236
+ * <Home active />
237
+ *
238
+ * becomes:
239
+ *
240
+ * active: true
241
+ */
242
+ if (!attribute.value) {
243
+ properties.push(t.objectProperty(key, t.booleanLiteral(true)));
244
+ continue;
245
+ }
246
+ /**
247
+ * String prop:
248
+ *
249
+ * name="Naxrul"
250
+ *
251
+ * becomes:
252
+ *
253
+ * name: "Naxrul"
254
+ */
255
+ if (t.isStringLiteral(attribute.value)) {
256
+ properties.push(t.objectProperty(key, t.stringLiteral(attribute.value.value)));
257
+ continue;
258
+ }
259
+ /**
260
+ * Expression prop:
261
+ *
262
+ * age={30}
263
+ * user={user}
264
+ * items={items.map(...)}
265
+ */
266
+ if (t.isJSXExpressionContainer(attribute.value)) {
267
+ const expression = attribute.value.expression;
268
+ if (t.isJSXEmptyExpression(expression)) {
269
+ continue;
270
+ }
271
+ properties.push(t.objectProperty(key, expression));
272
+ continue;
273
+ }
274
+ /**
275
+ * JSX element as a prop:
276
+ *
277
+ * content={<div>Hello</div>}
278
+ */
279
+ if (t.isJSXElement(attribute.value)) {
280
+ properties.push(t.objectProperty(key, attribute.value));
281
+ continue;
282
+ }
283
+ }
284
+ return t.objectExpression(properties);
285
+ }
286
+ /**
287
+ * Convert:
288
+ *
289
+ * <Home name="Naxrul" age={30} />
290
+ *
291
+ * into:
292
+ *
293
+ * {
294
+ * component: Home,
295
+ * props: {
296
+ * name: "Naxrul",
297
+ * age: 30
298
+ * }
299
+ * }
300
+ */
301
+ function jsxToComponentAndProps(jsx) {
302
+ const component = jsxNameToExpression(jsx.openingElement.name);
303
+ if (!component) {
304
+ return null;
305
+ }
306
+ const props = jsxAttributesToProps(jsx);
307
+ return {
308
+ component,
309
+ props,
310
+ };
311
+ }
312
+ function hasRuntimeImport(ast, name) {
313
+ for (const statement of ast.program.body) {
314
+ if (!t.isImportDeclaration(statement)) {
315
+ continue;
316
+ }
317
+ if (statement.source.value !== RUNTIME_IMPORT) {
318
+ continue;
319
+ }
320
+ for (const specifier of statement.specifiers) {
321
+ if (t.isImportSpecifier(specifier) &&
322
+ t.isIdentifier(specifier.imported) &&
323
+ specifier.imported.name === name) {
324
+ return true;
325
+ }
326
+ }
327
+ }
328
+ return false;
329
+ }
330
+ function injectRuntimeImport(ast, name) {
331
+ if (hasRuntimeImport(ast, name)) {
332
+ return;
333
+ }
334
+ // Find existing:
335
+ // import { ... } from "xanix/runtime";
336
+ for (const statement of ast.program.body) {
337
+ if (!t.isImportDeclaration(statement)) {
338
+ continue;
339
+ }
340
+ if (statement.source.value !== RUNTIME_IMPORT) {
341
+ continue;
342
+ }
343
+ statement.specifiers.push(t.importSpecifier(t.identifier(name), t.identifier(name)));
344
+ return;
345
+ }
346
+ // No runtime import exists yet
347
+ ast.program.body.unshift(t.importDeclaration([t.importSpecifier(t.identifier(name), t.identifier(name))], t.stringLiteral(RUNTIME_IMPORT)));
348
+ }
349
+ export function transformer(code, id) {
350
+ const ast = parse(code, {
351
+ sourceType: "module",
352
+ plugins: ["typescript", "jsx"],
353
+ });
354
+ let changed = false;
355
+ traverse(ast, {
356
+ CallExpression(callPath) {
357
+ const call = callPath.node;
358
+ /**
359
+ * Find:
360
+ *
361
+ * res.send(<Home />);
362
+ */
363
+ if (!t.isMemberExpression(call.callee)) {
364
+ return;
365
+ }
366
+ if (!t.isIdentifier(call.callee.property, {
367
+ name: "send",
368
+ })) {
369
+ return;
370
+ }
371
+ const argument = call.arguments[0];
372
+ if (!argument || !t.isJSXElement(argument)) {
373
+ return;
374
+ }
375
+ const functionPath = callPath.getFunctionParent();
376
+ if (!functionPath) {
377
+ return;
378
+ }
379
+ const params = functionPath.node.params;
380
+ if (params.length < 2) {
381
+ return;
382
+ }
383
+ const requestParam = params[0];
384
+ const responseParam = params[1];
385
+ if (!t.isIdentifier(requestParam) || !t.isIdentifier(responseParam)) {
386
+ return;
387
+ }
388
+ const componentName = getJSXComponentName(argument);
389
+ if (!componentName) {
390
+ return;
391
+ }
392
+ const componentImport = findComponentImport(ast, componentName);
393
+ if (!componentImport) {
394
+ return;
395
+ }
396
+ const componentImportPath = componentImport.file;
397
+ const componentFile = resolveComponentFile(id, componentImportPath);
398
+ if (!path.isAbsolute(componentFile)) {
399
+ return;
400
+ }
401
+ const normalizedFile = normalizeFilePath(componentFile);
402
+ const pageId = createPageId(normalizedFile);
403
+ /**
404
+ * Convert:
405
+ *
406
+ * <Home name="Naxrul" age={30} />
407
+ *
408
+ * into:
409
+ *
410
+ * component: Home
411
+ *
412
+ * props: {
413
+ * name: "Naxrul",
414
+ * age: 30
415
+ * }
416
+ */
417
+ const componentAndProps = jsxToComponentAndProps(argument);
418
+ if (!componentAndProps) {
419
+ return;
420
+ }
421
+ /**
422
+ * Remove:
423
+ *
424
+ * import Home from "./Home";
425
+ */
426
+ removeComponentImport(componentImport);
427
+ /**
428
+ * Add:
429
+ *
430
+ * const Home =
431
+ * (await import("./Home")).default;
432
+ */
433
+ const dynamicImport = createDynamicComponentImport(componentName, componentImportPath, componentImport.export);
434
+ /**
435
+ * Insert immediately before:
436
+ *
437
+ * res.send(<Home />);
438
+ */
439
+ const statementPath = callPath.getStatementParent();
440
+ if (statementPath) {
441
+ statementPath.insertBefore(dynamicImport);
442
+ }
443
+ /**
444
+ * Route becomes:
445
+ *
446
+ * async (req, res) => {}
447
+ */
448
+ if (t.isFunction(functionPath.node)) {
449
+ functionPath.node.async = true;
450
+ }
451
+ /**
452
+ * Replace:
453
+ *
454
+ * res.send(<Home />);
455
+ *
456
+ * with:
457
+ *
458
+ * res.send(
459
+ * await xanixPage({
460
+ * clientId,
461
+ * req,
462
+ * res,
463
+ * component: Home,
464
+ * props: {
465
+ * ...
466
+ * }
467
+ * })
468
+ * );
469
+ */
470
+ const pageCall = t.awaitExpression(t.callExpression(t.identifier("xanixPage"), [
471
+ t.objectExpression([
472
+ t.objectProperty(t.identifier("pageId"), t.stringLiteral(pageId)),
473
+ t.objectProperty(t.identifier("req"), t.identifier(requestParam.name)),
474
+ t.objectProperty(t.identifier("res"), t.identifier(responseParam.name)),
475
+ t.objectProperty(t.identifier("Component"), componentAndProps.component),
476
+ t.objectProperty(t.identifier("props"), componentAndProps.props),
477
+ ]),
478
+ ]));
479
+ call.arguments[0] = pageCall;
480
+ changed = true;
481
+ },
482
+ });
483
+ if (!changed) {
484
+ return null;
485
+ }
486
+ /**
487
+ * Add:
488
+ *
489
+ * import xanixPage from "xanix/page";
490
+ */
491
+ injectRuntimeImport(ast, "xanixPage");
492
+ /**
493
+ * Remove empty imports.
494
+ */
495
+ removeEmptyImportDeclarations(ast);
496
+ const output = generate(ast, {}, code);
497
+ return {
498
+ code: output.code,
499
+ map: output.map,
500
+ };
501
+ }
@@ -0,0 +1 @@
1
+ "use strict";
@@ -1,5 +1,6 @@
1
1
  import path from "node:path";
2
2
  import BuildCache from "../../cacheNpmModules.js";
3
+ import outdirs from "../../../../outdirs.js";
3
4
  function XanixResolveCacheDeps(metadata, entries) {
4
5
  if (!entries.length) {
5
6
  return {
@@ -14,12 +15,15 @@ function XanixResolveCacheDeps(metadata, entries) {
14
15
  }
15
16
  const dependency = metadata.get(source);
16
17
  if (dependency) {
17
- return { id: `/.xanix/cache/${dependency.file}`, external: true };
18
+ return { id: `/${outdirs.cache}/${dependency.file}`, external: true };
18
19
  }
19
20
  const buildCache = await BuildCache(entries);
20
21
  const newDependency = buildCache.get(source);
21
22
  if (newDependency) {
22
- return { id: `/.xanix/cache/${newDependency.file}`, external: true };
23
+ return {
24
+ id: `/${outdirs.cache}/${newDependency.file}`,
25
+ external: true,
26
+ };
23
27
  }
24
28
  },
25
29
  };