kernel-script 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 +21 -0
- package/README.md +396 -0
- package/bun.lock +385 -0
- package/dist/core/bootstrap.d.ts +2 -0
- package/dist/core/commands.d.ts +15 -0
- package/dist/core/engine-hub.d.ts +8 -0
- package/dist/core/helper.d.ts +1 -0
- package/dist/core/hooks/use-queue.d.ts +36 -0
- package/dist/core/persistence-manager.d.ts +10 -0
- package/dist/core/queue-manager.d.ts +66 -0
- package/dist/core/registry.d.ts +3 -0
- package/dist/core/store/base-task.store.d.ts +39 -0
- package/dist/core/task-context.d.ts +23 -0
- package/dist/index.cjs +4051 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +3575 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 2noScript
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
# kernel-script
|
|
2
|
+
|
|
3
|
+
[npm-version]: https://npmjs.org/package/kernel-script
|
|
4
|
+
[npm-downloads]: https://npmjs.org/package/kernel-script
|
|
5
|
+
[license]: https://mit-license.org
|
|
6
|
+
[license-url]: LICENSE
|
|
7
|
+
|
|
8
|
+
[](https://npmjs.org/package/kernel-script)
|
|
9
|
+
[](https://npmjs.org/package/kernel-script)
|
|
10
|
+
[](LICENSE)
|
|
11
|
+
|
|
12
|
+
Task queue manager for Chrome extensions with background processing, persistence, and React hooks.
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Quick Start](#quick-start)
|
|
17
|
+
- [Features](#features)
|
|
18
|
+
- [Architecture](#architecture)
|
|
19
|
+
- [Installation](#installation)
|
|
20
|
+
- [Usage](#usage)
|
|
21
|
+
- [Basic Setup](#basic-setup)
|
|
22
|
+
- [React Hook](#react-hook)
|
|
23
|
+
- [Advanced](#advanced)
|
|
24
|
+
- [API Reference](#api-reference)
|
|
25
|
+
- [Core](#core)
|
|
26
|
+
- [Hooks](#hooks)
|
|
27
|
+
- [Store](#store)
|
|
28
|
+
- [Queue Operations](#queue-operations)
|
|
29
|
+
- [Types](#types)
|
|
30
|
+
- [Troubleshooting](#troubleshooting)
|
|
31
|
+
- [Contributing](#contributing)
|
|
32
|
+
- [License](#license)
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install kernel-script
|
|
38
|
+
# or
|
|
39
|
+
bun add kernel-script
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import {
|
|
44
|
+
setupBackgroundEngine,
|
|
45
|
+
registerAllEngines,
|
|
46
|
+
useQueue,
|
|
47
|
+
createTaskStore,
|
|
48
|
+
} from 'kernel-script';
|
|
49
|
+
|
|
50
|
+
// 1. Define your engine
|
|
51
|
+
const myEngine = {
|
|
52
|
+
keycard: 'my-platform',
|
|
53
|
+
execute: async (ctx) => {
|
|
54
|
+
// Your automation logic here
|
|
55
|
+
return { success: true, output: 'Done' };
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// 2. Initialize in background script
|
|
60
|
+
setupBackgroundEngine({ 'my-platform': myEngine });
|
|
61
|
+
|
|
62
|
+
// 3. Use in React component
|
|
63
|
+
const store = createTaskStore({ name: 'my-tasks' });
|
|
64
|
+
const { start, pause, tasks, pendingCount } = useQueue({
|
|
65
|
+
keycard: 'my-platform',
|
|
66
|
+
funcs: store,
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Features
|
|
71
|
+
|
|
72
|
+
- **Task Queue Management** - Queue, schedule, and execute tasks with configurable concurrency
|
|
73
|
+
- **Background Processing** - Run tasks in Chrome background service workers
|
|
74
|
+
- **Persistence** - Queue state persists across extension restarts
|
|
75
|
+
- **React Hooks** - Built-in `useQueue` hook for React integration
|
|
76
|
+
- **Engine System** - Pluggable engine architecture for different task types
|
|
77
|
+
- **TypeScript Support** - Full TypeScript support with type definitions
|
|
78
|
+
|
|
79
|
+
## Architecture
|
|
80
|
+
|
|
81
|
+
### Data Flow
|
|
82
|
+
|
|
83
|
+
```mermaid
|
|
84
|
+
graph LR
|
|
85
|
+
A[User] --> B[React Store]
|
|
86
|
+
B --> C[sendMessage]
|
|
87
|
+
C --> D[QueueManager]
|
|
88
|
+
D --> E[EngineHub]
|
|
89
|
+
D --> F[PersistenceManager]
|
|
90
|
+
E --> G[Engines]
|
|
91
|
+
F --> H[IndexedDB]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Components
|
|
95
|
+
|
|
96
|
+
| Layer | Component | Description |
|
|
97
|
+
| ----- | ------------------- | ------------------------------------ |
|
|
98
|
+
| UI | TaskStore (Zustand) | Local state management |
|
|
99
|
+
| UI | useQueue Hook | React hook interface |
|
|
100
|
+
| BG | QueueManager | Task scheduling, concurrency control |
|
|
101
|
+
| BG | EngineHub | Engine router/registry |
|
|
102
|
+
| BG | PersistenceManager | IndexedDB persistence |
|
|
103
|
+
| BG | Engines | Task executors |
|
|
104
|
+
|
|
105
|
+
### Task Flows
|
|
106
|
+
|
|
107
|
+
#### Task Execution Flow
|
|
108
|
+
|
|
109
|
+
```mermaid
|
|
110
|
+
graph LR
|
|
111
|
+
A[User creates task] --> B[Store.update]
|
|
112
|
+
B --> C[sendMessage ADD]
|
|
113
|
+
C --> D[QueueManager.add]
|
|
114
|
+
D --> E[EngineHub.get]
|
|
115
|
+
E --> F[Engine.execute]
|
|
116
|
+
F --> G[Result]
|
|
117
|
+
G --> H[QUEUE_EVENT]
|
|
118
|
+
H --> I[Store.setTasks]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Task Lifecycle
|
|
122
|
+
|
|
123
|
+
```mermaid
|
|
124
|
+
stateDiagram-v2
|
|
125
|
+
[*] --> Draft
|
|
126
|
+
Draft --> Waiting: add()
|
|
127
|
+
Waiting --> Running: start()
|
|
128
|
+
Running --> Completed: success
|
|
129
|
+
Running --> Error: failed
|
|
130
|
+
Error --> Waiting: retryTasks
|
|
131
|
+
Completed --> [*]
|
|
132
|
+
Error --> [*]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Persistence & Hydration
|
|
136
|
+
|
|
137
|
+
| Event | Action |
|
|
138
|
+
| --------------- | ----------------------------------------------------- |
|
|
139
|
+
| Browser restart | Service Worker restarts |
|
|
140
|
+
| Hydrate | Load queue state from IndexedDB |
|
|
141
|
+
| RehydrateTasks | Scan tasks, reset Running to Waiting, re-add to queue |
|
|
142
|
+
|
|
143
|
+
### Message Flow
|
|
144
|
+
|
|
145
|
+
```mermaid
|
|
146
|
+
sequenceDiagram
|
|
147
|
+
participant UI as UI (React)
|
|
148
|
+
participant BG as Background SW
|
|
149
|
+
|
|
150
|
+
UI->>BG: QUEUE_COMMAND: ADD
|
|
151
|
+
BG->>BG: queueManager.add()
|
|
152
|
+
BG->>BG: processTask()
|
|
153
|
+
BG->>BG: engine.execute()
|
|
154
|
+
BG-->>UI: QUEUE_EVENT: TASKS_UPDATED
|
|
155
|
+
UI->>UI: setTasks(tasks)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Main Operations
|
|
159
|
+
|
|
160
|
+
| Operation | Description |
|
|
161
|
+
| ----------------- | ----------------------------- |
|
|
162
|
+
| `add(task)` | Add 1 task to queue |
|
|
163
|
+
| `addMany(tasks)` | Add multiple tasks |
|
|
164
|
+
| `start()` | Start processing queue |
|
|
165
|
+
| `pause()` | Pause (don't cancel tasks) |
|
|
166
|
+
| `resume()` | Resume processing |
|
|
167
|
+
| `stop()` | Stop + halt all running tasks |
|
|
168
|
+
| `haltTask(id)` | Halt 1 task to Waiting |
|
|
169
|
+
| `cancelTask(id)` | Cancel completely from list |
|
|
170
|
+
| `retryTasks(ids)` | Retry failed tasks |
|
|
171
|
+
|
|
172
|
+
## Installation
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
npm install kernel-script
|
|
176
|
+
# or
|
|
177
|
+
bun add kernel-script
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Usage
|
|
181
|
+
|
|
182
|
+
### Basic Setup
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
import { setupBackgroundEngine, registerAllEngines } from 'kernel-script';
|
|
186
|
+
import type { BaseEngine, Task, EngineResult } from 'kernel-script';
|
|
187
|
+
|
|
188
|
+
// Define your custom engine
|
|
189
|
+
const myEngine: BaseEngine = {
|
|
190
|
+
keycard: 'my-platform',
|
|
191
|
+
|
|
192
|
+
async execute(ctx: Task): Promise<EngineResult> {
|
|
193
|
+
try {
|
|
194
|
+
const tab = await chrome.tabs.create({ url: ctx.payload.url });
|
|
195
|
+
await this.runAutomation(tab.id, ctx);
|
|
196
|
+
const output = await this.getResult(tab.id);
|
|
197
|
+
return { success: true, output };
|
|
198
|
+
} catch (error) {
|
|
199
|
+
return { success: false, error: error.message };
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
cancel(taskId: string): void {
|
|
204
|
+
// Cancel logic here
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// Initialize in your background script
|
|
209
|
+
setupBackgroundEngine({ 'my-platform': myEngine });
|
|
210
|
+
|
|
211
|
+
// Optionally register all built-in engines
|
|
212
|
+
registerAllEngines();
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### React Hook
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
import { useQueue, createTaskStore } from 'kernel-script';
|
|
219
|
+
|
|
220
|
+
// Create a task store
|
|
221
|
+
const taskStore = createTaskStore({ name: 'my-tasks' });
|
|
222
|
+
|
|
223
|
+
// Use in your component
|
|
224
|
+
function TaskQueue() {
|
|
225
|
+
const { start, pause, resume, stop, tasks, pendingCount, runningCount } = useQueue({
|
|
226
|
+
keycard: 'my-platform',
|
|
227
|
+
funcs: taskStore,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
return (
|
|
231
|
+
<div>
|
|
232
|
+
<h2>Tasks: {tasks.length}</h2>
|
|
233
|
+
<p>Pending: {pendingCount} | Running: {runningCount}</p>
|
|
234
|
+
<button onClick={start}>Start</button>
|
|
235
|
+
<button onClick={pause}>Pause</button>
|
|
236
|
+
<button onClick={resume}>Resume</button>
|
|
237
|
+
<button onClick={stop}>Stop</button>
|
|
238
|
+
</div>
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Advanced
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import { getQueueManager, TaskConfig } from 'kernel-script';
|
|
247
|
+
|
|
248
|
+
// Get queue manager instance
|
|
249
|
+
const queueManager = getQueueManager();
|
|
250
|
+
|
|
251
|
+
// Configure queue
|
|
252
|
+
const config: TaskConfig = {
|
|
253
|
+
threads: 3,
|
|
254
|
+
delayMin: 1000,
|
|
255
|
+
delayMax: 5000,
|
|
256
|
+
stopOnErrorCount: 5,
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
// Add tasks
|
|
260
|
+
await queueManager.add('my-platform', 'default', {
|
|
261
|
+
id: 'task-001',
|
|
262
|
+
no: 1,
|
|
263
|
+
name: 'Generate cat image',
|
|
264
|
+
status: 'Waiting',
|
|
265
|
+
progress: 0,
|
|
266
|
+
payload: { prompt: 'a cute cat' },
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// Add multiple tasks
|
|
270
|
+
await queueManager.addMany('my-platform', 'default', [
|
|
271
|
+
{ id: 'task-002', no: 2, name: 'Task 2', status: 'Waiting', progress: 0, payload: {} },
|
|
272
|
+
{ id: 'task-003', no: 3, name: 'Task 3', status: 'Waiting', progress: 0, payload: {} },
|
|
273
|
+
]);
|
|
274
|
+
|
|
275
|
+
// Start processing
|
|
276
|
+
queueManager.start('my-platform', 'default');
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## API Reference
|
|
280
|
+
|
|
281
|
+
### Core
|
|
282
|
+
|
|
283
|
+
| Export | Description |
|
|
284
|
+
| -------------------------------- | -------------------------------------------- |
|
|
285
|
+
| `QueueManager` | Main queue manager class |
|
|
286
|
+
| `getQueueManager()` | Get queue manager singleton |
|
|
287
|
+
| `TaskContext` | Context for task execution with abort signal |
|
|
288
|
+
| `setupBackgroundEngine(engines)` | Initialize background engine |
|
|
289
|
+
| `engineHub` | Engine registry |
|
|
290
|
+
| `persistenceManager` | Persistence layer |
|
|
291
|
+
| `registerAllEngines()` | Register all built-in engines |
|
|
292
|
+
| `sleep(ms)` | Promise-based sleep function |
|
|
293
|
+
|
|
294
|
+
### Hooks
|
|
295
|
+
|
|
296
|
+
| Hook | Description | Usage |
|
|
297
|
+
| ------------------ | ------------------------------- | ------------------------------ |
|
|
298
|
+
| `useQueue(config)` | React hook for queue operations | `useQueue({ keycard, funcs })` |
|
|
299
|
+
|
|
300
|
+
### Store
|
|
301
|
+
|
|
302
|
+
| Function | Description |
|
|
303
|
+
| -------------------------- | ------------------------------ |
|
|
304
|
+
| `createTaskStore(options)` | Create Zustand store for tasks |
|
|
305
|
+
|
|
306
|
+
### Queue Operations
|
|
307
|
+
|
|
308
|
+
| Operation | Description |
|
|
309
|
+
| --------------------------------------------- | ----------------------------- |
|
|
310
|
+
| `add(platformId, identifier, task)` | Add 1 task to queue |
|
|
311
|
+
| `addMany(platformId, identifier, tasks)` | Add multiple tasks |
|
|
312
|
+
| `start(platformId, identifier)` | Start processing queue |
|
|
313
|
+
| `pause(platformId, identifier)` | Pause (don't cancel tasks) |
|
|
314
|
+
| `resume(platformId, identifier)` | Resume processing |
|
|
315
|
+
| `stop(platformId, identifier)` | Stop + halt all running tasks |
|
|
316
|
+
| `getStatus(platformId, identifier)` | Get queue status |
|
|
317
|
+
| `retryTasks(platformId, identifier, taskIds)` | Retry failed tasks |
|
|
318
|
+
|
|
319
|
+
## Types
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
// Task status
|
|
323
|
+
type TaskStatus = 'Draft' | 'Waiting' | 'Running' | 'Completed' | 'Error' | 'Previous' | 'Skipped';
|
|
324
|
+
|
|
325
|
+
// Task definition
|
|
326
|
+
interface Task {
|
|
327
|
+
id: string;
|
|
328
|
+
no: number;
|
|
329
|
+
name: string;
|
|
330
|
+
status: TaskStatus;
|
|
331
|
+
progress: number;
|
|
332
|
+
payload: Record<string, any>;
|
|
333
|
+
output?: unknown;
|
|
334
|
+
errorMessage?: string;
|
|
335
|
+
isQueued?: boolean;
|
|
336
|
+
isFlagged?: boolean;
|
|
337
|
+
createAt?: number;
|
|
338
|
+
updateAt?: number;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Queue configuration
|
|
342
|
+
interface TaskConfig {
|
|
343
|
+
threads: number;
|
|
344
|
+
delayMin: number;
|
|
345
|
+
delayMax: number;
|
|
346
|
+
stopOnErrorCount: number;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Engine interface
|
|
350
|
+
interface BaseEngine {
|
|
351
|
+
keycard: string;
|
|
352
|
+
execute(ctx: Task): Promise<EngineResult>;
|
|
353
|
+
cancel(taskId: string): void;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Engine result
|
|
357
|
+
interface EngineResult {
|
|
358
|
+
success: boolean;
|
|
359
|
+
output?: unknown;
|
|
360
|
+
error?: string;
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Troubleshooting
|
|
365
|
+
|
|
366
|
+
### Common Issues
|
|
367
|
+
|
|
368
|
+
**Q: Tasks not executing after adding**
|
|
369
|
+
A: Make sure to call `start(platformId, identifier)` after adding tasks.
|
|
370
|
+
|
|
371
|
+
**Q: Queue not persisting after extension restart**
|
|
372
|
+
A: Verify `persistenceManager` is initialized. Check IndexedDB permissions.
|
|
373
|
+
|
|
374
|
+
**Q: React hook not updating**
|
|
375
|
+
A: Ensure your store is passed correctly to `useQueue` funcs parameter.
|
|
376
|
+
|
|
377
|
+
**Q: Engine not found**
|
|
378
|
+
A: Register your engine with `setupBackgroundEngine()` before using it.
|
|
379
|
+
|
|
380
|
+
**Q: "Cannot read property X of undefined"**
|
|
381
|
+
A: Ensure you're importing from `dist/` after building: `import { ... } from 'kernel-script'`
|
|
382
|
+
|
|
383
|
+
**Q: TypeScript errors on import**
|
|
384
|
+
A: Make sure to install peer dependencies: `npm install react react-dom`
|
|
385
|
+
|
|
386
|
+
## Contributing
|
|
387
|
+
|
|
388
|
+
1. Fork the repository
|
|
389
|
+
2. Create a feature branch: `git checkout -b feature/my-feature`
|
|
390
|
+
3. Make your changes
|
|
391
|
+
4. Run tests: `bun run build`
|
|
392
|
+
5. Submit a pull request
|
|
393
|
+
|
|
394
|
+
## License
|
|
395
|
+
|
|
396
|
+
MIT License - see [LICENSE](LICENSE) for details.
|