@pie-players/pie-calculator-desmos 0.1.2
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/README.md +285 -0
- package/dist/desmos-provider.d.ts +73 -0
- package/dist/desmos-provider.d.ts.map +1 -0
- package/dist/desmos-provider.js +301 -0
- package/dist/desmos-provider.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# @pie-players/pie-calculator-desmos
|
|
2
|
+
|
|
3
|
+
Desmos calculator provider for PIE Players - Premium graphing, scientific, and basic calculators.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ Beautiful, intuitive graphing calculators
|
|
8
|
+
- ✅ Interactive expression lists
|
|
9
|
+
- ✅ Scientific and basic calculator modes
|
|
10
|
+
- ✅ State persistence and export
|
|
11
|
+
- ⚠️ Requires Desmos API key from [desmos.com/api](https://www.desmos.com/api)
|
|
12
|
+
- ⚠️ Requires internet connection
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @pie-players/pie-calculator-desmos
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## How Desmos API Keys Work
|
|
21
|
+
|
|
22
|
+
According to Desmos documentation, the API key should be included when loading the Desmos calculator library:
|
|
23
|
+
|
|
24
|
+
```html
|
|
25
|
+
<script src="https://www.desmos.com/api/v1.11/calculator.js?apiKey=YOUR_KEY"></script>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
However, **this approach exposes your API key in client-side HTML**, which is a security risk for production applications.
|
|
29
|
+
|
|
30
|
+
## Security Best Practices
|
|
31
|
+
|
|
32
|
+
### ⚠️ Important Security Considerations
|
|
33
|
+
|
|
34
|
+
While Desmos's documentation shows the API key embedded in the script URL (client-side), this is **NOT SECURE for production** because:
|
|
35
|
+
|
|
36
|
+
1. Anyone can view your HTML source and see the API key
|
|
37
|
+
2. The key can be copied and used by others
|
|
38
|
+
3. You cannot rotate keys without redeploying your entire application
|
|
39
|
+
4. You have no control over who uses your key
|
|
40
|
+
|
|
41
|
+
### Our Recommended Patterns
|
|
42
|
+
|
|
43
|
+
This package supports three configuration patterns:
|
|
44
|
+
|
|
45
|
+
#### 1. Development Mode (Direct API Key) - Testing Only
|
|
46
|
+
|
|
47
|
+
Use the demo key or your own key for local development:
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<!-- Load Desmos with demo key -->
|
|
51
|
+
<script src="https://www.desmos.com/api/v1.11/calculator.js?apiKey=REDACTED_API_KEY"></script>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { DesmosCalculatorProvider } from '@pie-players/pie-calculator-desmos';
|
|
56
|
+
|
|
57
|
+
const provider = new DesmosCalculatorProvider();
|
|
58
|
+
await provider.initialize(); // Uses the globally loaded Desmos
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
⚠️ Only use your real API key like this during development!
|
|
62
|
+
|
|
63
|
+
#### 2. Production Mode (Server-Side Proxy) - ✅ RECOMMENDED
|
|
64
|
+
|
|
65
|
+
For production, use a server-side proxy to keep your API key secure:
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
const provider = new DesmosCalculatorProvider();
|
|
69
|
+
await provider.initialize({
|
|
70
|
+
proxyEndpoint: '/api/desmos/script-url' // Server returns the script URL with key
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Your server endpoint returns a signed or time-limited URL.
|
|
75
|
+
|
|
76
|
+
#### 3. Pre-loaded Library (Client-Side)
|
|
77
|
+
|
|
78
|
+
If you must use client-side loading in production (not recommended), at least load the library yourself and don't pass the key through our package:
|
|
79
|
+
|
|
80
|
+
```html
|
|
81
|
+
<script src="https://www.desmos.com/api/v1.11/calculator.js?apiKey=YOUR_KEY"></script>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
const provider = new DesmosCalculatorProvider();
|
|
86
|
+
await provider.initialize(); // No key needed, uses window.Desmos
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Note**: This still exposes your key in HTML, but at least it's not in your JavaScript bundle.
|
|
90
|
+
|
|
91
|
+
## Server-Side Proxy Implementation
|
|
92
|
+
|
|
93
|
+
### Understanding the Challenge
|
|
94
|
+
|
|
95
|
+
Desmos requires the API key in the script URL when loading the library. To keep your key secure while still working within Desmos's architecture, you need a server-side proxy.
|
|
96
|
+
|
|
97
|
+
### Option A: Proxy the Desmos Script (Most Secure)
|
|
98
|
+
|
|
99
|
+
Create a server endpoint that proxies the Desmos calculator script with your API key:
|
|
100
|
+
|
|
101
|
+
#### Express.js Example
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
// server.js
|
|
105
|
+
app.get('/api/desmos/calculator.js', requireAuth, async (req, res) => {
|
|
106
|
+
if (!req.user) {
|
|
107
|
+
return res.status(401).json({ error: 'Unauthorized' });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Fetch Desmos script with your API key server-side
|
|
111
|
+
const desmosUrl = `https://www.desmos.com/api/v1.11/calculator.js?apiKey=${process.env.DESMOS_API_KEY}`;
|
|
112
|
+
const response = await fetch(desmosUrl);
|
|
113
|
+
const script = await response.text();
|
|
114
|
+
|
|
115
|
+
res.setHeader('Content-Type', 'application/javascript');
|
|
116
|
+
res.send(script);
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Then load from your proxy in the client:
|
|
121
|
+
|
|
122
|
+
```html
|
|
123
|
+
<script src="/api/desmos/calculator.js"></script>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Option B: Return Signed/Time-Limited URL
|
|
127
|
+
|
|
128
|
+
Create temporary, authenticated URLs that expire:
|
|
129
|
+
|
|
130
|
+
#### Next.js API Route Example
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
// pages/api/desmos/script-url.ts
|
|
134
|
+
import { getServerSession } from 'next-auth';
|
|
135
|
+
import { sign } from 'jsonwebtoken';
|
|
136
|
+
|
|
137
|
+
export default async function handler(req, res) {
|
|
138
|
+
const session = await getServerSession(req, res);
|
|
139
|
+
|
|
140
|
+
if (!session) {
|
|
141
|
+
return res.status(401).json({ error: 'Unauthorized' });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Create a time-limited token
|
|
145
|
+
const token = sign(
|
|
146
|
+
{ userId: session.user.id },
|
|
147
|
+
process.env.JWT_SECRET,
|
|
148
|
+
{ expiresIn: '1h' }
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
// Return URL with your API key (only valid for this session)
|
|
152
|
+
res.json({
|
|
153
|
+
scriptUrl: `https://www.desmos.com/api/v1.11/calculator.js?apiKey=${process.env.DESMOS_API_KEY}`,
|
|
154
|
+
expiresAt: Date.now() + 3600000
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Advantages of Server-Side Proxy
|
|
160
|
+
|
|
161
|
+
1. **Security**: API key never exposed to client in retrievable form
|
|
162
|
+
2. **Authentication**: Control who can access Desmos
|
|
163
|
+
3. **Rate Limiting**: Implement usage limits server-side
|
|
164
|
+
4. **Usage Tracking**: Monitor calculator usage for billing
|
|
165
|
+
5. **Key Rotation**: Change keys without redeploying client code
|
|
166
|
+
6. **Compliance**: Meets security requirements for sensitive data
|
|
167
|
+
|
|
168
|
+
### Reality Check
|
|
169
|
+
|
|
170
|
+
**Important**: Even with a proxy, if the client loads the Desmos script, a determined user could still inspect network traffic and find the API key embedded in the script content. For true security:
|
|
171
|
+
|
|
172
|
+
1. Consider if Desmos calculators are necessary for your use case
|
|
173
|
+
2. Use alternative open-source calculator libraries (like Math.js) when possible
|
|
174
|
+
3. Contact Desmos at <partnerships@desmos.com> to discuss enterprise security options
|
|
175
|
+
4. Implement rate limiting and usage monitoring to detect key misuse
|
|
176
|
+
|
|
177
|
+
## Usage
|
|
178
|
+
|
|
179
|
+
### Basic Calculator
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
const provider = new DesmosCalculatorProvider();
|
|
183
|
+
await provider.initialize({ proxyEndpoint: '/api/desmos/token' });
|
|
184
|
+
|
|
185
|
+
const calculator = await provider.createCalculator(
|
|
186
|
+
'basic',
|
|
187
|
+
document.getElementById('calculator-container')
|
|
188
|
+
);
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Scientific Calculator
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
const calculator = await provider.createCalculator(
|
|
195
|
+
'scientific',
|
|
196
|
+
document.getElementById('calculator-container'),
|
|
197
|
+
{
|
|
198
|
+
desmos: {
|
|
199
|
+
degreeMode: true,
|
|
200
|
+
functionDefinition: true
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
);
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Graphing Calculator
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
const calculator = await provider.createCalculator(
|
|
210
|
+
'graphing',
|
|
211
|
+
document.getElementById('calculator-container'),
|
|
212
|
+
{
|
|
213
|
+
desmos: {
|
|
214
|
+
expressions: true,
|
|
215
|
+
settingsMenu: true,
|
|
216
|
+
zoomButtons: true,
|
|
217
|
+
plotInequalities: true
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
);
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Restricted/Test Mode
|
|
224
|
+
|
|
225
|
+
For assessments, you can restrict calculator features:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
const calculator = await provider.createCalculator(
|
|
229
|
+
'graphing',
|
|
230
|
+
container,
|
|
231
|
+
{
|
|
232
|
+
restrictedMode: true, // Disables settings, zoom, expressions topbar
|
|
233
|
+
desmos: {
|
|
234
|
+
restrictedFunctions: true // Additional Desmos restrictions
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
);
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Configuration Options
|
|
241
|
+
|
|
242
|
+
See the `DesmosCalculatorConfig` interface in `@pie-players/pie-calculator` for all available options.
|
|
243
|
+
|
|
244
|
+
Common options:
|
|
245
|
+
|
|
246
|
+
- `expressions`: Show/hide expression list (graphing)
|
|
247
|
+
- `settingsMenu`: Show/hide settings menu
|
|
248
|
+
- `zoomButtons`: Show/hide zoom controls
|
|
249
|
+
- `degreeMode`: Use degrees instead of radians
|
|
250
|
+
- `border`: Show calculator border
|
|
251
|
+
- `links`: Enable links to Desmos.com
|
|
252
|
+
|
|
253
|
+
## State Management
|
|
254
|
+
|
|
255
|
+
Save and restore calculator state:
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
// Export state
|
|
259
|
+
const state = calculator.exportState();
|
|
260
|
+
localStorage.setItem('calculator-state', JSON.stringify(state));
|
|
261
|
+
|
|
262
|
+
// Import state
|
|
263
|
+
const savedState = JSON.parse(localStorage.getItem('calculator-state'));
|
|
264
|
+
calculator.importState(savedState);
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Loading Desmos API
|
|
268
|
+
|
|
269
|
+
The Desmos API must be loaded before initializing the provider. You can load it from CDN:
|
|
270
|
+
|
|
271
|
+
```html
|
|
272
|
+
<script src="https://www.desmos.com/api/v1.10/calculator.js?apiKey=REDACTED_API_KEY"></script>
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Or load it dynamically in your application.
|
|
276
|
+
|
|
277
|
+
## License
|
|
278
|
+
|
|
279
|
+
This package is MIT licensed. The Desmos API requires a separate API key from Desmos.
|
|
280
|
+
|
|
281
|
+
## Links
|
|
282
|
+
|
|
283
|
+
- [Desmos API Documentation](https://www.desmos.com/api)
|
|
284
|
+
- [Get Desmos API Key](https://www.desmos.com/api)
|
|
285
|
+
- [PIE Calculator Base Package](https://www.npmjs.com/package/@pie-players/pie-calculator)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Desmos Calculator Provider
|
|
3
|
+
* Implementation of CalculatorProvider for Desmos calculators
|
|
4
|
+
*
|
|
5
|
+
* Supports: Basic, Scientific, and Graphing calculators
|
|
6
|
+
* Based on Desmos API v1.10+
|
|
7
|
+
* Requires: Desmos API key (obtain from https://www.desmos.com/api)
|
|
8
|
+
*
|
|
9
|
+
* SECURITY BEST PRACTICE:
|
|
10
|
+
* - Development: Pass apiKey directly for local testing
|
|
11
|
+
* - Production: Use proxyEndpoint to keep API key server-side
|
|
12
|
+
*
|
|
13
|
+
* Example server-side proxy (Express.js):
|
|
14
|
+
* ```
|
|
15
|
+
* app.get('/api/desmos/token', requireAuth, (req, res) => {
|
|
16
|
+
* res.json({ apiKey: process.env.DESMOS_API_KEY });
|
|
17
|
+
* });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
import type { Calculator, CalculatorProvider, CalculatorProviderCapabilities, CalculatorProviderConfig, CalculatorType } from "@pie-players/pie-calculator";
|
|
21
|
+
declare global {
|
|
22
|
+
interface Window {
|
|
23
|
+
Desmos?: any;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Desmos Calculator Provider Implementation
|
|
28
|
+
*/
|
|
29
|
+
export declare class DesmosCalculatorProvider implements CalculatorProvider {
|
|
30
|
+
readonly providerId = "desmos";
|
|
31
|
+
readonly providerName = "Desmos";
|
|
32
|
+
readonly supportedTypes: CalculatorType[];
|
|
33
|
+
readonly version = "1.10";
|
|
34
|
+
private initialized;
|
|
35
|
+
private apiKey?;
|
|
36
|
+
private proxyEndpoint?;
|
|
37
|
+
private isDevelopment;
|
|
38
|
+
/**
|
|
39
|
+
* Get the configured API key
|
|
40
|
+
* @internal Used internally by calculator instances
|
|
41
|
+
*/
|
|
42
|
+
getApiKey(): string | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Dynamically load the Desmos calculator library
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
private loadDesmosScript;
|
|
48
|
+
/**
|
|
49
|
+
* Initialize Desmos library
|
|
50
|
+
* @param config Configuration with API key (development) or proxy endpoint (production)
|
|
51
|
+
*/
|
|
52
|
+
initialize(config?: {
|
|
53
|
+
apiKey?: string;
|
|
54
|
+
proxyEndpoint?: string;
|
|
55
|
+
}): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Create a calculator instance
|
|
58
|
+
*/
|
|
59
|
+
createCalculator(type: CalculatorType, container: HTMLElement, config?: CalculatorProviderConfig): Promise<Calculator>;
|
|
60
|
+
/**
|
|
61
|
+
* Check if type is supported
|
|
62
|
+
*/
|
|
63
|
+
supportsType(type: CalculatorType): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Cleanup
|
|
66
|
+
*/
|
|
67
|
+
destroy(): void;
|
|
68
|
+
/**
|
|
69
|
+
* Get provider capabilities
|
|
70
|
+
*/
|
|
71
|
+
getCapabilities(): CalculatorProviderCapabilities;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=desmos-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desmos-provider.d.ts","sourceRoot":"","sources":["../src/desmos-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACX,UAAU,EACV,kBAAkB,EAClB,8BAA8B,EAC9B,wBAAwB,EAExB,cAAc,EAEd,MAAM,6BAA6B,CAAC;AAErC,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,MAAM;QACf,MAAM,CAAC,EAAE,GAAG,CAAC;KACb;CACD;AAED;;GAEG;AACH,qBAAa,wBAAyB,YAAW,kBAAkB;IAClE,QAAQ,CAAC,UAAU,YAAY;IAC/B,QAAQ,CAAC,YAAY,YAAY;IACjC,QAAQ,CAAC,cAAc,EAAE,cAAc,EAAE,CAIvC;IACF,QAAQ,CAAC,OAAO,UAAU;IAE1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,aAAa,CAAS;IAE9B;;;OAGG;IACH,SAAS,IAAI,MAAM,GAAG,SAAS;IAI/B;;;OAGG;YACW,gBAAgB;IAwB9B;;;OAGG;IACG,UAAU,CAAC,MAAM,CAAC,EAAE;QACzB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;KACvB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqEjB;;OAEG;IACG,gBAAgB,CACrB,IAAI,EAAE,cAAc,EACpB,SAAS,EAAE,WAAW,EACtB,MAAM,CAAC,EAAE,wBAAwB,GAC/B,OAAO,CAAC,UAAU,CAAC;IAYtB;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO;IAI3C;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,eAAe,IAAI,8BAA8B;CAUjD"}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Desmos Calculator Provider
|
|
3
|
+
* Implementation of CalculatorProvider for Desmos calculators
|
|
4
|
+
*
|
|
5
|
+
* Supports: Basic, Scientific, and Graphing calculators
|
|
6
|
+
* Based on Desmos API v1.10+
|
|
7
|
+
* Requires: Desmos API key (obtain from https://www.desmos.com/api)
|
|
8
|
+
*
|
|
9
|
+
* SECURITY BEST PRACTICE:
|
|
10
|
+
* - Development: Pass apiKey directly for local testing
|
|
11
|
+
* - Production: Use proxyEndpoint to keep API key server-side
|
|
12
|
+
*
|
|
13
|
+
* Example server-side proxy (Express.js):
|
|
14
|
+
* ```
|
|
15
|
+
* app.get('/api/desmos/token', requireAuth, (req, res) => {
|
|
16
|
+
* res.json({ apiKey: process.env.DESMOS_API_KEY });
|
|
17
|
+
* });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Desmos Calculator Provider Implementation
|
|
22
|
+
*/
|
|
23
|
+
export class DesmosCalculatorProvider {
|
|
24
|
+
providerId = "desmos";
|
|
25
|
+
providerName = "Desmos";
|
|
26
|
+
supportedTypes = [
|
|
27
|
+
"basic",
|
|
28
|
+
"scientific",
|
|
29
|
+
"graphing",
|
|
30
|
+
];
|
|
31
|
+
version = "1.10";
|
|
32
|
+
initialized = false;
|
|
33
|
+
apiKey;
|
|
34
|
+
proxyEndpoint;
|
|
35
|
+
isDevelopment = false;
|
|
36
|
+
/**
|
|
37
|
+
* Get the configured API key
|
|
38
|
+
* @internal Used internally by calculator instances
|
|
39
|
+
*/
|
|
40
|
+
getApiKey() {
|
|
41
|
+
return this.apiKey;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Dynamically load the Desmos calculator library
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
async loadDesmosScript() {
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
const script = document.createElement("script");
|
|
50
|
+
// Include API key in script URL if available
|
|
51
|
+
const scriptUrl = this.apiKey
|
|
52
|
+
? `https://www.desmos.com/api/v1.10/calculator.js?apiKey=${this.apiKey}`
|
|
53
|
+
: "https://www.desmos.com/api/v1.10/calculator.js";
|
|
54
|
+
script.src = scriptUrl;
|
|
55
|
+
script.async = true;
|
|
56
|
+
script.onload = () => {
|
|
57
|
+
if (window.Desmos) {
|
|
58
|
+
console.log("[DesmosProvider] Desmos API loaded successfully");
|
|
59
|
+
resolve();
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
reject(new Error("Desmos API loaded but window.Desmos is undefined"));
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
script.onerror = () => {
|
|
66
|
+
reject(new Error("Failed to load Desmos API from CDN"));
|
|
67
|
+
};
|
|
68
|
+
document.head.appendChild(script);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Initialize Desmos library
|
|
73
|
+
* @param config Configuration with API key (development) or proxy endpoint (production)
|
|
74
|
+
*/
|
|
75
|
+
async initialize(config) {
|
|
76
|
+
if (this.initialized)
|
|
77
|
+
return;
|
|
78
|
+
// SSR guard
|
|
79
|
+
if (typeof window === "undefined") {
|
|
80
|
+
throw new Error("Desmos calculators can only be initialized in the browser");
|
|
81
|
+
}
|
|
82
|
+
// Determine if we're in development mode
|
|
83
|
+
this.isDevelopment =
|
|
84
|
+
process.env.NODE_ENV === "development" ||
|
|
85
|
+
typeof process === "undefined" ||
|
|
86
|
+
!process.env.NODE_ENV;
|
|
87
|
+
// Configure API access pattern
|
|
88
|
+
if (config?.proxyEndpoint) {
|
|
89
|
+
// Production pattern: server-side proxy
|
|
90
|
+
this.proxyEndpoint = config.proxyEndpoint;
|
|
91
|
+
try {
|
|
92
|
+
const response = await fetch(config.proxyEndpoint);
|
|
93
|
+
if (!response.ok) {
|
|
94
|
+
throw new Error(`Proxy endpoint returned ${response.status}`);
|
|
95
|
+
}
|
|
96
|
+
const data = await response.json();
|
|
97
|
+
this.apiKey = data.apiKey;
|
|
98
|
+
console.log("[DesmosProvider] Initialized with server-side proxy (SECURE)");
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
throw new Error(`[DesmosProvider] Failed to fetch API key from proxy: ${error}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else if (config?.apiKey) {
|
|
105
|
+
// Development pattern: direct API key
|
|
106
|
+
this.apiKey = config.apiKey;
|
|
107
|
+
// Security warning in production
|
|
108
|
+
if (!this.isDevelopment) {
|
|
109
|
+
console.error("⚠️ [DesmosProvider] SECURITY WARNING: API key exposed in client-side code!\n" +
|
|
110
|
+
"This is insecure for production. Use proxyEndpoint instead.\n" +
|
|
111
|
+
"See: https://pie-players.dev/docs/calculator-desmos#security");
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
console.log("[DesmosProvider] Initialized with direct API key (DEVELOPMENT MODE)");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
// No API key provided
|
|
119
|
+
console.warn("[DesmosProvider] No API key or proxy endpoint provided.\n" +
|
|
120
|
+
"Production usage requires authentication. Obtain API key from https://www.desmos.com/api\n" +
|
|
121
|
+
"Recommended: Use proxyEndpoint for production, apiKey for development only.");
|
|
122
|
+
}
|
|
123
|
+
// Load Desmos API if not already loaded
|
|
124
|
+
if (!window.Desmos) {
|
|
125
|
+
console.log("[DesmosProvider] Loading Desmos API library...");
|
|
126
|
+
await this.loadDesmosScript();
|
|
127
|
+
}
|
|
128
|
+
this.initialized = true;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Create a calculator instance
|
|
132
|
+
*/
|
|
133
|
+
async createCalculator(type, container, config) {
|
|
134
|
+
if (!this.initialized) {
|
|
135
|
+
await this.initialize();
|
|
136
|
+
}
|
|
137
|
+
if (!this.supportsType(type)) {
|
|
138
|
+
throw new Error(`Desmos does not support calculator type: ${type}`);
|
|
139
|
+
}
|
|
140
|
+
return new DesmosCalculator(this, type, container, config, this.apiKey);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Check if type is supported
|
|
144
|
+
*/
|
|
145
|
+
supportsType(type) {
|
|
146
|
+
return this.supportedTypes.includes(type);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Cleanup
|
|
150
|
+
*/
|
|
151
|
+
destroy() {
|
|
152
|
+
this.initialized = false;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get provider capabilities
|
|
156
|
+
*/
|
|
157
|
+
getCapabilities() {
|
|
158
|
+
return {
|
|
159
|
+
supportsHistory: false, // Desmos doesn't expose history API
|
|
160
|
+
supportsGraphing: true,
|
|
161
|
+
supportsExpressions: true,
|
|
162
|
+
canExport: true,
|
|
163
|
+
maxPrecision: 15,
|
|
164
|
+
inputMethods: ["keyboard", "mouse", "touch"],
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Desmos Calculator Instance
|
|
170
|
+
*/
|
|
171
|
+
class DesmosCalculator {
|
|
172
|
+
provider;
|
|
173
|
+
type;
|
|
174
|
+
Desmos;
|
|
175
|
+
calculator;
|
|
176
|
+
container;
|
|
177
|
+
constructor(provider, type, container, config, apiKey) {
|
|
178
|
+
this.provider = provider;
|
|
179
|
+
this.type = type;
|
|
180
|
+
this.container = container;
|
|
181
|
+
this.Desmos = window.Desmos;
|
|
182
|
+
if (!this.Desmos) {
|
|
183
|
+
throw new Error("Desmos API not available");
|
|
184
|
+
}
|
|
185
|
+
this._initializeCalculator(config, apiKey);
|
|
186
|
+
}
|
|
187
|
+
_initializeCalculator(config, apiKey) {
|
|
188
|
+
// Merge Desmos-specific config with defaults
|
|
189
|
+
const desmosConfig = {
|
|
190
|
+
...(config?.desmos || {}),
|
|
191
|
+
apiKey: apiKey || config?.desmos?.apiKey,
|
|
192
|
+
};
|
|
193
|
+
// Apply restricted mode if specified
|
|
194
|
+
if (config?.restrictedMode) {
|
|
195
|
+
Object.assign(desmosConfig, {
|
|
196
|
+
expressionsTopbar: false,
|
|
197
|
+
settingsMenu: false,
|
|
198
|
+
zoomButtons: false,
|
|
199
|
+
expressions: false,
|
|
200
|
+
links: false,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
// Create appropriate calculator type
|
|
204
|
+
switch (this.type) {
|
|
205
|
+
case "graphing":
|
|
206
|
+
this.calculator = this.Desmos.GraphingCalculator(this.container, desmosConfig);
|
|
207
|
+
break;
|
|
208
|
+
case "scientific":
|
|
209
|
+
this.calculator = this.Desmos.ScientificCalculator(this.container, desmosConfig);
|
|
210
|
+
break;
|
|
211
|
+
case "basic":
|
|
212
|
+
this.calculator = this.Desmos.FourFunctionCalculator(this.container, desmosConfig);
|
|
213
|
+
break;
|
|
214
|
+
default:
|
|
215
|
+
throw new Error(`Unsupported calculator type: ${this.type}`);
|
|
216
|
+
}
|
|
217
|
+
console.log(`[DesmosCalculator] Created ${this.type} calculator`);
|
|
218
|
+
}
|
|
219
|
+
getValue() {
|
|
220
|
+
// For graphing calculator, get the state
|
|
221
|
+
if (this.type === "graphing" && this.calculator.getState) {
|
|
222
|
+
const state = this.calculator.getState();
|
|
223
|
+
return JSON.stringify(state);
|
|
224
|
+
}
|
|
225
|
+
// For other calculators, return empty (Desmos doesn't expose value API)
|
|
226
|
+
return "";
|
|
227
|
+
}
|
|
228
|
+
setValue(value) {
|
|
229
|
+
// For graphing calculator, set the state
|
|
230
|
+
if (this.type === "graphing" && this.calculator.setState) {
|
|
231
|
+
try {
|
|
232
|
+
const state = JSON.parse(value);
|
|
233
|
+
this.calculator.setState(state);
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
console.error("[DesmosCalculator] Failed to set state:", error);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
clear() {
|
|
241
|
+
if (this.calculator.setBlank) {
|
|
242
|
+
this.calculator.setBlank();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async evaluate(expression) {
|
|
246
|
+
// Desmos doesn't provide a direct evaluate API
|
|
247
|
+
// For graphing calculator, add expression and observe
|
|
248
|
+
if (this.type === "graphing") {
|
|
249
|
+
return new Promise((resolve) => {
|
|
250
|
+
const id = `eval_${Date.now()}`;
|
|
251
|
+
this.calculator.setExpression({ id, latex: expression });
|
|
252
|
+
// Give Desmos time to process
|
|
253
|
+
setTimeout(() => {
|
|
254
|
+
const helperExpression = this.calculator.HelperExpression({
|
|
255
|
+
latex: expression,
|
|
256
|
+
});
|
|
257
|
+
const result = helperExpression.numericValue || expression;
|
|
258
|
+
this.calculator.removeExpression({ id });
|
|
259
|
+
resolve(String(result));
|
|
260
|
+
}, 100);
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
return expression;
|
|
264
|
+
}
|
|
265
|
+
resize() {
|
|
266
|
+
if (this.calculator.resize) {
|
|
267
|
+
this.calculator.resize();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
exportState() {
|
|
271
|
+
let providerState = {};
|
|
272
|
+
if (this.type === "graphing" && this.calculator.getState) {
|
|
273
|
+
providerState = this.calculator.getState();
|
|
274
|
+
}
|
|
275
|
+
return {
|
|
276
|
+
type: this.type,
|
|
277
|
+
provider: "desmos",
|
|
278
|
+
value: this.getValue(),
|
|
279
|
+
providerState,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
importState(state) {
|
|
283
|
+
if (state.provider !== "desmos") {
|
|
284
|
+
throw new Error(`Cannot import state from provider: ${state.provider}`);
|
|
285
|
+
}
|
|
286
|
+
if (state.providerState && this.calculator.setState) {
|
|
287
|
+
this.calculator.setState(state.providerState);
|
|
288
|
+
}
|
|
289
|
+
else if (state.value) {
|
|
290
|
+
this.setValue(state.value);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
destroy() {
|
|
294
|
+
if (this.calculator && this.calculator.destroy) {
|
|
295
|
+
this.calculator.destroy();
|
|
296
|
+
}
|
|
297
|
+
this.container.replaceChildren();
|
|
298
|
+
console.log("[DesmosCalculator] destroyed");
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=desmos-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desmos-provider.js","sourceRoot":"","sources":["../src/desmos-provider.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pie-players/pie-calculator-desmos",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Desmos calculator provider for PIE Assessment Toolkit - High-quality graphing calculators",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"typecheck": "tsc --noEmit"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"pie",
|
|
24
|
+
"calculator",
|
|
25
|
+
"desmos",
|
|
26
|
+
"graphing",
|
|
27
|
+
"math",
|
|
28
|
+
"accessibility"
|
|
29
|
+
],
|
|
30
|
+
"author": "PIE Framework",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@pie-players/pie-calculator": "0.1.1"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"typescript": "^5.7.2"
|
|
40
|
+
}
|
|
41
|
+
}
|