r1-create 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.
@@ -0,0 +1,311 @@
1
+ "use strict";
2
+ /**
3
+ * UI utilities module for R1 display optimization
4
+ * Provides tools for 240x282px display, hardware-accelerated CSS, and DOM optimization
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.R1Component = exports.PerformanceUtils = exports.LayoutUtils = exports.DOMUtils = exports.CSSUtils = exports.R1_DIMENSIONS = void 0;
8
+ exports.R1_DIMENSIONS = {
9
+ width: 240,
10
+ height: 282
11
+ };
12
+ /**
13
+ * CSS utilities for hardware-accelerated animations and R1 optimization
14
+ */
15
+ class CSSUtils {
16
+ /**
17
+ * Apply hardware-accelerated transform
18
+ * @param element Target element
19
+ * @param transform Transform value (e.g., 'translateX(10px)')
20
+ */
21
+ static setTransform(element, transform) {
22
+ element.style.transform = transform;
23
+ element.style.willChange = 'transform';
24
+ }
25
+ /**
26
+ * Apply hardware-accelerated opacity
27
+ * @param element Target element
28
+ * @param opacity Opacity value (0-1)
29
+ */
30
+ static setOpacity(element, opacity) {
31
+ element.style.opacity = opacity.toString();
32
+ element.style.willChange = 'opacity';
33
+ }
34
+ /**
35
+ * Reset will-change property to optimize performance
36
+ * @param element Target element
37
+ */
38
+ static resetWillChange(element) {
39
+ element.style.willChange = 'auto';
40
+ }
41
+ /**
42
+ * Add hardware-accelerated transition
43
+ * @param element Target element
44
+ * @param property CSS property to transition
45
+ * @param duration Duration in milliseconds
46
+ * @param easing Easing function (default: ease-out)
47
+ */
48
+ static addTransition(element, property, duration, easing = 'ease-out') {
49
+ element.style.transition = `${property} ${duration}ms ${easing}`;
50
+ }
51
+ /**
52
+ * Create optimized CSS animation class
53
+ * @param name Animation name
54
+ * @param keyframes CSS keyframes
55
+ * @param duration Duration in milliseconds
56
+ * @param easing Easing function
57
+ */
58
+ static createAnimation(name, keyframes, duration, easing = 'ease-out') {
59
+ const style = document.createElement('style');
60
+ style.textContent = `
61
+ @keyframes ${name} {
62
+ ${keyframes}
63
+ }
64
+ .${name} {
65
+ animation: ${name} ${duration}ms ${easing};
66
+ }
67
+ `;
68
+ document.head.appendChild(style);
69
+ }
70
+ }
71
+ exports.CSSUtils = CSSUtils;
72
+ /**
73
+ * DOM optimization utilities for minimal DOM changes
74
+ */
75
+ class DOMUtils {
76
+ /**
77
+ * Batch DOM operations using DocumentFragment
78
+ * @param operations Function containing DOM operations
79
+ * @param container Container element to append fragment to
80
+ */
81
+ static batchOperations(operations, container) {
82
+ const fragment = document.createDocumentFragment();
83
+ operations(fragment);
84
+ container.appendChild(fragment);
85
+ }
86
+ /**
87
+ * Efficiently update element content without full innerHTML replacement
88
+ * @param element Target element
89
+ * @param content New content
90
+ */
91
+ static updateContent(element, content) {
92
+ if (element.textContent !== content) {
93
+ element.textContent = content;
94
+ }
95
+ }
96
+ /**
97
+ * Toggle class efficiently
98
+ * @param element Target element
99
+ * @param className Class name to toggle
100
+ * @param condition Optional condition for toggle
101
+ */
102
+ static toggleClass(element, className, condition) {
103
+ if (condition !== undefined) {
104
+ element.classList.toggle(className, condition);
105
+ }
106
+ else {
107
+ element.classList.toggle(className);
108
+ }
109
+ }
110
+ /**
111
+ * Create element with optimized attributes
112
+ * @param tagName Element tag name
113
+ * @param attributes Element attributes
114
+ * @param textContent Optional text content
115
+ */
116
+ static createElement(tagName, attributes = {}, textContent) {
117
+ const element = document.createElement(tagName);
118
+ Object.entries(attributes).forEach(([key, value]) => {
119
+ element.setAttribute(key, value);
120
+ });
121
+ if (textContent !== undefined) {
122
+ element.textContent = textContent;
123
+ }
124
+ return element;
125
+ }
126
+ /**
127
+ * Debounce function for reducing DOM updates
128
+ * @param func Function to debounce
129
+ * @param delay Delay in milliseconds
130
+ */
131
+ static debounce(func, delay) {
132
+ let timeoutId;
133
+ return ((...args) => {
134
+ clearTimeout(timeoutId);
135
+ timeoutId = setTimeout(() => func.apply(null, args), delay);
136
+ });
137
+ }
138
+ }
139
+ exports.DOMUtils = DOMUtils;
140
+ DOMUtils.documentFragment = null;
141
+ /**
142
+ * Layout utilities for R1 display
143
+ */
144
+ class LayoutUtils {
145
+ /**
146
+ * Check if coordinates are within R1 display bounds
147
+ * @param x X coordinate
148
+ * @param y Y coordinate
149
+ */
150
+ static isWithinBounds(x, y) {
151
+ return x >= 0 && x <= exports.R1_DIMENSIONS.width && y >= 0 && y <= exports.R1_DIMENSIONS.height;
152
+ }
153
+ /**
154
+ * Clamp coordinates to R1 display bounds
155
+ * @param x X coordinate
156
+ * @param y Y coordinate
157
+ */
158
+ static clampToBounds(x, y) {
159
+ return {
160
+ x: Math.max(0, Math.min(x, exports.R1_DIMENSIONS.width)),
161
+ y: Math.max(0, Math.min(y, exports.R1_DIMENSIONS.height))
162
+ };
163
+ }
164
+ /**
165
+ * Calculate responsive font size based on container
166
+ * @param containerWidth Container width
167
+ * @param baseSize Base font size in px
168
+ * @param minSize Minimum font size in px
169
+ * @param maxSize Maximum font size in px
170
+ */
171
+ static calculateFontSize(containerWidth, baseSize = 16, minSize = 12, maxSize = 24) {
172
+ const ratio = containerWidth / exports.R1_DIMENSIONS.width;
173
+ const scaledSize = baseSize * ratio;
174
+ return Math.max(minSize, Math.min(scaledSize, maxSize));
175
+ }
176
+ /**
177
+ * Create CSS for R1-optimized container
178
+ */
179
+ static createR1Container() {
180
+ return `
181
+ width: ${exports.R1_DIMENSIONS.width}px;
182
+ height: ${exports.R1_DIMENSIONS.height}px;
183
+ max-width: 100vw;
184
+ max-height: 100vh;
185
+ overflow: hidden;
186
+ position: relative;
187
+ box-sizing: border-box;
188
+ `;
189
+ }
190
+ /**
191
+ * Apply R1 container styles to element
192
+ * @param element Target element
193
+ */
194
+ static applyR1Container(element) {
195
+ Object.assign(element.style, {
196
+ width: `${exports.R1_DIMENSIONS.width}px`,
197
+ height: `${exports.R1_DIMENSIONS.height}px`,
198
+ maxWidth: '100vw',
199
+ maxHeight: '100vh',
200
+ overflow: 'hidden',
201
+ position: 'relative',
202
+ boxSizing: 'border-box'
203
+ });
204
+ }
205
+ }
206
+ exports.LayoutUtils = LayoutUtils;
207
+ /**
208
+ * Performance monitoring utilities
209
+ */
210
+ class PerformanceUtils {
211
+ /**
212
+ * Start performance measurement
213
+ * @param name Measurement name
214
+ */
215
+ static startMeasure(name) {
216
+ this.performanceMarks.set(name, performance.now());
217
+ }
218
+ /**
219
+ * End performance measurement and log result
220
+ * @param name Measurement name
221
+ * @param logToConsole Whether to log to console
222
+ */
223
+ static endMeasure(name, logToConsole = true) {
224
+ const startTime = this.performanceMarks.get(name);
225
+ if (!startTime) {
226
+ console.warn(`No start mark found for: ${name}`);
227
+ return 0;
228
+ }
229
+ const duration = performance.now() - startTime;
230
+ this.performanceMarks.delete(name);
231
+ if (logToConsole) {
232
+ console.log(`Performance [${name}]: ${duration.toFixed(2)}ms`);
233
+ }
234
+ return duration;
235
+ }
236
+ /**
237
+ * Monitor frame rate
238
+ * @param duration Duration to monitor in seconds
239
+ * @param callback Callback with average FPS
240
+ */
241
+ static monitorFPS(duration, callback) {
242
+ let frames = 0;
243
+ const startTime = performance.now();
244
+ const tick = () => {
245
+ frames++;
246
+ const currentTime = performance.now();
247
+ const elapsed = (currentTime - startTime) / 1000;
248
+ if (elapsed >= duration) {
249
+ const fps = frames / elapsed;
250
+ callback(fps);
251
+ }
252
+ else {
253
+ requestAnimationFrame(tick);
254
+ }
255
+ };
256
+ requestAnimationFrame(tick);
257
+ }
258
+ }
259
+ exports.PerformanceUtils = PerformanceUtils;
260
+ PerformanceUtils.performanceMarks = new Map();
261
+ /**
262
+ * R1 UI Component base class
263
+ */
264
+ class R1Component {
265
+ constructor(tagName = 'div', className) {
266
+ this.mounted = false;
267
+ this.element = document.createElement(tagName);
268
+ if (className) {
269
+ this.element.className = className;
270
+ }
271
+ }
272
+ /**
273
+ * Mount component to container
274
+ * @param container Container element
275
+ */
276
+ mount(container) {
277
+ if (this.mounted) {
278
+ console.warn('Component already mounted');
279
+ return;
280
+ }
281
+ container.appendChild(this.element);
282
+ this.mounted = true;
283
+ this.onMount();
284
+ }
285
+ /**
286
+ * Unmount component
287
+ */
288
+ unmount() {
289
+ if (!this.mounted)
290
+ return;
291
+ if (this.element.parentNode) {
292
+ this.element.parentNode.removeChild(this.element);
293
+ }
294
+ this.mounted = false;
295
+ this.onUnmount();
296
+ }
297
+ /**
298
+ * Get component element
299
+ */
300
+ getElement() {
301
+ return this.element;
302
+ }
303
+ /**
304
+ * Check if component is mounted
305
+ */
306
+ isMounted() {
307
+ return this.mounted;
308
+ }
309
+ }
310
+ exports.R1Component = R1Component;
311
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ # R1 SDK Examples
2
+
3
+ This directory contains example applications demonstrating various features of the R1 Create SDK.
4
+
5
+ ## Examples
6
+
7
+ ### 1. Basic Plugin (`basic/`)
8
+ Simple plugin demonstrating:
9
+ - Hardware event handling (side button, scroll wheel)
10
+ - Accelerometer data display
11
+ - LLM interaction
12
+ - Storage operations
13
+
14
+ ### 2. Camera App (`camera/`)
15
+ Camera application showing:
16
+ - Camera access and preview
17
+ - Photo capture
18
+ - Image storage and display
19
+ - Hardware-accelerated UI
20
+
21
+ ### 3. Voice Recorder (`voice/`)
22
+ Voice recording app with:
23
+ - Microphone access
24
+ - Audio recording and playback
25
+ - Audio storage with Base64 encoding
26
+ - Voice-to-LLM integration
27
+
28
+ ### 4. Accelerometer Game (`accelerometer/`)
29
+ Simple tilt-based game featuring:
30
+ - Real-time accelerometer input
31
+ - Hardware-accelerated animations
32
+ - Game state management
33
+ - Performance optimization
34
+
35
+ ### 5. LLM Chat (`chat/`)
36
+ Chat interface demonstrating:
37
+ - Conversational LLM interaction
38
+ - Message history storage
39
+ - Voice input/output
40
+ - UI optimization for R1 display
41
+
42
+ ## Running Examples
43
+
44
+ 1. Build the SDK first:
45
+ ```bash
46
+ npm run build
47
+ ```
48
+
49
+ 2. Serve the examples using a local server:
50
+ ```bash
51
+ npx http-server examples -p 8080
52
+ ```
53
+
54
+ 3. Navigate to `http://localhost:8080/[example-name]/` in your browser
55
+
56
+ ## Note for R1 Device
57
+
58
+ These examples are designed to work in the R1 environment where the hardware APIs are available. When running in a regular browser:
59
+ - Hardware events won't trigger
60
+ - Storage APIs may not be available
61
+ - LLM interactions will fail
62
+ - Media permissions may be restricted
63
+
64
+ The examples include fallback behavior and error handling for development purposes.
@@ -0,0 +1,157 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Basic R1 Plugin</title>
7
+ <style>
8
+ body {
9
+ margin: 0;
10
+ padding: 0;
11
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
12
+ background: #000;
13
+ color: #fff;
14
+ overflow: hidden;
15
+ }
16
+
17
+ .container {
18
+ width: 240px;
19
+ height: 282px;
20
+ display: flex;
21
+ flex-direction: column;
22
+ align-items: center;
23
+ justify-content: center;
24
+ padding: 20px;
25
+ box-sizing: border-box;
26
+ }
27
+
28
+ .status {
29
+ font-size: 14px;
30
+ margin-bottom: 20px;
31
+ text-align: center;
32
+ }
33
+
34
+ .button {
35
+ background: #ff6b35;
36
+ color: white;
37
+ border: none;
38
+ padding: 12px 24px;
39
+ border-radius: 8px;
40
+ cursor: pointer;
41
+ font-size: 14px;
42
+ margin: 8px;
43
+ transition: background-color 0.2s;
44
+ }
45
+
46
+ .button:hover {
47
+ background: #e55a2b;
48
+ }
49
+
50
+ .accelerometer {
51
+ font-size: 12px;
52
+ text-align: center;
53
+ margin-top: 20px;
54
+ }
55
+ </style>
56
+ </head>
57
+ <body>
58
+ <div class="container">
59
+ <h1 style="font-size: 18px; margin-bottom: 20px;">R1 Basic Plugin</h1>
60
+
61
+ <div class="status" id="status">Initializing...</div>
62
+
63
+ <button class="button" onclick="askLLM()">Ask LLM</button>
64
+ <button class="button" onclick="saveData()">Save Data</button>
65
+ <button class="button" onclick="loadData()">Load Data</button>
66
+
67
+ <div class="accelerometer" id="accelerometer">
68
+ Accelerometer: Not active
69
+ </div>
70
+ </div>
71
+
72
+ <script type="module">
73
+ // Note: In a real R1 environment, you would import from 'r1-create'
74
+ // For this example, we're importing from the built dist
75
+ import { r1, createR1App } from './../../dist/index.js';
76
+
77
+ let accelerometerActive = false;
78
+
79
+ createR1App(async (sdk) => {
80
+ document.getElementById('status').textContent = 'R1 SDK Ready!';
81
+
82
+ // Hardware event listeners
83
+ sdk.hardware.on('sideClick', () => {
84
+ document.getElementById('status').textContent = 'Side button clicked!';
85
+ setTimeout(() => {
86
+ document.getElementById('status').textContent = 'R1 SDK Ready!';
87
+ }, 2000);
88
+ });
89
+
90
+ sdk.hardware.on('scrollUp', () => {
91
+ document.getElementById('status').textContent = 'Scrolled up!';
92
+ });
93
+
94
+ sdk.hardware.on('scrollDown', () => {
95
+ document.getElementById('status').textContent = 'Scrolled down!';
96
+ });
97
+
98
+ // Start accelerometer
99
+ if (await sdk.accelerometer.isAvailable()) {
100
+ sdk.accelerometer.start((data) => {
101
+ document.getElementById('accelerometer').innerHTML = `
102
+ Accelerometer:<br>
103
+ X: ${data.x.toFixed(2)}<br>
104
+ Y: ${data.y.toFixed(2)}<br>
105
+ Z: ${data.z.toFixed(2)}
106
+ `;
107
+ });
108
+ accelerometerActive = true;
109
+ }
110
+
111
+ // Message handler
112
+ sdk.messaging.onMessage((response) => {
113
+ if (response.parsedData) {
114
+ console.log('LLM Response:', response.parsedData);
115
+ document.getElementById('status').textContent = 'LLM responded!';
116
+ } else {
117
+ console.log('Message:', response.message);
118
+ document.getElementById('status').textContent = response.message;
119
+ }
120
+ });
121
+ });
122
+
123
+ // Global functions for buttons
124
+ window.askLLM = async () => {
125
+ document.getElementById('status').textContent = 'Asking LLM...';
126
+ await r1.llm.askLLMJSON('Tell me an interesting fact about technology in JSON format: {"fact": "your fact here"}');
127
+ };
128
+
129
+ window.saveData = async () => {
130
+ try {
131
+ await r1.storage.plain.setItem('demo_data', {
132
+ timestamp: new Date().toISOString(),
133
+ message: 'Hello from R1 plugin!',
134
+ visits: Math.floor(Math.random() * 100)
135
+ });
136
+ document.getElementById('status').textContent = 'Data saved!';
137
+ } catch (error) {
138
+ document.getElementById('status').textContent = 'Save failed: ' + error.message;
139
+ }
140
+ };
141
+
142
+ window.loadData = async () => {
143
+ try {
144
+ const data = await r1.storage.plain.getItem('demo_data');
145
+ if (data) {
146
+ document.getElementById('status').textContent = `Loaded: ${data.visits} visits`;
147
+ console.log('Loaded data:', data);
148
+ } else {
149
+ document.getElementById('status').textContent = 'No data found';
150
+ }
151
+ } catch (error) {
152
+ document.getElementById('status').textContent = 'Load failed: ' + error.message;
153
+ }
154
+ };
155
+ </script>
156
+ </body>
157
+ </html>
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "r1-create",
3
+ "version": "1.0.0",
4
+ "description": "3rd party SDK for building R1/RabbitOS plugins with hardware access, storage, LLM integration, and optimized UI utilities",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist/**/*",
9
+ "examples/**/*",
10
+ "README.md",
11
+ "LICENSE"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "build:watch": "tsc --watch",
16
+ "dev": "tsc --watch",
17
+ "test": "node test.js",
18
+ "test:build": "npm run build && npm test",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "keywords": [
22
+ "r1",
23
+ "rabbit",
24
+ "rabbitos",
25
+ "plugin",
26
+ "sdk",
27
+ "hardware",
28
+ "accelerometer",
29
+ "llm",
30
+ "mobile"
31
+ ],
32
+ "author": "",
33
+ "license": "Apache-2.0",
34
+ "devDependencies": {
35
+ "typescript": "^5.0.0",
36
+ "@types/node": "^20.0.0"
37
+ },
38
+ "engines": {
39
+ "node": ">=16.0.0"
40
+ },
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "https://github.com/AidanTheBandit/R1-create.js.git"
44
+ },
45
+ "bugs": {
46
+ "url": "https://github.com/AidanTheBandit/R1-create.js/issues"
47
+ },
48
+ "homepage": "https://github.com/AidanTheBandit/R1-create.js#readme"
49
+ }