rari 0.1.3

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.
@@ -0,0 +1,218 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import process from "node:process";
4
+ import colors from "picocolors";
5
+
6
+ //#region src/deployment/render.ts
7
+ function logInfo(message) {
8
+ console.warn(`${colors.blue("info")} ${message}`);
9
+ }
10
+ function logSuccess(message) {
11
+ console.warn(`${colors.green("✓")} ${message}`);
12
+ }
13
+ function logError(message) {
14
+ console.error(`${colors.red("✗")} ${message}`);
15
+ }
16
+ function logWarning(message) {
17
+ console.warn(`${colors.yellow("⚠")} ${message}`);
18
+ }
19
+ async function createRenderDeployment() {
20
+ const cwd = process.cwd();
21
+ logInfo("Creating Render deployment configuration...");
22
+ const packageJsonPath = join(cwd, "package.json");
23
+ if (!existsSync(packageJsonPath)) {
24
+ logError("No package.json found. Please run this command from your project root.");
25
+ process.exit(1);
26
+ }
27
+ try {
28
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
29
+ packageJson.scripts = packageJson.scripts || {};
30
+ if (packageJson.scripts.start && packageJson.scripts.start !== "rari start") {
31
+ logWarning(`Existing start script found: "${packageJson.scripts.start}"`);
32
+ logWarning("Backing up to start:original and replacing with \"rari start\"");
33
+ packageJson.scripts["start:original"] = packageJson.scripts.start;
34
+ }
35
+ packageJson.scripts.start = "rari start";
36
+ packageJson.scripts["start:local"] = "rari start";
37
+ packageJson.scripts["deploy:render"] = "echo \"Push to GitHub and connect to Render to deploy\"";
38
+ packageJson.engines = packageJson.engines || {};
39
+ if (!packageJson.engines.node) packageJson.engines.node = ">=20.0.0";
40
+ if (!packageJson.dependencies || !packageJson.dependencies.rari) {
41
+ logInfo("Adding rari dependency...");
42
+ packageJson.dependencies = packageJson.dependencies || {};
43
+ packageJson.dependencies.rari = "^0.1.0";
44
+ }
45
+ writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
46
+ logSuccess("Updated package.json for Render deployment");
47
+ } catch (error) {
48
+ logError(`Failed to update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
49
+ process.exit(1);
50
+ }
51
+ const renderConfig = `services:
52
+ - type: web
53
+ name: rari-app
54
+ runtime: node
55
+ env: node
56
+ plan: free
57
+ buildCommand: npm install
58
+ startCommand: npm start
59
+ healthCheckPath: /
60
+ envVars:
61
+ - key: NODE_ENV
62
+ value: production
63
+ - key: RUST_LOG
64
+ value: info
65
+ `;
66
+ const renderYamlPath = join(cwd, "render.yaml");
67
+ if (existsSync(renderYamlPath)) {
68
+ logWarning("render.yaml already exists, backing up to render.yaml.backup");
69
+ const existingConfig = readFileSync(renderYamlPath, "utf-8");
70
+ writeFileSync(join(cwd, "render.yaml.backup"), existingConfig);
71
+ }
72
+ writeFileSync(renderYamlPath, renderConfig);
73
+ logSuccess("Created render.yaml configuration");
74
+ const gitignorePath = join(cwd, ".gitignore");
75
+ const renderGitignoreEntries = [
76
+ "",
77
+ "# Render",
78
+ ".render/",
79
+ ""
80
+ ].join("\n");
81
+ if (existsSync(gitignorePath)) {
82
+ const gitignoreContent = readFileSync(gitignorePath, "utf-8");
83
+ if (!gitignoreContent.includes(".render/")) {
84
+ writeFileSync(gitignorePath, gitignoreContent + renderGitignoreEntries);
85
+ logSuccess("Updated .gitignore with Render entries");
86
+ }
87
+ } else {
88
+ const defaultGitignore = `# Dependencies
89
+ node_modules/
90
+ .pnpm-store/
91
+
92
+ # Build outputs
93
+ .rari/
94
+ dist/
95
+
96
+ # Environment variables
97
+ .env
98
+ .env.local
99
+ .env.production
100
+
101
+ # Render
102
+ .render/
103
+
104
+ # Logs
105
+ *.log
106
+ npm-debug.log*
107
+ pnpm-debug.log*
108
+
109
+ # OS files
110
+ .DS_Store
111
+ Thumbs.db
112
+
113
+ # IDE files
114
+ .vscode/
115
+ .idea/
116
+ *.swp
117
+ *.swo
118
+ *~
119
+
120
+ # Temporary files
121
+ .tmp/
122
+ tmp/
123
+ `;
124
+ writeFileSync(gitignorePath, defaultGitignore);
125
+ logSuccess("Created .gitignore with Render entries");
126
+ }
127
+ const readmePath = join(cwd, "README.md");
128
+ const renderReadmeSection = `
129
+ ## 🎨 Deploy to Render
130
+
131
+ This Rari application is configured for Render deployment.
132
+
133
+ ### Quick Deploy
134
+
135
+ 1. **Push to GitHub**:
136
+ \`\`\`bash
137
+ git add .
138
+ git commit -m "Add Render deployment"
139
+ git push origin main
140
+ \`\`\`
141
+
142
+ 2. **Deploy to Render**:
143
+ - Go to [render.com](https://render.com)
144
+ - Create new "Web Service"
145
+ - Connect your GitHub repository
146
+ - Render will auto-detect Node.js and use the configuration from \`render.yaml\`
147
+ - Click "Create Web Service"
148
+
149
+ 3. **Your app will be live!** 🎉
150
+ - Render provides a \`.onrender.com\` URL
151
+ - Optional: Add custom domain in Render dashboard
152
+
153
+ ### Local Development
154
+
155
+ \`\`\`bash
156
+ # Development server
157
+ npm run start:local
158
+
159
+ # Production simulation
160
+ npm start
161
+ \`\`\`
162
+
163
+ ### Environment Variables
164
+
165
+ Render automatically provides:
166
+ - \`PORT\` - Server port (Render assigns this)
167
+ - \`NODE_ENV=production\` - Production mode (from render.yaml)
168
+ - \`RUST_LOG=info\` - Rust logging level (from render.yaml)
169
+
170
+ Optional variables you can add in Render dashboard:
171
+ - \`RUST_LOG=debug\` - Enhanced logging
172
+
173
+ ---
174
+ `;
175
+ if (existsSync(readmePath)) {
176
+ const readmeContent = readFileSync(readmePath, "utf-8");
177
+ if (!readmeContent.includes("Deploy to Render")) {
178
+ writeFileSync(readmePath, readmeContent + renderReadmeSection);
179
+ logSuccess("Updated README.md with Render deployment instructions");
180
+ }
181
+ } else {
182
+ const defaultReadme = `# My Rari App
183
+
184
+ A high-performance React Server Components application powered by Rari.
185
+ ${renderReadmeSection}
186
+ ## Getting Started
187
+
188
+ \`\`\`bash
189
+ npm install
190
+ npm start
191
+ \`\`\`
192
+
193
+ Visit [http://localhost:3000](http://localhost:3000) to see your app.
194
+ `;
195
+ writeFileSync(readmePath, defaultReadme);
196
+ logSuccess("Created README.md with Render deployment instructions");
197
+ }
198
+ console.warn("");
199
+ logSuccess("Render deployment setup complete! 🎉");
200
+ console.warn("");
201
+ logInfo("Next steps:");
202
+ console.warn(` 1. ${colors.cyan("git add .")}`);
203
+ console.warn(` 2. ${colors.cyan("git commit -m \"Add Render deployment\"")}`);
204
+ console.warn(` 3. ${colors.cyan("git push origin main")}`);
205
+ console.warn(` 4. Go to ${colors.cyan("https://render.com")} and create a Web Service`);
206
+ console.warn("");
207
+ logInfo("Your Rari app will automatically:");
208
+ console.warn(" ✅ Detect Render environment");
209
+ console.warn(" ✅ Bind to 0.0.0.0 (Render requirement)");
210
+ console.warn(" ✅ Use Render's PORT environment variable");
211
+ console.warn(" ✅ Run in production mode");
212
+ console.warn(" ✅ Download platform-specific Rari binary");
213
+ console.warn("");
214
+ logSuccess("Ready for deployment! 🚀");
215
+ }
216
+
217
+ //#endregion
218
+ export { createRenderDeployment };
@@ -0,0 +1,283 @@
1
+ import React$1, { ComponentType, ReactNode } from "react";
2
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
3
+
4
+ //#region src/router/types.d.ts
5
+ interface Route {
6
+ path: string;
7
+ filePath: string;
8
+ component: ComponentType<any> | null;
9
+ isDynamic: boolean;
10
+ paramNames: string[];
11
+ children?: Route[];
12
+ parent?: Route;
13
+ isLayout?: boolean;
14
+ isIndex?: boolean;
15
+ meta?: RouteMeta;
16
+ }
17
+ interface RouteMeta {
18
+ title?: string;
19
+ description?: string;
20
+ requiresAuth?: boolean;
21
+ [key: string]: any;
22
+ }
23
+ interface RouteParams {
24
+ [key: string]: string | string[];
25
+ }
26
+ interface SearchParams {
27
+ [key: string]: string | string[];
28
+ }
29
+ interface RouteMatch {
30
+ route: Route;
31
+ params: RouteParams;
32
+ searchParams: SearchParams;
33
+ pathname: string;
34
+ search: string;
35
+ hash: string;
36
+ parentMatches?: RouteMatch[];
37
+ childMatch?: RouteMatch | null;
38
+ layouts?: Route[];
39
+ }
40
+ interface NavigationOptions {
41
+ replace?: boolean;
42
+ state?: any;
43
+ scroll?: boolean;
44
+ scrollPosition?: {
45
+ x: number;
46
+ y: number;
47
+ };
48
+ }
49
+ interface RouterConfig {
50
+ basePath?: string;
51
+ useHash?: boolean;
52
+ caseSensitive?: boolean;
53
+ notFoundComponent?: ComponentType<any>;
54
+ loadingComponent?: ComponentType<any>;
55
+ errorComponent?: ComponentType<{
56
+ error: Error;
57
+ retry: () => void;
58
+ }>;
59
+ }
60
+ interface PageProps {
61
+ params: RouteParams;
62
+ searchParams: SearchParams;
63
+ meta?: RouteMeta;
64
+ }
65
+ type PageComponent<P = Record<string, unknown>> = ComponentType<PageProps & P>;
66
+ interface RouterContext {
67
+ currentRoute: RouteMatch | null;
68
+ routes: Route[];
69
+ navigate: (path: string, options?: NavigationOptions) => void;
70
+ back: () => void;
71
+ forward: () => void;
72
+ replace: (path: string, options?: Omit<NavigationOptions, 'replace'>) => void;
73
+ isActive: (path: string, exact?: boolean) => boolean;
74
+ config: RouterConfig;
75
+ }
76
+ interface NavigationState {
77
+ isNavigating: boolean;
78
+ destination?: string;
79
+ error?: Error;
80
+ }
81
+ interface RouteGenerationOptions {
82
+ pagesDir: string;
83
+ extensions: string[];
84
+ transforms?: RouteTransform[];
85
+ }
86
+ type RouteTransform = (route: Route) => Route;
87
+ interface LinkProps {
88
+ to: string;
89
+ options?: NavigationOptions;
90
+ children: ReactNode;
91
+ className?: string;
92
+ activeClassName?: string;
93
+ exact?: boolean;
94
+ onClick?: (event: React.MouseEvent<HTMLAnchorElement>) => void;
95
+ [key: string]: any;
96
+ }
97
+ interface RouterProviderProps {
98
+ config?: RouterConfig;
99
+ routes?: Route[];
100
+ children: ReactNode;
101
+ }
102
+ interface UseRouterReturn extends RouterContext {}
103
+ interface UseNavigationReturn extends NavigationState {
104
+ navigate: RouterContext['navigate'];
105
+ back: RouterContext['back'];
106
+ forward: RouterContext['forward'];
107
+ replace: RouterContext['replace'];
108
+ }
109
+ interface UseRouteReturn {
110
+ route: RouteMatch | null;
111
+ params: RouteParams;
112
+ searchParams: SearchParams;
113
+ isLoading: boolean;
114
+ error: Error | null;
115
+ }
116
+ interface FileRouteInfo {
117
+ filePath: string;
118
+ routePath: string;
119
+ isDynamic: boolean;
120
+ paramNames: string[];
121
+ isIndex: boolean;
122
+ isLayout: boolean;
123
+ isNotFound: boolean;
124
+ }
125
+ interface LayoutProps {
126
+ children: ReactNode;
127
+ route: RouteMatch;
128
+ }
129
+ interface ErrorBoundaryProps {
130
+ error: Error;
131
+ retry: () => void;
132
+ route: RouteMatch;
133
+ }
134
+ interface LoadingProps {
135
+ route: Route;
136
+ progress?: number;
137
+ }
138
+ //#endregion
139
+ //#region src/router/router.d.ts
140
+ declare const RouterContext$1: React$1.Context<RouterContext | null>;
141
+ declare function RouterProvider({
142
+ config,
143
+ routes,
144
+ children
145
+ }: RouterProviderProps): react_jsx_runtime0.JSX.Element;
146
+ declare function useRouter(): UseRouterReturn;
147
+ declare function useNavigation(): UseNavigationReturn;
148
+ declare function useRoute(): UseRouteReturn;
149
+ declare function useParams(): RouteParams;
150
+ declare function useSearchParams(): readonly [SearchParams, (params: Record<string, string | string[]> | ((prev: Record<string, string | string[]>) => Record<string, string | string[]>), options?: NavigationOptions) => void];
151
+ declare function usePathname(): string;
152
+ declare function withRouter<P extends object>(Component: ComponentType<P & {
153
+ router: RouterContext;
154
+ }>): {
155
+ (props: P): react_jsx_runtime0.JSX.Element;
156
+ displayName: string;
157
+ };
158
+ declare function RouteComponent({
159
+ path,
160
+ component: Component,
161
+ exact,
162
+ render,
163
+ children
164
+ }: {
165
+ path: string;
166
+ component?: ComponentType<any>;
167
+ exact?: boolean;
168
+ render?: (props: {
169
+ match: RouteMatch | null;
170
+ }) => ReactNode;
171
+ children?: ReactNode;
172
+ }): string | number | bigint | boolean | react_jsx_runtime0.JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | React$1.ReactPortal | React$1.ReactElement<unknown, string | React$1.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
173
+ declare function Routes({
174
+ children: _children
175
+ }: {
176
+ children: ReactNode;
177
+ }): react_jsx_runtime0.JSX.Element | null;
178
+ declare function Outlet(): react_jsx_runtime0.JSX.Element | null;
179
+ declare function Navigate({
180
+ to,
181
+ replace,
182
+ state
183
+ }: {
184
+ to: string;
185
+ replace?: boolean;
186
+ state?: any;
187
+ }): null;
188
+ declare function Link({
189
+ to,
190
+ children,
191
+ className,
192
+ activeClassName,
193
+ exact,
194
+ onClick,
195
+ ...props
196
+ }: {
197
+ to: string;
198
+ children: ReactNode;
199
+ className?: string;
200
+ activeClassName?: string;
201
+ exact?: boolean;
202
+ onClick?: (event: React$1.MouseEvent<HTMLAnchorElement>) => void;
203
+ [key: string]: any;
204
+ }): react_jsx_runtime0.JSX.Element;
205
+ //#endregion
206
+ //#region src/router/utils.d.ts
207
+ declare function extractParamNames(routePath: string): string[];
208
+ declare function isDynamicRoute(routePath: string): boolean;
209
+ declare function findMatchingRoute(pathname: string, routes: Route[]): RouteMatch | null;
210
+ declare function parseSearchParams(search: string): SearchParams;
211
+ declare function buildSearchString(params: SearchParams): string;
212
+ declare function parseUrl(url: string): {
213
+ pathname: string;
214
+ search: string;
215
+ hash: string;
216
+ searchParams: SearchParams;
217
+ };
218
+ declare function buildUrl(pathname: string, searchParams?: SearchParams, hash?: string): string;
219
+ declare function isPathActive(pathname: string, routePath: string, exact?: boolean): boolean;
220
+ declare function normalizePathname(pathname: string): string;
221
+ declare function joinPaths(...segments: string[]): string;
222
+ declare function getRoutePriority(route: Route): number;
223
+ //#endregion
224
+ //#region src/runtime-client.d.ts
225
+ interface RuntimeClient {
226
+ initialize: () => Promise<void>;
227
+ registerComponent: (componentId: string, componentCode: string) => Promise<void>;
228
+ renderToRscFormat: (componentId: string, props?: string) => Promise<string>;
229
+ renderToString: (componentId: string, props?: string) => Promise<string>;
230
+ renderToStreamCallbacks: (componentId: string, props?: string) => Promise<any>;
231
+ registerClientComponent: (componentId: string, filePath: string, exportName: string) => void;
232
+ registerClientReference: (referenceId: string, filePath: string, exportName: string) => void;
233
+ listComponents: () => string[];
234
+ shutdown: () => Promise<void>;
235
+ }
236
+ interface HealthResponse {
237
+ status: string;
238
+ timestamp: string;
239
+ }
240
+ interface StatusResponse {
241
+ status: string;
242
+ mode: string;
243
+ uptime_seconds: number;
244
+ request_count: number;
245
+ components_registered: number;
246
+ memory_usage?: number;
247
+ }
248
+ declare class HttpRuntimeClient implements RuntimeClient {
249
+ private baseUrl;
250
+ private timeout;
251
+ private components;
252
+ private initialized;
253
+ constructor(options?: {
254
+ host?: string;
255
+ port?: number;
256
+ timeout?: number;
257
+ ssl?: boolean;
258
+ });
259
+ private request;
260
+ initialize(): Promise<void>;
261
+ registerComponent(componentId: string, componentCode: string): Promise<void>;
262
+ renderToRscFormat(componentId: string, props?: string): Promise<string>;
263
+ renderToString(componentId: string, props?: string): Promise<string>;
264
+ renderToStreamCallbacks(componentId: string, props?: string): Promise<any>;
265
+ registerClientComponent(componentId: string, filePath: string, exportName: string): void;
266
+ private queueClientComponentRegistration;
267
+ registerClientReference(referenceId: string, filePath: string, exportName: string): void;
268
+ listComponents(): string[];
269
+ shutdown(): Promise<void>;
270
+ getServerStatus(): Promise<StatusResponse>;
271
+ checkHealth(): Promise<HealthResponse>;
272
+ refreshComponentList(): Promise<string[]>;
273
+ isInitialized(): boolean;
274
+ getBaseUrl(): string;
275
+ }
276
+ declare function createHttpRuntimeClient(options?: {
277
+ host?: string;
278
+ port?: number;
279
+ timeout?: number;
280
+ ssl?: boolean;
281
+ }): RuntimeClient;
282
+ //#endregion
283
+ export { ErrorBoundaryProps, FileRouteInfo, HttpRuntimeClient, LayoutProps, Link, LinkProps, LoadingProps, Navigate, NavigationOptions, NavigationState, Outlet, PageComponent, PageProps, Route, RouteComponent, RouteGenerationOptions, RouteMatch, RouteMeta, RouteParams, RouterConfig, RouterContext$1 as RouterContext, RouterProvider, RouterProviderProps, Routes, RuntimeClient, SearchParams, buildSearchString, buildUrl, createHttpRuntimeClient, extractParamNames, findMatchingRoute, getRoutePriority, isDynamicRoute, isPathActive, joinPaths, normalizePathname, parseSearchParams, parseUrl, useNavigation, useParams, usePathname, useRoute, useRouter, useSearchParams, withRouter };