### JurisJS Getting Started
Source: https://github.com/jurisjs/juris/blob/main/demos/pages/minimal_counter_demo.html
Begin your journey with JurisJS through readily available resources. The platform emphasizes immediate productivity with no setup or configuration required. Explore the Quick Start, Installation guides, and Your First App tutorials to get started quickly.
```javascript
// Quick Start: juris-docs.html#quick-start
// Installation: juris-docs.html#installation
// Your First App: juris-docs.html#basic-setup
// Examples: juris-examples.html
```
--------------------------------
### Juris Zero Build Tool Setup
Source: https://github.com/jurisjs/juris/wiki/Home
Illustrates the simplicity of using Juris without a build tool by including it via a script tag. This example shows how to immediately start building an application with state management and interactive elements.
```html
```
--------------------------------
### Basic Juris Setup
Source: https://github.com/jurisjs/juris/wiki/Developer's-Guide
Demonstrates the fundamental setup of a Juris application, including script inclusion, state management, and rendering a simple counter with buttons.
```html
```
--------------------------------
### Install and Run Juris.js
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris_readme.md
This snippet demonstrates how to install Juris.js using npm and provides a basic example of creating and rendering a 'HelloWorld' component.
```bash
# Install Juris
npm install juris
# Create your first component
echo 'import Juris from "juris";
const juris = new Juris({
components: {
HelloWorld: () => ({
h1: { text: "Hello, Juris!" }
})
},
layout: { HelloWorld: {} }
});
juris.render("#app");' > app.js
# Run your app
node app.js
```
--------------------------------
### Juris.js Basic App Setup
Source: https://github.com/jurisjs/juris/blob/main/readmes/ai-guide.md
Illustrates the fundamental setup of a Juris.js application, including component registration, headless components, layout definition, and initial state configuration. It shows how to initialize and render the application.
```javascript
const juris = new Juris({
components: {
ComponentName1,
ComponentName2
},
headlessComponents: {
DataManager: { fn: DataManager, options: { autoInit: true } }
},
layout: {
div: {
children: [{ App: {} }]
}
},
states: {
user: { name: '', email: '' },
ui: { theme: 'light' }
}
});
juris.render('#app');
```
--------------------------------
### Juris Quick Start Example with CDN
Source: https://github.com/jurisjs/juris/wiki/Home
Demonstrates a quick start example using Juris loaded from a CDN. This example sets up a simple Todo application with states for todos and filters, and defines components for input, list, and filters.
```javascript
// Import from CDN
import Juris from 'https://unpkg.com/juris@0.4.0/juris.mini.js';
// Create application
const app = new Juris({
states: {
todos: [],
filter: 'all'
},
components: {
TodoApp: (props, context) => ({
div: {
className: 'todo-app',
children: [
{ h1: { text: 'Todo Application' } },
{ TodoInput: {} },
{ TodoList: {} },
{ TodoFilters: {} }
]
}
})
},
layout: { TodoApp: {} }
});
// Render to page
app.render('#app');
```
--------------------------------
### Juris Quick Start Example (CDN)
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris_whitepaper.md
Demonstrates how to use Juris.js by including it via a CDN link, suitable for quick prototyping or projects without a build setup. It sets up a basic Todo application.
```javascript
// Import from CDN
import Juris from 'https://unpkg.com/juris@0.4.0/juris.mini.js';
// Create application
const app = new Juris({
states: {
todos: [],
filter: 'all'
},
components: {
TodoApp: (props, context) => ({
div: {
className: 'todo-app',
children: [
{ h1: { text: 'Todo Application' } },
{ TodoInput: {} },
{ TodoList: {} },
{ TodoFilters: {} }
]
}
})
},
layout: { TodoApp: {} }
});
// Render to page
app.render('#app');
```
--------------------------------
### Basic Juris Application Setup
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris_documentation.md
A fundamental example demonstrating how to initialize a Juris application with states, components, and a layout, and then render it to the DOM.
```javascript
// Create a new Juris instance
const app = new Juris({
states: {
counter: 0,
user: { name: 'Guest' }
},
components: {
MyButton: (props, context) => ({
button: {
text: () => `Count: ${context.getState('counter')}`,
onclick: () => {
const current = context.getState('counter');
context.setState('counter', current + 1);
}
}
})
},
layout: {
div: {
children: [
{ h1: { text: 'Welcome to Juris!' } },
{ MyButton: {} }
]
}
}
});
// Render the application
app.render('#app');
```
--------------------------------
### Juris Quick Start Example
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris_hooks_readme.md
A basic example of setting up Juris with the state manager and a component that utilizes useState and useTimer hooks.
```javascript
import { createExtendableStateManager, TimerHooks, UIHooks } from 'juris-hooks';
const juris = new Juris({
headlessComponents: {
stateManager: {
fn: createExtendableStateManager([TimerHooks, UIHooks]),
options: { autoInit: true }
}
},
components: {
MyComponent: (props, context) => {
// ✨ useState works just like React!
const [getCount, setCount] = context.useState('counter', 0);
const timer = context.useTimer(1000);
return {
render: () => ({
div: {
children: [
{ p: { text: () => `Count: ${getCount()}` } },
{ button: {
text: 'Increment',
onclick: () => setCount(count => count + 1)
}}
]
}
})
};
}
}
});
```
--------------------------------
### Juris Headless Component Example
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris_headless_guide.md
Demonstrates the creation of a headless component in JavaScript, showcasing lifecycle hooks, reactive state management using `getState` and `setState`, and event subscriptions with `subscribe`. It includes an example of managing component state and interacting with external services.
```javascript
const userProfileComponent = (props, context) => {
const { getState, setState, subscribe } = context;
// Reactive state management
const profileData = () => getState('user.profile', {});
// Subscribe to changes
const unsubscribe = subscribe('user.profile', (newProfile) => {
// React to profile changes
validateProfile(newProfile);
});
return {
api: {
updateProfile: async (data) => {
setState('user.profile.updating', true);
try {
const updated = await updateUserProfile(data);
setState('user.profile', updated);
setState('user.profile.lastUpdated', Date.now());
} finally {
setState('user.profile.updating', false);
}
},
getProfile: () => profileData(),
isUpdating: () => getState('user.profile.updating', false)
},
hooks: {
onRegister: () => {
// Initialize profile data
loadInitialProfile();
},
onUnregister: () => {
// Cleanup subscriptions
unsubscribe();
}
}
};
};
```
--------------------------------
### Auto-Initializing Headless Components
Source: https://github.com/jurisjs/juris/wiki/Developer's-Guide
Shows how to configure headless components for automatic initialization when the Juris application starts. It includes an example of a component with an API and options for auto-initialization.
```javascript
const app = new Juris({
headlessComponents: {
// Auto-initialize on startup
AuthManager: {
fn: (props, context) => ({
api: {
login: (credentials) => { /* login logic */ },
logout: () => { /* logout logic */ },
isAuthenticated: () => context.getState('auth.isLoggedIn', false)
}
}),
options: { autoInit: true }
},
// Simple function (no auto-init)
CacheManager: (props, context) => ({
api: {
set: (key, value) => context.setState(`cache.${key}`, value),
get: (key) => context.getState(`cache.${key}`)
}
})
}
});
```
--------------------------------
### Include Juris CDN
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris-developer-readme.md
This snippet shows how to include the Juris framework in an HTML file using a CDN link. No build tools are required, making it easy to get started.
```bash
# Include Juris (single file, no build tools required)
```
--------------------------------
### JurisJS Navigation Links (HTML)
Source: https://github.com/jurisjs/juris/blob/main/demos/pages/minimal_counter_demo.html
Provides a set of navigation links for the JurisJS project, including links to Features, Demo, Examples, Docs, and Why Juris. Also includes a 'Get Started' call to action.
```HTML
[JurisJS](index.html)
* [Features](index.html#features)
* [Demo](index.html#demo)
* [Examples](juris-examples.html)
* [Docs](juris-docs.html)
* [Why Juris](why-juris.html)
[Get Started](#get-started)
```
--------------------------------
### Repository Setup and Initialization
Source: https://github.com/jurisjs/juris/blob/main/plugins/juris-plugin-guidelines.md
Commands to initialize a new Git repository, stage all files, make an initial commit, and set up the remote origin for pushing to GitHub.
```bash
git init
git add .
git commit -m "Initial commit: Add [Plugin Name]"
git remote add origin https://github.com/username/juris-plugin-name.git
git push -u origin main
```
--------------------------------
### Basic Juris Application Setup
Source: https://github.com/jurisjs/juris/blob/main/readmes/mobile_renderer_readme.md
A fundamental example of setting up a Juris application. It defines a 'Counter' component with state management and integrates the 'mobileRenderer' as a headless service. The application is then rendered to an '#app' element.
```javascript
const app = new Juris({
components: {
Counter: (props, context) => ({
stack: { // Automatically becomes UIStackView (iOS) or LinearLayout (Android)
children: [
{
text: { // Automatically becomes UILabel (iOS) or TextView (Android)
text: () => `Count: ${context.getState('count')}`,
style: { fontSize: 18, textAlign: 'center' }
}
},
{
button: { // Automatically becomes UIButton (iOS) or Button (Android)
text: 'Increment',
onclick: () => {
const current = context.getState('count');
context.setState('count', current + 1);
},
style: {
backgroundColor: '#007AFF',
color: 'white',
padding: 12,
borderRadius: 8
}
}
}
]
}
})
},
// 2. Add the mobile renderer as a headless service
headlessComponents: {
mobileRenderer: {
fn: MobileRendererService,
options: {
autoInit: true,
enableHotReload: true,
enableDebugTools: true,
performance: {
enableMetrics: true,
logThreshold: 16
}
}
}
},
layout: {
safe: { // Automatically becomes UISafeAreaLayoutGuide (iOS) or safe area handling (Android)
children: [
{ Counter: {} }
]
}
}
});
// 3. Render - automatically uses mobile renderer on mobile platforms
app.render('#app');
```
--------------------------------
### Juris Service Example (HttpService)
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris_headless_guide.md
Illustrates a JavaScript `HttpService` class designed for use within the Juris framework. This service handles HTTP requests, including GET and POST methods, with configurable base URLs and headers. It demonstrates basic error handling for non-successful HTTP responses.
```javascript
class HttpService {
constructor(config) {
this.baseURL = config.baseURL;
this.defaultHeaders = config.headers || {};
}
async get(endpoint, options = {}) {
return this.request('GET', endpoint, null, options);
}
async post(endpoint, data, options = {}) {
return this.request('POST', endpoint, data, options);
}
async request(method, endpoint, data, options) {
const url = `${this.baseURL}${endpoint}`;
const headers = { ...this.defaultHeaders, ...options.headers };
const response = await fetch(url, {
method,
headers,
body: data ? JSON.stringify(data) : undefined,
...options
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
}
}
// Usage in Juris configuration
const juris = new Juris({
services: {
http: new HttpService({
baseURL: '/api',
headers: { 'Content-Type': 'application/json' }
}),
logger: new LoggerService(),
validator: new ValidationService()
}
});
```
--------------------------------
### Basic Juris App Setup with Mobile Renderer
Source: https://github.com/jurisjs/juris/blob/main/readmes/mobile_renderer_readme.md
Demonstrates the basic setup of a Juris application, enabling the mobile renderer service with auto-initialization and defining a simple layout.
```javascript
// 1. Create your Juris app as usual
const app = new Juris({
states: {
count: 0,
user: { name: 'John' }
},
headlessComponents: {
mobileRenderer: { fn: MobileRendererService, options: { autoInit: true } }
},
layout: {
safe: {
children: [{ ContactForm: {} }]
}
}
});
```
--------------------------------
### Juris Service Example (HttpService)
Source: https://github.com/jurisjs/juris/wiki/Headless-Components-‐-Complete-Developer-Guide
Illustrates a JavaScript `HttpService` class designed for use within the Juris framework. This service handles HTTP requests, including GET and POST methods, with configurable base URLs and headers. It demonstrates basic error handling for non-successful HTTP responses.
```javascript
class HttpService {
constructor(config) {
this.baseURL = config.baseURL;
this.defaultHeaders = config.headers || {};
}
async get(endpoint, options = {}) {
return this.request('GET', endpoint, null, options);
}
async post(endpoint, data, options = {}) {
return this.request('POST', endpoint, data, options);
}
async request(method, endpoint, data, options) {
const url = `${this.baseURL}${endpoint}`;
const headers = { ...this.defaultHeaders, ...options.headers };
const response = await fetch(url, {
method,
headers,
body: data ? JSON.stringify(data) : undefined,
...options
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
}
}
// Usage in Juris configuration
const juris = new Juris({
services: {
http: new HttpService({
baseURL: '/api',
headers: { 'Content-Type': 'application/json' }
}),
logger: new LoggerService(),
validator: new ValidationService()
}
});
```
--------------------------------
### Installing Juris
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris_readme.md
Provides instructions for installing the Juris framework using npm or via a CDN for quick prototyping. This covers both project integration and browser-based usage.
```bash
npm install juris
# Or use CDN for quick prototyping
```
--------------------------------
### Server-Side Rendering Setup with Juris
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris-plugin-patterns.md
This example demonstrates how to set up Juris for Server-Side Rendering (SSR) in a Node.js environment using Express. It shows creating a Juris instance, configuring an `SSRRenderer`, rendering components to an HTML string, and sending a complete HTML page with initial state for client-side hydration.
```javascript
// server.js (Node.js)
const { Juris } = require('./juris');
// Create SSR-capable Juris instance
const createSSRJuris = (initialState = {}) => {
const juris = new Juris({
states: initialState,
components: {
App: require('./components/App'),
Header: require('./components/Header'),
// ... other components
}
});
// Replace with SSR renderer
juris.domRenderer = new SSRRenderer(juris, {
isServer: true,
includeHydrationData: true,
prettify: true
});
return juris;
};
// Express route
app.get('/', (req, res) => {
const juris = createSSRJuris({
user: { name: 'John', email: 'john@example.com' },
posts: []
});
// Render to HTML string
const html = juris.domRenderer.renderToString({
App: {
initialData: req.query
}
});
// Send complete HTML page
res.send(`
My SSR App
${html}
`);
});
```
--------------------------------
### Basic Juris App Setup with Router
Source: https://github.com/jurisjs/juris/blob/main/reviews/juris_router_readme (2).md
Demonstrates the fundamental setup of a Juris application with the router configured. It includes defining basic routes, components, and the main router outlet.
```javascript
const app = new Juris({
router: {
mode: 'hash', // 'hash', 'history', or 'memory'
routes: {
'/': { component: 'HomePage' },
'/about': { component: 'AboutPage' },
'/users/:id': { component: 'UserPage' }
}
},
components: {
HomePage: () => ({ render: () => ({ h1: { text: 'Welcome!' } }) }),
AboutPage: () => ({ render: () => ({ h1: { text: 'About Us' } }) }),
UserPage: (props, context) => ({
render: () => ({
div: {
children: [
{ h1: { text: `User: ${context.getState('router.params.id')}` } }
]
}
})
})
},
layout: {
div: {
children: [
{ Router: {} } // Main router outlet
]
}
}
});
app.render();
```
--------------------------------
### Juris App Initialization and Rendering
Source: https://github.com/jurisjs/juris/blob/main/demos/juris_simple_calculator_app.html
Demonstrates how to initialize and render the Juris application, setting up the calculator component and initial states.
```javascript
// Initialize Juris app
const juris = new Juris({
components: {
Calculator
},
layout: {
div: {
children: [
{ Calculator: {} }
]
}
},
states: {
display: '0',
value: null,
operator: '',
waitingForOperand: false,
history: []
}
});
// Render the app
juris.render('#app');
```
--------------------------------
### Event Handling Example
Source: https://github.com/jurisjs/juris/blob/main/readmes/ai-guide.md
A simple example demonstrating how to attach an event handler (`onclick`) to a button in Juris.js, updating a counter state when clicked.
```javascript
{
button: {
text: 'Click me',
onclick: () => setState('counter', getState('counter', 0) + 1)
}
}
```
--------------------------------
### Juris Complete Configuration Example
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris_readme.md
Provides a comprehensive example of configuring a Juris.js application, including initial states, middleware, components, layout, render mode, and services.
```javascript
const juris = new Juris({
// Initial state
states: {
user: { name: 'Guest', theme: 'light' },
app: { title: 'My App', version: '1.0.0' }
},
// State middleware
middleware: [
loggingMiddleware,
validationMiddleware,
persistenceMiddleware
],
// Headless components (logic only)
headlessComponents: {
auth: AuthManager,
data: DataManager,
theme: ThemeManager
},
// UI components
components: {
App: AppComponent,
Header: HeaderComponent,
Footer: FooterComponent
},
// Main layout
layout: { App: {} },
// Render mode ('fine-grained' or 'batch')
renderMode: 'batch',
// Services (dependency injection)
services: {
api: new APIService(),
storage: new StorageService(),
analytics: new AnalyticsService()
}
});
```
--------------------------------
### Universal Component Example
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris-plugin-patterns.md
An example of a Juris component designed to work with any state management solution and rendering context, showcasing the framework's adaptability.
```javascript
function UniversalComponent(props, context) {
const data = context.getState('app.data');
return context.render({
div: {
text: `Data: ${data}`,
onClick: () => context.setState('app.data', newData)
}
});
}
```
--------------------------------
### Install Juris via npm (Server-Side Projects)
Source: https://github.com/jurisjs/juris/blob/main/README.md
Details how to install the Juris package for server-side environments like Node.js, Bun, and Deno using npm. Includes installation commands and import examples for ES Modules and CommonJS.
```bash
npm install @jurisjs/juris
```
```javascript
import { Juris } from "@jurisjs/juris";
// or
import Juris from "@jurisjs/juris";
// CommonJS (Node.js)
const { Juris } = require("@jurisjs/juris");
```
--------------------------------
### Juris.js Application Initialization and State Management
Source: https://github.com/jurisjs/juris/blob/main/demos/pages/generic_juris_framework.html
Demonstrates the initialization process of the Juris.js application, including restoring state from local storage, setting up cross-tab synchronization, loading initial todos, and initializing the remote sync service. It also shows how to subscribe to state changes for debugging purposes and exposes the app instance globally.
```javascript
restoreFromLocalStorage();
setupCrossTabSync();
if (app.getState('todos', [])
.length === 0) {
app.services.todoService.loadTodos().then(todos => {
app.setState('todos', todos);
});
}
app.services.remoteSyncService.startAutoSync({
getState: (path, defaultValue) => app.getState(path, defaultValue),
setState: (path, value, context) => app.setState(path, value, context)
});
app.subscribe('todos', (newTodos, oldTodos) => {
console.log(`Todos updated: ${newTodos.length} total`);
});
app.subscribe('router.currentRoute', (newRoute) => {
console.log(`Route changed to: ${newRoute}`);
});
app.subscribe('user.isAuthenticated', (isAuth) => {
console.log(`Authentication status: ${isAuth}`);
});
app.render('#app');
window.app = app;
```
--------------------------------
### Hierarchical State Structure Example
Source: https://github.com/jurisjs/juris/blob/main/ai-guides/ai-guides.md
Provides an example of a well-organized, hierarchical state structure for a Juris.js application, demonstrating how to group related data like user profiles, preferences, and application-level settings.
```javascript
// Good: Organized hierarchy
const initialState = {
user: {
profile: { name: "", email: "" },
preferences: { theme: "light", language: "en" },
permissions: { admin: false, moderator: false },
},
app: {
loading: false,
error: null,
navigation: { currentPage: "home" },
},
};
```
--------------------------------
### Juris Headless Components for Data Management
Source: https://github.com/jurisjs/juris/blob/main/readmes/ai-guide.md
Demonstrates using headless components for data management patterns, leveraging `onRegister` for initialization.
```javascript
import { component, onRegister, reactive } from '@juris/core';
const DataLoader = component({
props: {
url: { type: 'string', required: true }
},
state: {
data: null,
loading: true,
error: null
},
onRegister: function() {
console.log(`DataLoader registered for ${this.props.url}`);
this.fetchData();
},
fetchData: async function() {
try {
const response = await fetch(this.props.url);
if (!response.ok) throw new Error('Network response was not ok');
const data = await response.json();
this.state.data = data;
this.state.loading = false;
} catch (error) {
this.state.error = error;
this.state.loading = false;
}
},
render: function() {
if (this.state.loading) return 'Loading...';
if (this.state.error) return `Error: ${this.state.error.message}`;
return JSON.stringify(this.state.data);
}
});
console.log('Juris headless components for data management demonstrated.');
```
--------------------------------
### Service-Oriented Architecture: Auth Service Example
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris_headless_guide.md
An example of designing a headless component as a service, specifically an authentication service. It provides methods for login, logout, checking authentication status, and managing user permissions.
```javascript
const authService = (props, context) => {
const { getState, setState, services } = context;
return {
api: {
// Authentication methods
login: async (credentials) => { /* implementation */ },
logout: () => { /* implementation */ },
refresh: async () => { /* implementation */ },
// State accessors
isAuthenticated: () => getState('auth.isLoggedIn', false),
getCurrentUser: () => getState('auth.user', null),
getToken: () => getState('auth.token', null),
// Permission helpers
hasPermission: (permission) => {
const user = getState('auth.user');
return user?.permissions?.includes(permission) || false;
},
hasRole: (role) => {
const user = getState('auth.user');
return user?.roles?.includes(role) || false;
}
}
};
};
```
--------------------------------
### Before Install Prompt Handling
Source: https://github.com/jurisjs/juris/blob/main/demos/juris_ecommerce_demo.html
Handles the 'beforeinstallprompt' event to allow the application to be installed on the user's device, typically by showing an install button or notification.
```javascript
let deferredPrompt; window.addEventListener('beforeinstallprompt', (e) => { e.preventDefault(); deferredPrompt = e; // Show install button or notification console.log('💡 App can be installed'); });
```
--------------------------------
### Service-Oriented Architecture: Auth Service Example
Source: https://github.com/jurisjs/juris/wiki/Headless-Components-‐-Complete-Developer-Guide
An example of designing a headless component as a service, specifically an authentication service. It provides methods for login, logout, checking authentication status, and managing user permissions.
```javascript
const authService = (props, context) => {
const { getState, setState, services } = context;
return {
api: {
// Authentication methods
login: async (credentials) => { /* implementation */ },
logout: () => { /* implementation */ },
refresh: async () => { /* implementation */ },
// State accessors
isAuthenticated: () => getState('auth.isLoggedIn', false),
getCurrentUser: () => getState('auth.user', null),
getToken: () => getState('auth.token', null),
// Permission helpers
hasPermission: (permission) => {
const user = getState('auth.user');
return user?.permissions?.includes(permission) || false;
},
hasRole: (role) => {
const user = getState('auth.user');
return user?.roles?.includes(role) || false;
}
}
};
};
```
--------------------------------
### Registering Headless Components
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris_headless_guide.md
Demonstrates three methods for registering headless components: directly using `headlessManager.register`, via the `juris` instance, or during Juris initialization.
```javascript
headlessManager.register(name, componentFn, options = {})
```
```javascript
juris.registerHeadlessComponent(name, componentFn, options = {})
```
```javascript
const juris = new Juris({
headlessComponents: {
componentName: {
fn: componentFn,
options: { autoInit: true }
}
}
});
```
--------------------------------
### Basic Juris Usage Example
Source: https://github.com/jurisjs/juris/blob/main/README.md
A placeholder for a basic usage example of the Juris library, showing how to import and instantiate it. This snippet is intended to be expanded with actual implementation examples.
```javascript
import { Juris } from "https://unpkg.com/juris@0.88.2/juris.js";
// or
import Juris from "https://unpkg.com/juris@0.88.2/juris.js";
// Your implementation examples here
```
--------------------------------
### Single Responsibility Principle Examples
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris_headless_guide.md
Illustrates the Single Responsibility Principle by showing examples of components with focused responsibilities (authentication, caching) versus components with mixed responsibilities. Promotes creating components that do one thing well.
```javascript
// Good: Focused authentication service
const authService = (props, context) => { /* auth logic only */ };
// Good: Focused data caching service
const cacheService = (props, context) => { /* caching logic only */ };
// Avoid: Mixed responsibilities
const authAndDataService = (props, context) => { /* auth + data + UI logic */ };
```
--------------------------------
### Create a Basic Juris App
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris-developer-readme.md
Demonstrates the creation of a simple Juris application with state management and a basic component. It initializes states for a counter and user, defines a 'hello-world' component, and renders the app to a DOM element.
```javascript
// Create your first Juris app
const app = new Juris({
states: {
counter: { value: 0 },
user: { name: 'Developer' }
},
components: {
'hello-world': (props, ctx) => ({
div: {
children: [
{ h1: { text: () => `Hello, ${ctx.getState('user.name')}!` } },
{ p: { text: () => `Count: ${ctx.getState('counter.value')}` } },
{
button: {
text: 'Click me!',
onclick: () => {
const current = ctx.getState('counter.value');
ctx.setState('counter.value', current + 1);
}
}
}
]
}
})
},
layout: { 'hello-world': {} }
});
app.render('#app');
```
--------------------------------
### Single Responsibility Principle Examples
Source: https://github.com/jurisjs/juris/wiki/Headless-Components-‐-Complete-Developer-Guide
Illustrates the Single Responsibility Principle by showing examples of components with focused responsibilities (authentication, caching) versus components with mixed responsibilities. Promotes creating components that do one thing well.
```javascript
// Good: Focused authentication service
const authService = (props, context) => { /* auth logic only */ };
// Good: Focused data caching service
const cacheService = (props, context) => { /* caching logic only */ };
// Avoid: Mixed responsibilities
const authAndDataService = (props, context) => { /* auth + data + UI logic */ };
```
--------------------------------
### ExamplesPage Component
Source: https://github.com/jurisjs/juris/blob/main/demos/juris-docs-site.html
The ExamplesPage component showcases various code examples of the Juris Framework in action. It presents different application types like a Todo App, Dashboard, E-commerce site, and a Game, each with a brief description and a 'View Example' button.
```javascript
const ExamplesPage = (props, context) => {
return {
render: () => ({
div: {
className: 'section-view',
children: [
{
h1: { text: 'Code Examples' }
},
{
p: {
className: 'subtitle',
text: 'Explore real-world examples of Juris Framework in action.'
}
},
{
div: {
className: 'feature-grid',
children: [
{
div: {
className: 'feature-card',
children: [
{
h3: { text: '📝 Todo App' }
},
{
p: {
text: 'Classic todo application showcasing state management, user interactions, and persistent storage.'
}
},
{
button: {
className: 'cta-button',
text: 'View Example'
}
}
]
}
},
{
div: {
className: 'feature-card',
children: [
{
h3: { text: '📊 Dashboard' }
},
{
p: {
text: 'Data visualization dashboard with real-time updates and interactive charts.'
}
},
{
button: {
className: 'cta-button',
text: 'View Example'
}
}
]
}
},
{
div: {
className: 'feature-card',
children: [
{
h3: { text: '🛒 E-commerce' }
},
{
p: {
text: 'Shopping cart with product filtering, user authentication, and payment integration.'
}
},
{
button: {
className: 'cta-button',
text: 'View Example'
}
}
]
}
},
{
div: {
className: 'feature-card',
children: [
{
h3: { text: '🎮 Game' }
},
{
p: {
text: 'Interactive browser game demonstrating animation, collision detection, and game state.'
}
},
{
button: {
className: 'cta-button',
text: 'View Example'
}
}
]
}
}
]
}
}
]
}
})
};
};
```
--------------------------------
### Juris.js: Incorrect Event Handling
Source: https://github.com/jurisjs/juris/blob/main/readmes/ai-guide.md
Illustrates the correct method for handling events in Juris.js components. The 'WRONG' example shows a function being called immediately, while the 'CORRECT' example demonstrates passing a function reference to the event handler like `onclick`.
```javascript
// WRONG - Calling function immediately
onclick: setState('clicked', true)
// CORRECT - Passing function reference
onclick: () => setState('clicked', true)
```
--------------------------------
### Asynchronous Initialization Example
Source: https://github.com/jurisjs/juris/blob/main/readmes/juris_headless_guide.md
Shows how a headless component can perform asynchronous initialization, such as connecting to a database. It updates the context state during the initialization process and provides methods to interact with the initialized resource.
```javascript
const databaseComponent = (props, context) => {
const { setState } = context;
// Async initialization
const initPromise = (async () => {
setState('db.connecting', true);
try {
const connection = await connectToDatabase(props.connectionString);
setState('db.connected', true);
setState('db.connection', connection);
return connection;
} catch (error) {
setState('db.error', error.message);
throw error;
} finally {
setState('db.connecting', false);
}
})();
return {
api: {
query: async (sql, params) => {
const connection = await initPromise;
return connection.query(sql, params);
},
isConnected: () => getState('db.connected', false),
getError: () => getState('db.error', null)
},
hooks: {
onUnregister: async () => {
try {
const connection = await initPromise;
await connection.close();
} catch (error) {
// Handle cleanup error
}
}
}
};
};
```
--------------------------------
### Juris Initialization and Rendering
Source: https://github.com/jurisjs/juris/blob/main/demos/juris_simple_todos_app.html
Demonstrates how to initialize the Juris application, define components, set up the layout, and manage initial states. It also shows how to render the application into a specified DOM element and provides global access for debugging.
```javascript
// Initialize Juris app
const juris = new Juris({
components: {
TodosApp,
TodoItem
},
layout: {
div: {
children: [
{
TodosApp: {}
}
]
}
},
states: {
todos: {},
todoList: [],
newTodo: '',
filter: 'all'
}
});
// Render the app
juris.render('#app');
// Global access for debugging
window.juris = juris;
console.log('📝 Simple Todos Ready!');
console.log('💡 Try: juris.setState("newTodo", "Test todo")');
console.log('📊 Current todos:', juris.getState('todos'));
```
--------------------------------
### Juris Framework Initialization and Core Methods
Source: https://github.com/jurisjs/juris/blob/main/demos/pages/juris-demo_modify.html
This snippet covers the initialization of the Juris framework, including state management, component registration, routing setup, and the enhancement system. It also highlights a key fix in the `getComponent` method for improved selector validation and handling of different selector types.
```javascript
class Juris {
constructor(config = {}) {
// Core state
this.state = config.states || {};
this.components = new Map();
this.services = config.services || {};
this.layout = config.layout;
this.middleware = config.middleware || [];
// Router configuration
this.router = config.router;
this.routes = {};
this.routeGuards = {};
this.routeMiddleware = [];
this.routeParams = {};
this.currentRoute = '/';
// State management
this.subscribers = new Map();
this.elementSubscriptions = new WeakMap();
this.currentlyTracking = null;
// External subscribers
this.externalSubscribers = new Map();
// Enhancement system with memory management
this.selectorObservers = new Map();
this.enhancementQueue = new Set();
this.cleanupScheduled = false;
this.trackedElements = new Set();
this.isDestroyed = false;
// Performance optimization
this.updateBatches = new Map();
this.batchTimeout = null;
// Component lifecycle management
this.componentInstances = new Map();
this.componentApis = new WeakMap();
this.lifecycleCleanup = new WeakMap();
this.mountedComponents = new Set();
// Register components
if (config.components) {
Object.entries(config.components).forEach(([name, component]) => {
this.registerComponent(name, component);
});
}
// Register components from services (for backwards compatibility)
if (config.services) {
this.registerComponentsFromServices(config.services);
}
// Setup router if enabled
if (this.router) {
this.setupRouter();
}
// Setup cleanup handlers
this.setupCleanupHandlers();
console.log('🚀 Juris framework initialized');
}
// FIXED: Enhanced getComponent method with proper selector validation
getComponent(selector) {
// Validate selector input - this is the key fix
if (!selector) {
console.warn('getComponent: No selector provided');
return null;
}
// Handle invalid selector types - prevents [object Object] warnings
if (typeof selector !== 'string' && !(selector instanceof HTMLElement)) {
console.warn(`getComponent: Invalid selector type. Expected string or HTMLElement, got ${typeof selector}:`, selector);
return null;
}
let element;
if (typeof selector === 'string') {
// Find by component name first
element = document.querySelector(`[data-component-name="${selector}"]`);
if (!element) {
// Try CSS selector as fallback
try {
element = document.querySelector(selector);
} catch (error) {
console.warn(`getComponent: Invalid CSS selector "${selector}":`, error);
return null;
}
}
} else if (selector instanceof HTMLElement) {
element = selector;
}
if (!element) {
return null; // Silent fail instead of warning to reduce noise
}
// Check if element has component API stored
const api = this.componentApis.get(element);
if (api) {
return api;
}
// Fallback to instance API
const instanceId = element.getAttribute('data-component-instance');
const instance = instanceId ? this.componentInstances.get(instanceId) : null;
if (instance && instance.api) {
return instance.api;
}
return null; // Silent fail
}
// ... other methods from the original file
}
```
--------------------------------
### Juris Headless Component Example
Source: https://github.com/jurisjs/juris/wiki/Headless-Components-‐-Complete-Developer-Guide
Demonstrates the creation of a headless component in JavaScript, showcasing lifecycle hooks, reactive state management using `getState` and `setState`, and event subscriptions with `subscribe`. It includes an example of managing component state and interacting with external services.
```javascript
const userProfileComponent = (props, context) => {
const { getState, setState, subscribe } = context;
// Reactive state management
const profileData = () => getState('user.profile', {});
// Subscribe to changes
const unsubscribe = subscribe('user.profile', (newProfile) => {
// React to profile changes
validateProfile(newProfile);
});
return {
api: {
updateProfile: async (data) => {
setState('user.profile.updating', true);
try {
const updated = await updateUserProfile(data);
setState('user.profile', updated);
setState('user.profile.lastUpdated', Date.now());
} finally {
setState('user.profile.updating', false);
}
},
getProfile: () => profileData(),
isUpdating: () => getState('user.profile.updating', false)
},
hooks: {
onRegister: () => {
// Initialize profile data
loadInitialProfile();
},
onUnregister: () => {
// Cleanup subscriptions
unsubscribe();
}
}
};
};
```