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.
- package/LICENSE +201 -0
- package/README.md +245 -0
- package/dist/hardware/index.d.ts +87 -0
- package/dist/hardware/index.d.ts.map +1 -0
- package/dist/hardware/index.js +172 -0
- package/dist/hardware/index.js.map +1 -0
- package/dist/index.d.ts +88 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +196 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/index.d.ts +100 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +177 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/media/index.d.ts +176 -0
- package/dist/media/index.d.ts.map +1 -0
- package/dist/media/index.js +396 -0
- package/dist/media/index.js.map +1 -0
- package/dist/storage/index.d.ts +115 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +179 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/types/index.d.ts +66 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/ui/index.d.ts +170 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +311 -0
- package/dist/ui/index.js.map +1 -0
- package/examples/README.md +64 -0
- package/examples/basic/index.html +157 -0
- package/package.json +49 -0
package/dist/ui/index.js
ADDED
|
@@ -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
|
+
}
|