@areb0s/scip.js 1.0.5

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,161 @@
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>SCIP.js Worker Test (OpenCV-style)</title>
7
+ <style>
8
+ body {
9
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
10
+ max-width: 800px;
11
+ margin: 40px auto;
12
+ padding: 20px;
13
+ background: #1a1a2e;
14
+ color: #e0e0e0;
15
+ }
16
+ h1 { color: #4fc3f7; }
17
+ pre {
18
+ background: #0d1117;
19
+ padding: 15px;
20
+ border-radius: 8px;
21
+ overflow-x: auto;
22
+ white-space: pre-wrap;
23
+ }
24
+ .success { color: #4caf50; }
25
+ .error { color: #f44336; }
26
+ button {
27
+ background: #4fc3f7;
28
+ color: #1a1a2e;
29
+ border: none;
30
+ padding: 10px 20px;
31
+ border-radius: 6px;
32
+ cursor: pointer;
33
+ font-size: 16px;
34
+ margin: 10px 5px 10px 0;
35
+ }
36
+ button:hover { background: #29b6f6; }
37
+ #result { margin-top: 20px; }
38
+ code { background: #0d1117; padding: 2px 6px; border-radius: 4px; }
39
+ </style>
40
+ </head>
41
+ <body>
42
+ <h1>SCIP.js Worker Test (OpenCV-style)</h1>
43
+ <p>Testing CDN loading pattern like OpenCV in Worker</p>
44
+
45
+ <button onclick="testInWorker()">Run Test in Worker</button>
46
+
47
+ <div id="result">
48
+ <pre>Click "Run Test in Worker" to test OpenCV-style loading pattern</pre>
49
+ </div>
50
+
51
+ <h2>Worker Code Pattern:</h2>
52
+ <pre>
53
+ // Set base URL before loading
54
+ self.SCIP_BASE_URL = 'https://cdn.../dist/';
55
+
56
+ // Fetch and execute script
57
+ const response = await fetch(self.SCIP_BASE_URL + 'scip.min.js');
58
+ new Function(await response.text())();
59
+
60
+ // Wait for initialization (like OpenCV's cv.ready)
61
+ await self.SCIP.ready;
62
+
63
+ // Use SCIP
64
+ const result = await self.SCIP.solve(`...`);
65
+ </pre>
66
+
67
+ <script>
68
+ function log(msg) {
69
+ document.getElementById('result').innerHTML += msg + '\n';
70
+ }
71
+
72
+ async function testInWorker() {
73
+ document.getElementById('result').innerHTML = '<pre>Starting Worker test...\n';
74
+
75
+ // Get base URL from current page
76
+ const pageBaseUrl = window.location.href.substring(0, window.location.href.lastIndexOf('/') + 1);
77
+
78
+ // Create inline worker
79
+ const workerCode = `
80
+ (async () => {
81
+ try {
82
+ self.postMessage({ type: 'log', msg: 'Worker started' });
83
+
84
+ // Set base URL (passed from main thread)
85
+ self.SCIP_BASE_URL = '${pageBaseUrl}';
86
+ self.postMessage({ type: 'log', msg: 'SCIP_BASE_URL set to: ' + self.SCIP_BASE_URL });
87
+
88
+ // Fetch and execute script (OpenCV pattern)
89
+ self.postMessage({ type: 'log', msg: 'Fetching scip.min.js...' });
90
+ const response = await fetch(self.SCIP_BASE_URL + 'scip.min.js');
91
+ if (!response.ok) throw new Error('Failed to fetch: ' + response.status);
92
+
93
+ const scriptText = await response.text();
94
+ self.postMessage({ type: 'log', msg: 'Script loaded (' + scriptText.length + ' bytes)' });
95
+
96
+ // Execute script
97
+ self.postMessage({ type: 'log', msg: 'Executing script...' });
98
+ new Function(scriptText)();
99
+
100
+ // Check SCIP is available
101
+ if (typeof self.SCIP === 'undefined') {
102
+ throw new Error('SCIP not found in global scope');
103
+ }
104
+ self.postMessage({ type: 'log', msg: 'SCIP object available: ' + Object.keys(self.SCIP).join(', ') });
105
+
106
+ // Wait for ready (like OpenCV's cv.ready)
107
+ self.postMessage({ type: 'log', msg: 'Waiting for SCIP.ready...' });
108
+ await self.SCIP.ready;
109
+ self.postMessage({ type: 'log', msg: 'SCIP initialized!' });
110
+
111
+ // Solve a problem
112
+ self.postMessage({ type: 'log', msg: 'Solving LP problem...' });
113
+ const result = await self.SCIP.solve(\`
114
+ Minimize
115
+ obj: 2 x + 3 y
116
+ Subject To
117
+ c1: x + y >= 4
118
+ c2: 2 x + y >= 5
119
+ Bounds
120
+ x >= 0
121
+ y >= 0
122
+ End
123
+ \`);
124
+
125
+ self.postMessage({ type: 'success', result });
126
+
127
+ } catch (error) {
128
+ self.postMessage({ type: 'error', msg: error.message, stack: error.stack });
129
+ }
130
+ })();
131
+ `;
132
+
133
+ const blob = new Blob([workerCode], { type: 'application/javascript' });
134
+ const worker = new Worker(URL.createObjectURL(blob));
135
+
136
+ worker.onmessage = (e) => {
137
+ const data = e.data;
138
+ if (data.type === 'log') {
139
+ log(data.msg);
140
+ } else if (data.type === 'success') {
141
+ log('<span class="success">SUCCESS!</span>');
142
+ log('Status: ' + data.result.status);
143
+ log('Objective: ' + data.result.objective);
144
+ log('Variables: ' + JSON.stringify(data.result.variables));
145
+ log('</pre>');
146
+ worker.terminate();
147
+ } else if (data.type === 'error') {
148
+ log('<span class="error">ERROR: ' + data.msg + '</span>');
149
+ if (data.stack) log(data.stack);
150
+ log('</pre>');
151
+ worker.terminate();
152
+ }
153
+ };
154
+
155
+ worker.onerror = (e) => {
156
+ log('<span class="error">Worker error: ' + e.message + '</span></pre>');
157
+ };
158
+ }
159
+ </script>
160
+ </body>
161
+ </html>
@@ -0,0 +1,230 @@
1
+ /**
2
+ * SCIP.js TypeScript Type Definitions
3
+ * SCIP Optimization Solver for JavaScript/WebAssembly
4
+ */
5
+
6
+ declare module 'scip.js' {
7
+ /**
8
+ * Solution status
9
+ */
10
+ export enum Status {
11
+ OPTIMAL = 'optimal',
12
+ INFEASIBLE = 'infeasible',
13
+ UNBOUNDED = 'unbounded',
14
+ TIME_LIMIT = 'timelimit',
15
+ UNKNOWN = 'unknown',
16
+ ERROR = 'error'
17
+ }
18
+
19
+ /**
20
+ * Initialization options
21
+ */
22
+ export interface InitOptions {
23
+ /** Path to scip.wasm file (default: './scip.wasm') */
24
+ wasmPath?: string;
25
+ /** Path to Web Worker script (for worker mode) */
26
+ workerPath?: string;
27
+ }
28
+
29
+ /**
30
+ * Solver options
31
+ */
32
+ export interface SolveOptions {
33
+ /** Input format: 'lp', 'mps', 'zpl' (default: 'lp') */
34
+ format?: 'lp' | 'mps' | 'zpl';
35
+ /** Time limit in seconds (default: 3600) */
36
+ timeLimit?: number;
37
+ /** Relative gap for MIP (e.g., 0.01 for 1%) */
38
+ gap?: number | null;
39
+ /** Enable verbose output */
40
+ verbose?: boolean;
41
+ /** Additional SCIP parameters */
42
+ parameters?: Record<string, string | number | boolean>;
43
+ /** Init options (for worker mode) */
44
+ initOptions?: InitOptions;
45
+ }
46
+
47
+ /**
48
+ * Solver statistics
49
+ */
50
+ export interface Statistics {
51
+ /** Solving time in seconds */
52
+ solvingTime: number | null;
53
+ /** Number of branch-and-bound nodes */
54
+ nodes: number | null;
55
+ /** Number of LP iterations */
56
+ iterations: number | null;
57
+ /** Final optimality gap (percentage) */
58
+ gap: number | null;
59
+ }
60
+
61
+ /**
62
+ * Solution result
63
+ */
64
+ export interface Solution {
65
+ /** Solution status */
66
+ status: Status;
67
+ /** Objective function value */
68
+ objective: number | null;
69
+ /** Variable values */
70
+ variables: Record<string, number>;
71
+ /** Solver statistics */
72
+ statistics: Statistics;
73
+ /** Exit code from SCIP */
74
+ exitCode?: number;
75
+ /** Raw output (if verbose mode) */
76
+ output?: string;
77
+ /** Raw solution file content */
78
+ rawSolution?: string | null;
79
+ /** Error message (if status is ERROR) */
80
+ error?: string;
81
+ }
82
+
83
+ /**
84
+ * Initialize SCIP WASM module
85
+ * @param options - Initialization options
86
+ */
87
+ export function init(options?: InitOptions): Promise<void>;
88
+
89
+ /**
90
+ * Promise that resolves when SCIP is initialized
91
+ * Use like OpenCV's cv.ready
92
+ * @example
93
+ * await SCIP.ready;
94
+ * const result = await SCIP.solve(`...`);
95
+ */
96
+ export const ready: Promise<void>;
97
+
98
+ /**
99
+ * Check if SCIP is initialized
100
+ */
101
+ export function isReady(): boolean;
102
+
103
+ /**
104
+ * Solve an optimization problem
105
+ * @param problem - Problem in LP, MPS, or ZIMPL format
106
+ * @param options - Solver options
107
+ * @returns Solution object
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * const result = await solve(`
112
+ * Minimize obj: x + 2 y
113
+ * Subject To
114
+ * c1: x + y >= 1
115
+ * Bounds
116
+ * 0 <= x <= 10
117
+ * 0 <= y <= 10
118
+ * End
119
+ * `);
120
+ *
121
+ * if (result.status === Status.OPTIMAL) {
122
+ * console.log('Optimal value:', result.objective);
123
+ * console.log('x =', result.variables.x);
124
+ * console.log('y =', result.variables.y);
125
+ * }
126
+ * ```
127
+ */
128
+ export function solve(problem: string, options?: SolveOptions): Promise<Solution>;
129
+
130
+ /**
131
+ * Solve a minimization problem
132
+ * Convenience wrapper that ensures minimization
133
+ */
134
+ export function minimize(problem: string, options?: SolveOptions): Promise<Solution>;
135
+
136
+ /**
137
+ * Solve a maximization problem
138
+ * Convenience wrapper that ensures maximization
139
+ */
140
+ export function maximize(problem: string, options?: SolveOptions): Promise<Solution>;
141
+
142
+ /**
143
+ * Get SCIP version info
144
+ */
145
+ export function version(): Promise<string>;
146
+
147
+ /**
148
+ * Get available SCIP parameters
149
+ */
150
+ export function getParameters(): Promise<string>;
151
+
152
+ // Worker API
153
+
154
+ /**
155
+ * Initialize SCIP in a Web Worker
156
+ */
157
+ export function initWorker(options?: InitOptions): Promise<void>;
158
+
159
+ /**
160
+ * Solve in a Web Worker (non-blocking)
161
+ */
162
+ export function solveInWorker(problem: string, options?: SolveOptions): Promise<Solution>;
163
+
164
+ /**
165
+ * Minimize in a Web Worker
166
+ */
167
+ export function minimizeInWorker(problem: string, options?: SolveOptions): Promise<Solution>;
168
+
169
+ /**
170
+ * Maximize in a Web Worker
171
+ */
172
+ export function maximizeInWorker(problem: string, options?: SolveOptions): Promise<Solution>;
173
+
174
+ /**
175
+ * Terminate the Web Worker
176
+ */
177
+ export function terminateWorker(): void;
178
+
179
+ /**
180
+ * Worker solver instance
181
+ */
182
+ export interface WorkerSolver {
183
+ solve(problem: string, options?: SolveOptions): Promise<Solution>;
184
+ minimize(problem: string, options?: SolveOptions): Promise<Solution>;
185
+ maximize(problem: string, options?: SolveOptions): Promise<Solution>;
186
+ version(): Promise<string>;
187
+ isReady(): Promise<boolean>;
188
+ terminate(): void;
189
+ }
190
+
191
+ /**
192
+ * Create a worker-based solver instance
193
+ * Use for long-running optimizations to avoid blocking the main thread
194
+ */
195
+ export function createWorkerSolver(options?: InitOptions): Promise<WorkerSolver>;
196
+
197
+ // Default export
198
+ const SCIP: {
199
+ init: typeof init;
200
+ ready: typeof ready;
201
+ isReady: typeof isReady;
202
+ solve: typeof solve;
203
+ minimize: typeof minimize;
204
+ maximize: typeof maximize;
205
+ version: typeof version;
206
+ getParameters: typeof getParameters;
207
+ Status: typeof Status;
208
+ };
209
+
210
+ export default SCIP;
211
+ }
212
+
213
+ // LP Format Problem Helper Types
214
+ declare module 'scip.js/lp' {
215
+ /**
216
+ * LP Problem builder (optional convenience API)
217
+ */
218
+ export interface LPProblem {
219
+ minimize(expression: string): LPProblem;
220
+ maximize(expression: string): LPProblem;
221
+ subjectTo(name: string, constraint: string): LPProblem;
222
+ bounds(variable: string, lower?: number, upper?: number): LPProblem;
223
+ binary(...variables: string[]): LPProblem;
224
+ integer(...variables: string[]): LPProblem;
225
+ general(...variables: string[]): LPProblem;
226
+ toString(): string;
227
+ }
228
+
229
+ export function createProblem(): LPProblem;
230
+ }
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@areb0s/scip.js",
3
+ "version": "1.0.5",
4
+ "description": "SCIP Optimization Solver compiled to WebAssembly - LP, MIP, and MINLP support",
5
+ "main": "dist/index.mjs",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/types.d.ts",
8
+ "type": "module",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/types.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./worker": {
16
+ "types": "./dist/types.d.ts",
17
+ "import": "./dist/scip-worker-client.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist/",
22
+ "README.md",
23
+ "LICENSE"
24
+ ],
25
+ "unpkg": "dist/scip.browser.min.js",
26
+ "jsdelivr": "dist/scip.browser.min.js",
27
+ "scripts": {
28
+ "build": "bash build.sh",
29
+ "build:docker": "docker build -t scip-wasm-builder .",
30
+ "build:browser": "node scripts/build-browser.mjs",
31
+ "test": "node examples/test.mjs",
32
+ "serve": "npx http-server dist -p 8080 --cors",
33
+ "clean": "rm -rf dist/ build/"
34
+ },
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/areb0s/scip.js"
38
+ },
39
+ "keywords": [
40
+ "scip",
41
+ "optimization",
42
+ "solver",
43
+ "linear-programming",
44
+ "mixed-integer-programming",
45
+ "minlp",
46
+ "wasm",
47
+ "webassembly",
48
+ "operations-research",
49
+ "constraint-programming"
50
+ ],
51
+ "author": "",
52
+ "license": "Apache-2.0",
53
+ "bugs": {
54
+ "url": "https://github.com/areb0s/scip.js"
55
+ },
56
+ "homepage": "https://github.com/areb0s/scip.js",
57
+ "devDependencies": {
58
+ "esbuild": "^0.24.0"
59
+ },
60
+ "engines": {
61
+ "node": ">=18.0.0"
62
+ },
63
+ "browser": {
64
+ "./dist/index.mjs": "./dist/index.mjs"
65
+ }
66
+ }