xanix 0.0.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/dist/BaseDocument.d.ts +3 -0
  2. package/dist/BaseDocument.js +8 -0
  3. package/dist/Document.d.ts +7 -0
  4. package/dist/Document.js +7 -0
  5. package/dist/bin/bundler/buildCache.d.ts +11 -0
  6. package/dist/bin/bundler/buildCache.js +129 -0
  7. package/dist/bin/bundler/buildClient.d.ts +3 -0
  8. package/dist/bin/bundler/buildClient.js +41 -0
  9. package/dist/bin/bundler/buildServer.d.ts +7 -0
  10. package/dist/bin/bundler/buildServer.js +55 -0
  11. package/dist/bin/bundler/cacheNpmModules.d.ts +11 -0
  12. package/dist/bin/bundler/cacheNpmModules.js +157 -0
  13. package/dist/bin/bundler/config/output.d.ts +14 -0
  14. package/dist/bin/bundler/config/output.js +48 -0
  15. package/dist/bin/bundler/generateClientEntries.d.ts +3 -0
  16. package/dist/bin/bundler/generateClientEntries.js +59 -0
  17. package/dist/bin/bundler/plugins/XanixAssets/index.d.ts +4 -0
  18. package/dist/bin/bundler/plugins/XanixAssets/index.js +22 -0
  19. package/dist/bin/bundler/plugins/XanixBrowserCodeRemover.d.ts +6 -0
  20. package/dist/bin/bundler/plugins/XanixBrowserCodeRemover.js +350 -0
  21. package/dist/bin/bundler/plugins/XanixEntryFinder/finder.d.ts +11 -0
  22. package/dist/bin/bundler/plugins/XanixEntryFinder/finder.js +156 -0
  23. package/dist/bin/bundler/plugins/XanixEntryFinder/index.d.ts +6 -0
  24. package/dist/bin/bundler/plugins/XanixEntryFinder/index.js +36 -0
  25. package/dist/bin/bundler/plugins/XanixEnv.d.ts +15 -0
  26. package/dist/bin/bundler/plugins/XanixEnv.js +46 -0
  27. package/dist/bin/bundler/plugins/XanixHydrate.d.ts +3 -0
  28. package/dist/bin/bundler/plugins/XanixHydrate.js +34 -0
  29. package/dist/bin/bundler/plugins/XanixReactRefresh.d.ts +2 -0
  30. package/dist/bin/bundler/plugins/XanixReactRefresh.js +126 -0
  31. package/dist/bin/bundler/plugins/XanixResolveCacheDeps/index.d.ts +5 -0
  32. package/dist/bin/bundler/plugins/XanixResolveCacheDeps/index.js +22 -0
  33. package/dist/bin/bundler/plugins/XanixTransform/index.d.ts +5 -0
  34. package/dist/bin/bundler/plugins/XanixTransform/index.js +19 -0
  35. package/dist/bin/bundler/plugins/XanixTransform/transformer.d.ts +16 -0
  36. package/dist/bin/bundler/plugins/XanixTransform/transformer.js +631 -0
  37. package/dist/bin/bundler/plugins/XanixWatchChange copy.d.ts +10 -0
  38. package/dist/bin/bundler/plugins/XanixWatchChange copy.js +30 -0
  39. package/dist/bin/bundler/plugins/XanixWatchChange.d.ts +9 -0
  40. package/dist/bin/bundler/plugins/XanixWatchChange.js +27 -0
  41. package/dist/bin/bundler/plugins/XanixWatchChangeClient.d.ts +7 -0
  42. package/dist/bin/bundler/plugins/XanixWatchChangeClient.js +15 -0
  43. package/dist/bin/bundler/plugins/commonjs.d.ts +3 -0
  44. package/dist/bin/bundler/plugins/commonjs.js +10 -0
  45. package/dist/bin/bundler/plugins/dep-XanixWatchChange.d.ts +9 -0
  46. package/dist/bin/bundler/plugins/dep-XanixWatchChange.js +27 -0
  47. package/dist/bin/bundler/plugins/nodeResolve.d.ts +3 -0
  48. package/dist/bin/bundler/plugins/nodeResolve.js +10 -0
  49. package/dist/bin/bundler/plugins/pathResolver.d.ts +5 -0
  50. package/dist/bin/bundler/plugins/pathResolver.js +57 -0
  51. package/dist/bin/bundler/plugins/plugins.d.ts +8 -0
  52. package/dist/bin/bundler/plugins/plugins.js +75 -0
  53. package/dist/bin/bundler/plugins/rollupEsbuild.d.ts +3 -0
  54. package/dist/bin/bundler/plugins/rollupEsbuild.js +14 -0
  55. package/dist/bin/bundler/plugins/xanixServerData.d.ts +6 -0
  56. package/dist/bin/bundler/plugins/xanixServerData.js +224 -0
  57. package/dist/bin/bundler/plugins/xanixTsconfigAlias.d.ts +6 -0
  58. package/dist/bin/bundler/plugins/xanixTsconfigAlias.js +51 -0
  59. package/dist/bin/bundler/plugins/xanixUseDataId.d.ts +4 -0
  60. package/dist/bin/bundler/plugins/xanixUseDataId.js +93 -0
  61. package/dist/bin/bundler/watchClient.d.ts +8 -0
  62. package/dist/bin/bundler/watchClient.js +54 -0
  63. package/dist/bin/bundler/watchServer.d.ts +10 -0
  64. package/dist/bin/bundler/watchServer.js +84 -0
  65. package/dist/bin/cli/build.d.ts +2 -0
  66. package/dist/bin/cli/build.js +18 -0
  67. package/dist/bin/cli/dev.d.ts +2 -0
  68. package/dist/bin/cli/dev.js +103 -0
  69. package/dist/bin/cli/start.d.ts +2 -0
  70. package/dist/bin/cli/start.js +19 -0
  71. package/dist/bin/include/entry.d.ts +3 -0
  72. package/dist/bin/include/entry.js +28 -0
  73. package/dist/bin/include/logger.d.ts +10 -0
  74. package/dist/bin/include/logger.js +11 -0
  75. package/dist/bin/include/manifest.d.ts +3 -0
  76. package/dist/bin/include/manifest.js +13 -0
  77. package/dist/bin/include/utils.d.ts +2 -0
  78. package/dist/bin/include/utils.js +14 -0
  79. package/dist/bin/index.d.ts +2 -0
  80. package/dist/bin/index.js +26 -0
  81. package/dist/bin/types.d.ts +12 -0
  82. package/dist/bin/types.js +1 -0
  83. package/dist/client/components/Body.d.ts +5 -0
  84. package/dist/client/components/Body.js +10 -0
  85. package/dist/client/components/Document/context.d.ts +3 -0
  86. package/dist/client/components/Document/context.js +14 -0
  87. package/dist/client/components/Document/index.d.ts +8 -0
  88. package/dist/client/components/Document/index.js +6 -0
  89. package/dist/client/components/Head copy.d.ts +5 -0
  90. package/dist/client/components/Head copy.js +8 -0
  91. package/dist/client/components/Head.d.ts +5 -0
  92. package/dist/client/components/Head.js +10 -0
  93. package/dist/client/components/Link.d.ts +6 -0
  94. package/dist/client/components/Link.js +10 -0
  95. package/dist/client/context/RouteContext.d.ts +8 -0
  96. package/dist/client/context/RouteContext.js +16 -0
  97. package/dist/client/hooks/usePageProps.d.ts +1 -0
  98. package/dist/client/hooks/usePageProps.js +2 -0
  99. package/dist/client/hooks/useRoute.d.ts +1 -0
  100. package/dist/client/hooks/useRoute.js +2 -0
  101. package/dist/client/hooks/useSearchParams.d.ts +1 -0
  102. package/dist/client/hooks/useSearchParams.js +2 -0
  103. package/dist/client/index.d.ts +2 -0
  104. package/dist/client/index.js +2 -0
  105. package/dist/client/navigation.d.ts +4 -0
  106. package/dist/client/navigation.js +14 -0
  107. package/dist/client/refresh.d.ts +7 -0
  108. package/dist/client/refresh.js +15 -0
  109. package/dist/client/runtime.d.ts +10 -0
  110. package/dist/client/runtime.js +98 -0
  111. package/dist/client-runtime.d.ts +10 -0
  112. package/dist/client-runtime.js +113 -0
  113. package/dist/components/BaseDocument.d.ts +3 -0
  114. package/dist/components/BaseDocument.js +8 -0
  115. package/dist/components/Body.d.ts +5 -0
  116. package/dist/components/Body.js +8 -0
  117. package/dist/components/Document/Document.d.ts +16 -0
  118. package/dist/components/Document/Document.js +15 -0
  119. package/dist/components/Document/context.d.ts +17 -0
  120. package/dist/components/Document/context.js +13 -0
  121. package/dist/components/Document/index.d.ts +7 -0
  122. package/dist/components/Document/index.js +10 -0
  123. package/dist/components/Document.d.ts +7 -0
  124. package/dist/components/Document.js +9 -0
  125. package/dist/components/DocumentContext/DocumentContext.d.ts +15 -0
  126. package/dist/components/DocumentContext/DocumentContext.js +18 -0
  127. package/dist/components/DocumentContext/context.d.ts +11 -0
  128. package/dist/components/DocumentContext/context.js +14 -0
  129. package/dist/components/DocumentContext/index.d.ts +15 -0
  130. package/dist/components/DocumentContext/index.js +18 -0
  131. package/dist/components/DocumentContext.d.ts +19 -0
  132. package/dist/components/DocumentContext.js +6 -0
  133. package/dist/components/DocumentProvider.d.ts +13 -0
  134. package/dist/components/DocumentProvider.js +7 -0
  135. package/dist/components/Head.d.ts +5 -0
  136. package/dist/components/Head.js +42 -0
  137. package/dist/components/Link.d.ts +7 -0
  138. package/dist/components/Link.js +28 -0
  139. package/dist/components/Script.d.ts +3 -0
  140. package/dist/components/Script.js +5 -0
  141. package/dist/dataLoader.d.ts +11 -0
  142. package/dist/dataLoader.js +46 -0
  143. package/dist/document/BaseDocument.d.ts +3 -0
  144. package/dist/document/BaseDocument.js +8 -0
  145. package/dist/document/Body.d.ts +5 -0
  146. package/dist/document/Body.js +9 -0
  147. package/dist/document/Document/Document.d.ts +7 -0
  148. package/dist/document/Document/Document.js +10 -0
  149. package/dist/document/Document/context.d.ts +17 -0
  150. package/dist/document/Document/context.js +13 -0
  151. package/dist/document/Document/index.d.ts +7 -0
  152. package/dist/document/Document/index.js +10 -0
  153. package/dist/document/Document.d.ts +7 -0
  154. package/dist/document/Document.js +10 -0
  155. package/dist/document/DocumentContext.d.ts +17 -0
  156. package/dist/document/DocumentContext.js +6 -0
  157. package/dist/document/Head.d.ts +5 -0
  158. package/dist/document/Head.js +40 -0
  159. package/dist/document/Link.d.ts +7 -0
  160. package/dist/document/Link.js +28 -0
  161. package/dist/document/Script.d.ts +3 -0
  162. package/dist/document/Script.js +5 -0
  163. package/dist/document/context.d.ts +17 -0
  164. package/dist/document/context.js +13 -0
  165. package/dist/document/index.d.ts +8 -0
  166. package/dist/document/index.js +7 -0
  167. package/dist/document/useDocument.d.ts +2 -0
  168. package/dist/document/useDocument.js +10 -0
  169. package/dist/hooks/useCookies.d.ts +2 -0
  170. package/dist/hooks/useCookies.js +11 -0
  171. package/dist/hooks/useData.d.ts +18 -0
  172. package/dist/hooks/useData.js +69 -0
  173. package/dist/hooks/useDocument.d.ts +2 -0
  174. package/dist/hooks/useDocument.js +10 -0
  175. package/dist/hooks/useHeaders.d.ts +2 -0
  176. package/dist/hooks/useHeaders.js +9 -0
  177. package/dist/hooks/useLocation.d.ts +2 -0
  178. package/dist/hooks/useLocation.js +25 -0
  179. package/dist/hooks/usePage.d.ts +5 -0
  180. package/dist/hooks/usePage.js +9 -0
  181. package/dist/hooks/useParams.d.ts +2 -0
  182. package/dist/hooks/useParams.js +6 -0
  183. package/dist/hooks/usePathname.d.ts +2 -0
  184. package/dist/hooks/usePathname.js +9 -0
  185. package/dist/hooks/useRequest.d.ts +2 -0
  186. package/dist/hooks/useRequest.js +8 -0
  187. package/dist/hooks/useSearchParams.d.ts +12 -0
  188. package/dist/hooks/useSearchParams.js +66 -0
  189. package/dist/index.d.ts +23 -0
  190. package/dist/index.js +27 -0
  191. package/dist/loader.d.ts +11 -0
  192. package/dist/loader.js +16 -0
  193. package/dist/navigate.d.ts +7 -0
  194. package/dist/navigate.js +31 -0
  195. package/dist/navigation/index.d.ts +2 -0
  196. package/dist/navigation/index.js +2 -0
  197. package/dist/navigation/navigate.d.ts +7 -0
  198. package/dist/navigation/navigate.js +31 -0
  199. package/dist/navigation/useLocation.d.ts +1 -0
  200. package/dist/navigation/useLocation.js +22 -0
  201. package/dist/router/index.d.ts +1 -0
  202. package/dist/router/index.js +1 -0
  203. package/dist/router/useParams.d.ts +9 -0
  204. package/dist/router/useParams.js +50 -0
  205. package/dist/router/useSearchParams .d.ts +9 -0
  206. package/dist/router/useSearchParams .js +50 -0
  207. package/dist/router/useSearchParams.d.ts +11 -0
  208. package/dist/router/useSearchParams.js +80 -0
  209. package/dist/server/index.d.ts +0 -0
  210. package/dist/server/index.js +1 -0
  211. package/dist/server/page.d.ts +9 -0
  212. package/dist/server/page.js +60 -0
  213. package/dist/server/readManifest.d.ts +14 -0
  214. package/dist/server/readManifest.js +8 -0
  215. package/dist/server/runtime/createServer.d.ts +12 -0
  216. package/dist/server/runtime/createServer.js +48 -0
  217. package/dist/server/runtime/index.d.ts +3 -0
  218. package/dist/server/runtime/index.js +3 -0
  219. package/dist/server/runtime/readManifest.d.ts +14 -0
  220. package/dist/server/runtime/readManifest.js +8 -0
  221. package/dist/server/runtime/xanixPage.d.ts +9 -0
  222. package/dist/server/runtime/xanixPage.js +87 -0
  223. package/dist/types.d.ts +12 -0
  224. package/dist/types.js +7 -0
  225. package/dist/utils/index.d.ts +9 -0
  226. package/dist/utils/index.js +27 -0
  227. package/dist/xanix.d.ts +3 -0
  228. package/dist/xanix.js +40 -0
  229. package/package.json +73 -13
  230. package/src/xanix-env.d.ts +79 -0
@@ -0,0 +1,7 @@
1
+ import { Plugin } from "rollup";
2
+ import { XanixClientEntry } from "../../types";
3
+ export type XanixWatchChangeClientOptions = {
4
+ onChange?: (entry: string, event: "update" | "delete" | "create" | undefined) => void;
5
+ };
6
+ declare const XanixWatchChangeClient: (entries: XanixClientEntry[], options: XanixWatchChangeClientOptions) => Plugin;
7
+ export default XanixWatchChangeClient;
@@ -0,0 +1,15 @@
1
+ import path from "path";
2
+ import { readManifest } from "../../include/manifest.js";
3
+ const XanixWatchChangeClient = (entries, options) => {
4
+ return {
5
+ name: "xanix-watch-client",
6
+ async watchChange(id, change) {
7
+ const entry = path.resolve(id).replaceAll("\\", "/");
8
+ const manifest = await readManifest();
9
+ if (!manifest)
10
+ return;
11
+ options.onChange?.(entry, change?.event);
12
+ },
13
+ };
14
+ };
15
+ export default XanixWatchChangeClient;
@@ -0,0 +1,3 @@
1
+ import { RollupCommonJSOptions } from "@rollup/plugin-commonjs";
2
+ declare const rollupCommonjs: (opt?: RollupCommonJSOptions) => import("rollup").Plugin<any>;
3
+ export default rollupCommonjs;
@@ -0,0 +1,10 @@
1
+ import commonjs from "@rollup/plugin-commonjs";
2
+ const rollupCommonjs = (opt) => {
3
+ return commonjs({
4
+ include: /node_modules/,
5
+ extensions: [".js", ".cjs"],
6
+ transformMixedEsModules: true,
7
+ ...opt,
8
+ });
9
+ };
10
+ export default rollupCommonjs;
@@ -0,0 +1,9 @@
1
+ import { Plugin } from "rollup";
2
+ import { XanixClientEntry } from "../../types";
3
+ export type XanixWatchChangeOptions = {
4
+ onClientEntryChange?: (entry: string, entries: XanixClientEntry[]) => Promise<void>;
5
+ onServerChange?: (entry: string, entries: XanixClientEntry[]) => Promise<void>;
6
+ onChange?: (entry: string, event: "update" | "delete" | "create" | undefined) => void;
7
+ };
8
+ declare const XanixWatchChange: (entries: XanixClientEntry[], options: XanixWatchChangeOptions) => Plugin;
9
+ export default XanixWatchChange;
@@ -0,0 +1,27 @@
1
+ import path from "path";
2
+ import { createManifest, readManifest } from "../../include/manifest.js";
3
+ import generateClientEntries from "../generateClientEntries.js";
4
+ import { entriesEqual } from "../../include/entry.js";
5
+ const XanixWatchChange = (entries, options) => {
6
+ return {
7
+ name: "xanix-watch-server",
8
+ async watchChange(id, change) {
9
+ const entry = path.resolve(id).replaceAll("\\", "/");
10
+ const manifest = await readManifest();
11
+ if (!manifest)
12
+ return;
13
+ const isClientEntry = Array.from(manifest.entries.values()).find((e) => e.file === entry);
14
+ if (!isClientEntry) {
15
+ const entries = await generateClientEntries();
16
+ const isEqual = await entriesEqual(entries);
17
+ if (!isEqual) {
18
+ await createManifest(entries);
19
+ await options.onClientEntryChange?.(entry, entries);
20
+ }
21
+ await options.onServerChange?.(entry, entries);
22
+ }
23
+ options.onChange?.(entry, change?.event);
24
+ },
25
+ };
26
+ };
27
+ export default XanixWatchChange;
@@ -0,0 +1,3 @@
1
+ import { RollupNodeResolveOptions } from "@rollup/plugin-node-resolve";
2
+ declare const rollupNodeResolve: (browser?: boolean, options?: RollupNodeResolveOptions) => import("rollup").Plugin<any>;
3
+ export default rollupNodeResolve;
@@ -0,0 +1,10 @@
1
+ import nodeResolve from "@rollup/plugin-node-resolve";
2
+ const rollupNodeResolve = (browser = true, options) => {
3
+ return nodeResolve({
4
+ extensions: [".mjs", ".js", ".json", ".node", ".ts", ".tsx", ".jsx"],
5
+ browser: browser,
6
+ preferBuiltins: !browser,
7
+ ...options,
8
+ });
9
+ };
10
+ export default rollupNodeResolve;
@@ -0,0 +1,5 @@
1
+ import type { Plugin } from "rollup";
2
+ /**
3
+ * Create Rollup aliases from tsconfig.json paths.
4
+ */
5
+ export declare function xanixTsconfigAlias(): Plugin;
@@ -0,0 +1,57 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import alias from "@rollup/plugin-alias";
4
+ /**
5
+ * Create Rollup aliases from tsconfig.json paths.
6
+ */
7
+ export function xanixTsconfigAlias() {
8
+ const root = process.cwd();
9
+ const tsconfigPath = path.resolve(root, "tsconfig.json");
10
+ if (!fs.existsSync(tsconfigPath)) {
11
+ return {
12
+ name: "xanix-tsconfig-alias",
13
+ };
14
+ }
15
+ let tsconfig;
16
+ try {
17
+ const content = fs.readFileSync(tsconfigPath, "utf8");
18
+ tsconfig = JSON.parse(content);
19
+ }
20
+ catch (error) {
21
+ throw new Error(`[xanix] Failed to read tsconfig.json: ${tsconfigPath}\n${String(error)}`);
22
+ }
23
+ const compilerOptions = tsconfig.compilerOptions ?? {};
24
+ const baseUrl = compilerOptions.baseUrl ?? ".";
25
+ const basePath = path.resolve(path.dirname(tsconfigPath), baseUrl);
26
+ const paths = compilerOptions.paths ?? {};
27
+ const entries = Object.entries(paths)
28
+ .map(([find, replacements]) => {
29
+ const replacement = replacements[0];
30
+ if (!replacement) {
31
+ return null;
32
+ }
33
+ const hasWildcard = find.includes("*");
34
+ if (hasWildcard) {
35
+ const findPrefix = find.replace(/\/?\*$/, "");
36
+ const replacementPrefix = replacement.replace(/\/?\*$/, "");
37
+ return {
38
+ find: new RegExp(`^${escapeRegExp(findPrefix)}\\/(.+)$`),
39
+ replacement: `${path.resolve(basePath, replacementPrefix)}/$1`,
40
+ };
41
+ }
42
+ return {
43
+ find,
44
+ replacement: path.resolve(basePath, replacement),
45
+ };
46
+ })
47
+ .filter((entry) => entry !== null);
48
+ return alias({
49
+ entries,
50
+ });
51
+ }
52
+ /**
53
+ * Escape a string for use inside RegExp.
54
+ */
55
+ function escapeRegExp(value) {
56
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
57
+ }
@@ -0,0 +1,8 @@
1
+ import type { Plugin } from "rollup";
2
+ export interface XanixRollupOptions {
3
+ target?: "client" | "server";
4
+ development?: boolean;
5
+ assetExternal?: boolean;
6
+ onChange?: (entry: string, event?: string) => void;
7
+ }
8
+ export declare function xanixDefaultPlugins(options?: XanixRollupOptions): Plugin[];
@@ -0,0 +1,75 @@
1
+ import XanixTsconfigAlias from "./XanixTsconfigAlias.js";
2
+ import { nodeResolve } from "@rollup/plugin-node-resolve";
3
+ import commonjs from "@rollup/plugin-commonjs";
4
+ import json from "@rollup/plugin-json";
5
+ import esbuild from "rollup-plugin-esbuild";
6
+ import url from "@rollup/plugin-url";
7
+ import path from "path";
8
+ import { XanixTransform } from "./XanixTransform/index.js";
9
+ import xanixReactRefresh from "./XanixReactRefresh.js";
10
+ import XanixEnvPlugin from "./XanixEnv.js";
11
+ import xanixUseDataId from "./xanixUseDataId.js";
12
+ export function xanixDefaultPlugins(options = {}) {
13
+ const target = options.target ?? "client";
14
+ const development = options.development ?? true;
15
+ const isClient = target === "client";
16
+ const isServer = target === "server";
17
+ let _plugins = [];
18
+ if (isServer) {
19
+ _plugins.push(XanixTransform({ mode: development ? "watch" : "start" }));
20
+ // _plugins.push(xanixServerData());
21
+ }
22
+ else {
23
+ if (development) {
24
+ _plugins.push(xanixReactRefresh());
25
+ }
26
+ }
27
+ return [
28
+ {
29
+ name: "watch",
30
+ async watchChange(id, change) {
31
+ const entry = path.resolve(id).replaceAll("\\", "/");
32
+ options.onChange?.(entry, change?.event);
33
+ },
34
+ },
35
+ url({
36
+ include: [
37
+ "**/*.jpg",
38
+ "**/*.jpeg",
39
+ "**/*.png",
40
+ "**/*.gif",
41
+ "**/*.webp",
42
+ "**/*.svg",
43
+ "**/*.ico",
44
+ "**/*.woff",
45
+ "**/*.woff2",
46
+ "**/*.ttf",
47
+ "**/*.eot",
48
+ "**/*.css",
49
+ ],
50
+ limit: 0,
51
+ fileName: "assets/[name]-[hash][extname]",
52
+ emitFiles: !(options?.assetExternal ?? false),
53
+ }),
54
+ XanixTsconfigAlias(),
55
+ XanixEnvPlugin({
56
+ mode: development ? "development" : "production",
57
+ isClient,
58
+ }),
59
+ nodeResolve({
60
+ browser: isClient,
61
+ preferBuiltins: isServer,
62
+ extensions: [".mjs", ".js", ".jsx", ".json", ".ts", ".tsx"],
63
+ }),
64
+ commonjs(),
65
+ json(),
66
+ xanixUseDataId(),
67
+ ..._plugins,
68
+ esbuild({
69
+ target: isClient ? "es2022" : "node20",
70
+ jsx: "automatic",
71
+ tsconfig: false,
72
+ minify: !development,
73
+ }),
74
+ ];
75
+ }
@@ -0,0 +1,3 @@
1
+ import { Options } from "rollup-plugin-esbuild";
2
+ declare const rollupEsbuild: (options?: Options) => import("rollup").Plugin<any>;
3
+ export default rollupEsbuild;
@@ -0,0 +1,14 @@
1
+ import esbuild from "rollup-plugin-esbuild";
2
+ const rollupEsbuild = (options) => {
3
+ return esbuild({
4
+ target: "es2022",
5
+ platform: "browser",
6
+ format: "esm",
7
+ jsx: "automatic",
8
+ sourceMap: false,
9
+ minify: false,
10
+ include: /\.(mjs|js|cjs|ts|tsx|jsx)$/,
11
+ ...options,
12
+ });
13
+ };
14
+ export default rollupEsbuild;
@@ -0,0 +1,6 @@
1
+ import type { Plugin } from "rollup";
2
+ interface XanixServerDataOptions {
3
+ root?: string;
4
+ }
5
+ export default function xanixServerData(options?: XanixServerDataOptions): Plugin;
6
+ export {};
@@ -0,0 +1,224 @@
1
+ import path from "node:path";
2
+ import crypto from "node:crypto";
3
+ import { parse } from "@babel/parser";
4
+ import traverse from "@babel/traverse";
5
+ import generate from "@babel/generator";
6
+ import * as t from "@babel/types";
7
+ function createLoaderId(filename, start) {
8
+ const relative = path.relative(process.cwd(), filename).replace(/\\/g, "/");
9
+ const value = `${relative}:${start}`;
10
+ return crypto.createHash("sha256").update(value).digest("hex").slice(0, 16);
11
+ }
12
+ function getArgumentNames(node) {
13
+ const names = [];
14
+ for (const property of node.properties) {
15
+ if (!t.isObjectProperty(property)) {
16
+ continue;
17
+ }
18
+ if (t.isIdentifier(property.key)) {
19
+ names.push(property.key.name);
20
+ }
21
+ }
22
+ return names;
23
+ }
24
+ export default function xanixServerData(options = {}) {
25
+ const root = options.root ?? process.cwd();
26
+ return {
27
+ name: "xanix-server-data",
28
+ transform(code, id) {
29
+ if (id.includes("node_modules") || !/\.(js|jsx|ts|tsx)$/.test(id)) {
30
+ return null;
31
+ }
32
+ const ast = parse(code, {
33
+ sourceType: "module",
34
+ plugins: ["typescript", "jsx"],
35
+ });
36
+ let hasUseData = false;
37
+ let changed = false;
38
+ const loaderStatements = [];
39
+ // --------------------------------------------------
40
+ // Find useData
41
+ // --------------------------------------------------
42
+ traverse(ast, {
43
+ ImportDeclaration(importPath) {
44
+ if (importPath.node.source.value !== "xanix") {
45
+ return;
46
+ }
47
+ for (const specifier of importPath.node.specifiers) {
48
+ if (t.isImportSpecifier(specifier) &&
49
+ t.isIdentifier(specifier.imported) &&
50
+ specifier.imported.name === "useData") {
51
+ hasUseData = true;
52
+ }
53
+ }
54
+ },
55
+ });
56
+ if (!hasUseData) {
57
+ return null;
58
+ }
59
+ // --------------------------------------------------
60
+ // Transform useData()
61
+ // --------------------------------------------------
62
+ traverse(ast, {
63
+ CallExpression(callPath) {
64
+ const node = callPath.node;
65
+ if (!t.isIdentifier(node.callee) || node.callee.name !== "useData") {
66
+ return;
67
+ }
68
+ const callback = node.arguments[0];
69
+ const args = node.arguments[1];
70
+ if (!callback ||
71
+ !(t.isArrowFunctionExpression(callback) ||
72
+ t.isFunctionExpression(callback))) {
73
+ return;
74
+ }
75
+ if (!args || !t.isObjectExpression(args)) {
76
+ return;
77
+ }
78
+ const loaderId = createLoaderId(id, node.start ?? 0);
79
+ const argumentNames = getArgumentNames(args);
80
+ // ----------------------------------------------
81
+ // Clone callback body
82
+ // ----------------------------------------------
83
+ const callbackBody = t.cloneNode(callback.body, true);
84
+ // ----------------------------------------------
85
+ // Create:
86
+ //
87
+ // async ({ category }) => {
88
+ // ...
89
+ // }
90
+ // ----------------------------------------------
91
+ const parameterProperties = argumentNames.map((name) => t.objectProperty(t.identifier(name), t.identifier(name), false, true));
92
+ const loaderParameter = t.objectPattern(parameterProperties);
93
+ let loaderFunction;
94
+ if (t.isBlockStatement(callbackBody)) {
95
+ loaderFunction = t.arrowFunctionExpression([loaderParameter], callbackBody, callback.async);
96
+ }
97
+ else {
98
+ loaderFunction = t.arrowFunctionExpression([loaderParameter], callbackBody, callback.async);
99
+ }
100
+ // ----------------------------------------------
101
+ // registerLoader(...)
102
+ // ----------------------------------------------
103
+ const registerLoader = t.expressionStatement(t.callExpression(t.identifier("registerLoader"), [
104
+ t.stringLiteral(loaderId),
105
+ loaderFunction,
106
+ ]));
107
+ loaderStatements.push(registerLoader);
108
+ // ----------------------------------------------
109
+ // Replace:
110
+ //
111
+ // useData(callback, args)
112
+ //
113
+ // with:
114
+ //
115
+ // useLoader(
116
+ // page.pageId,
117
+ // "id",
118
+ // args
119
+ // )
120
+ // ----------------------------------------------
121
+ const useLoader = t.callExpression(t.identifier("useLoader"), [
122
+ t.memberExpression(t.identifier("page"), t.identifier("pageId")),
123
+ t.stringLiteral(loaderId),
124
+ t.cloneNode(args, true),
125
+ ]);
126
+ callPath.replaceWith(useLoader);
127
+ changed = true;
128
+ },
129
+ });
130
+ if (!changed) {
131
+ return null;
132
+ }
133
+ // --------------------------------------------------
134
+ // Remove useData from import
135
+ // --------------------------------------------------
136
+ traverse(ast, {
137
+ ImportDeclaration(importPath) {
138
+ if (importPath.node.source.value !== "xanix") {
139
+ return;
140
+ }
141
+ importPath.node.specifiers = importPath.node.specifiers.filter((specifier) => {
142
+ return !(t.isImportSpecifier(specifier) &&
143
+ t.isIdentifier(specifier.imported) &&
144
+ specifier.imported.name === "useData");
145
+ });
146
+ if (importPath.node.specifiers.length === 0) {
147
+ importPath.remove();
148
+ }
149
+ },
150
+ });
151
+ // --------------------------------------------------
152
+ // Add imports
153
+ // --------------------------------------------------
154
+ const program = ast.program;
155
+ let importEnd = 0;
156
+ while (importEnd < program.body.length &&
157
+ t.isImportDeclaration(program.body[importEnd])) {
158
+ importEnd++;
159
+ }
160
+ const usePageImport = t.importDeclaration([t.importSpecifier(t.identifier("usePage"), t.identifier("usePage"))], t.stringLiteral("xanix"));
161
+ const loaderImport = t.importDeclaration([
162
+ t.importSpecifier(t.identifier("useLoader"), t.identifier("useLoader")),
163
+ t.importSpecifier(t.identifier("registerLoader"), t.identifier("registerLoader")),
164
+ ], t.stringLiteral("xanix/runtime/loader"));
165
+ program.body.splice(importEnd, 0, usePageImport, loaderImport);
166
+ // --------------------------------------------------
167
+ // Insert registerLoader calls
168
+ // after imports
169
+ // --------------------------------------------------
170
+ program.body.splice(importEnd + 2, 0, ...loaderStatements);
171
+ // --------------------------------------------------
172
+ // Add:
173
+ //
174
+ // const page = usePage();
175
+ //
176
+ // to function containing useLoader()
177
+ // --------------------------------------------------
178
+ traverse(ast, {
179
+ Function(functionPath) {
180
+ let hasUseLoader = false;
181
+ functionPath.traverse({
182
+ CallExpression(innerPath) {
183
+ if (t.isIdentifier(innerPath.node.callee, {
184
+ name: "useLoader",
185
+ })) {
186
+ hasUseLoader = true;
187
+ innerPath.stop();
188
+ }
189
+ },
190
+ });
191
+ if (!hasUseLoader) {
192
+ return;
193
+ }
194
+ if (!t.isBlockStatement(functionPath.node.body)) {
195
+ return;
196
+ }
197
+ const alreadyHasPage = functionPath.node.body.body.some((statement) => {
198
+ if (!t.isVariableDeclaration(statement)) {
199
+ return false;
200
+ }
201
+ return statement.declarations.some((declaration) => t.isIdentifier(declaration.id, {
202
+ name: "page",
203
+ }));
204
+ });
205
+ if (alreadyHasPage) {
206
+ return;
207
+ }
208
+ const declaration = t.variableDeclaration("const", [
209
+ t.variableDeclarator(t.identifier("page"), t.callExpression(t.identifier("usePage"), [])),
210
+ ]);
211
+ functionPath.node.body.body.unshift(declaration);
212
+ },
213
+ });
214
+ const output = generate(ast, {
215
+ sourceMaps: true,
216
+ sourceFileName: id,
217
+ }, code);
218
+ return {
219
+ code: output.code,
220
+ map: output.map,
221
+ };
222
+ },
223
+ };
224
+ }
@@ -0,0 +1,6 @@
1
+ import type { Plugin } from "rollup";
2
+ export interface XanixTsconfigAliasOptions {
3
+ tsconfigPath?: string;
4
+ root?: string;
5
+ }
6
+ export default function xanixTsconfigAlias(options?: XanixTsconfigAliasOptions): Plugin;
@@ -0,0 +1,51 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import ts from "typescript";
4
+ import alias from "@rollup/plugin-alias";
5
+ export default function xanixTsconfigAlias(options = {}) {
6
+ const root = options.root ?? process.cwd();
7
+ const tsconfigPath = options.tsconfigPath
8
+ ? path.resolve(root, options.tsconfigPath)
9
+ : path.resolve(root, "tsconfig.json");
10
+ if (!fs.existsSync(tsconfigPath)) {
11
+ return {
12
+ name: "xanix-tsconfig-alias",
13
+ };
14
+ }
15
+ const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
16
+ if (configFile.error) {
17
+ const message = ts.flattenDiagnosticMessageText(configFile.error.messageText, "\n");
18
+ throw new Error(`[xanix] Failed to read tsconfig.json:\n${message}`);
19
+ }
20
+ const config = configFile.config;
21
+ const compilerOptions = config.compilerOptions ?? {};
22
+ const baseUrl = compilerOptions.baseUrl ?? ".";
23
+ const basePath = path.resolve(path.dirname(tsconfigPath), baseUrl);
24
+ const paths = compilerOptions.paths ?? {};
25
+ const entries = Object.entries(paths)
26
+ .map(([find, replacements]) => {
27
+ const replacement = replacements[0];
28
+ if (!replacement) {
29
+ return null;
30
+ }
31
+ if (find.includes("*")) {
32
+ const findPrefix = find.replace(/\/?\*$/, "");
33
+ const replacementPrefix = replacement.replace(/\/?\*$/, "");
34
+ return {
35
+ find: new RegExp(`^${escapeRegExp(findPrefix)}/(.+)$`),
36
+ replacement: `${path.resolve(basePath, replacementPrefix)}/$1`,
37
+ };
38
+ }
39
+ return {
40
+ find,
41
+ replacement: path.resolve(basePath, replacement),
42
+ };
43
+ })
44
+ .filter((entry) => entry !== null);
45
+ return alias({
46
+ entries,
47
+ });
48
+ }
49
+ function escapeRegExp(value) {
50
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
51
+ }
@@ -0,0 +1,4 @@
1
+ export default function xanixUseDataTransform(): {
2
+ name: string;
3
+ transform(code: string, id: string): any;
4
+ };
@@ -0,0 +1,93 @@
1
+ import { createHash } from "node:crypto";
2
+ import { parse } from "@babel/parser";
3
+ import traverse from "@babel/traverse";
4
+ import generate from "@babel/generator";
5
+ import nodePath from "node:path";
6
+ import * as t from "@babel/types";
7
+ export default function xanixUseDataTransform() {
8
+ return {
9
+ name: "xanix-use-data-transform",
10
+ transform(code, id) {
11
+ if (!/\.[cm]?[jt]sx?$/.test(id)) {
12
+ return null;
13
+ }
14
+ if (!code.includes("useData")) {
15
+ return null;
16
+ }
17
+ const ast = parse(code, {
18
+ sourceType: "module",
19
+ plugins: ["typescript", "jsx"],
20
+ });
21
+ let changed = false;
22
+ let counter = 0;
23
+ const registrations = [];
24
+ traverse(ast, {
25
+ CallExpression(path) {
26
+ const { node } = path;
27
+ // Match useData(...)
28
+ if (!t.isIdentifier(node.callee, { name: "useData" })) {
29
+ return;
30
+ }
31
+ const callback = node.arguments[0];
32
+ if (!callback) {
33
+ return;
34
+ }
35
+ // First argument must be function
36
+ if (!t.isFunctionExpression(callback) &&
37
+ !t.isArrowFunctionExpression(callback)) {
38
+ return;
39
+ }
40
+ const args = node.arguments[1] ?? t.objectExpression([]);
41
+ // Stable ID based on file + position
42
+ const relative = nodePath
43
+ .relative(process.cwd(), id)
44
+ .replace(/\\/g, "/");
45
+ const start = node.start ?? 0;
46
+ const hash = createHash("sha256")
47
+ .update(`${relative}:${start}`)
48
+ .digest("hex");
49
+ const xanixId = hash.slice(0, 12);
50
+ // Generated hook name
51
+ const hookName = `useXanixData${counter++}`;
52
+ // Create:
53
+ //
54
+ // const useXanixData0 = useData.register(
55
+ // "id",
56
+ // callback
57
+ // );
58
+ const registration = t.variableDeclaration("const", [
59
+ t.variableDeclarator(t.identifier(hookName), t.callExpression(t.memberExpression(t.identifier("useData"), t.identifier("register")), [t.stringLiteral(xanixId), callback])),
60
+ ]);
61
+ registrations.push(registration);
62
+ // Replace:
63
+ //
64
+ // useData(callback, args)
65
+ //
66
+ // with:
67
+ //
68
+ // useXanixData0(args)
69
+ path.replaceWith(t.callExpression(t.identifier(hookName), [args]));
70
+ changed = true;
71
+ },
72
+ });
73
+ if (!changed) {
74
+ return null;
75
+ }
76
+ // Add registrations after imports
77
+ const body = ast.program.body;
78
+ let insertIndex = 0;
79
+ while (insertIndex < body.length &&
80
+ t.isImportDeclaration(body[insertIndex])) {
81
+ insertIndex++;
82
+ }
83
+ body.splice(insertIndex, 0, ...registrations);
84
+ const output = generate(ast, {
85
+ retainLines: true,
86
+ }, code);
87
+ return {
88
+ code: output.code,
89
+ map: null,
90
+ };
91
+ },
92
+ };
93
+ }
@@ -0,0 +1,8 @@
1
+ import { type RollupWatcher } from "rollup";
2
+ import { XanixClientEntry } from "../types.js";
3
+ type Option = {
4
+ onChange?: (entry: string, event?: string) => void;
5
+ onBuildEnd?: () => void;
6
+ };
7
+ declare const WatchClient: (entries: XanixClientEntry[], options: Option) => Promise<RollupWatcher>;
8
+ export default WatchClient;