Skip to content

Commit 9201f37

Browse files
authored
Merge pull request #1 from zooper-lib/feature/initial-implementation
Feature/initial implementation
2 parents 4210b89 + 4f61736 commit 9201f37

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+9402
-1
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
description: Implement an approved OpenSpec change and keep tasks in sync.
3+
---
4+
5+
$ARGUMENTS
6+
<!-- OPENSPEC:START -->
7+
**Guardrails**
8+
- Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
9+
- Keep changes tightly scoped to the requested outcome.
10+
- Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
11+
12+
**Steps**
13+
Track these steps as TODOs and complete them one by one.
14+
1. Read `changes/<id>/proposal.md`, `design.md` (if present), and `tasks.md` to confirm scope and acceptance criteria.
15+
2. Work through tasks sequentially, keeping edits minimal and focused on the requested change.
16+
3. Confirm completion before updating statuses—make sure every item in `tasks.md` is finished.
17+
4. Update the checklist after all work is done so each task is marked `- [x]` and reflects reality.
18+
5. Reference `openspec list` or `openspec show <item>` when additional context is required.
19+
20+
**Reference**
21+
- Use `openspec show <id> --json --deltas-only` if you need additional context from the proposal while implementing.
22+
<!-- OPENSPEC:END -->
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
description: Archive a deployed OpenSpec change and update specs.
3+
---
4+
5+
$ARGUMENTS
6+
<!-- OPENSPEC:START -->
7+
**Guardrails**
8+
- Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
9+
- Keep changes tightly scoped to the requested outcome.
10+
- Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
11+
12+
**Steps**
13+
1. Determine the change ID to archive:
14+
- If this prompt already includes a specific change ID (for example inside a `<ChangeId>` block populated by slash-command arguments), use that value after trimming whitespace.
15+
- If the conversation references a change loosely (for example by title or summary), run `openspec list` to surface likely IDs, share the relevant candidates, and confirm which one the user intends.
16+
- Otherwise, review the conversation, run `openspec list`, and ask the user which change to archive; wait for a confirmed change ID before proceeding.
17+
- If you still cannot identify a single change ID, stop and tell the user you cannot archive anything yet.
18+
2. Validate the change ID by running `openspec list` (or `openspec show <id>`) and stop if the change is missing, already archived, or otherwise not ready to archive.
19+
3. Run `openspec archive <id> --yes` so the CLI moves the change and applies spec updates without prompts (use `--skip-specs` only for tooling-only work).
20+
4. Review the command output to confirm the target specs were updated and the change landed in `changes/archive/`.
21+
5. Validate with `openspec validate --strict --no-interactive` and inspect with `openspec show <id>` if anything looks off.
22+
23+
**Reference**
24+
- Use `openspec list` to confirm change IDs before archiving.
25+
- Inspect refreshed specs with `openspec list --specs` and address any validation issues before handing off.
26+
<!-- OPENSPEC:END -->
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
description: Scaffold a new OpenSpec change and validate strictly.
3+
---
4+
5+
$ARGUMENTS
6+
<!-- OPENSPEC:START -->
7+
**Guardrails**
8+
- Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
9+
- Keep changes tightly scoped to the requested outcome.
10+
- Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
11+
- Identify any vague or ambiguous details and ask the necessary follow-up questions before editing files.
12+
- Do not write any code during the proposal stage. Only create design documents (proposal.md, tasks.md, design.md, and spec deltas). Implementation happens in the apply stage after approval.
13+
14+
**Steps**
15+
1. Review `openspec/project.md`, run `openspec list` and `openspec list --specs`, and inspect related code or docs (e.g., via `rg`/`ls`) to ground the proposal in current behaviour; note any gaps that require clarification.
16+
2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, and `design.md` (when needed) under `openspec/changes/<id>/`.
17+
3. Map the change into concrete capabilities or requirements, breaking multi-scope efforts into distinct spec deltas with clear relationships and sequencing.
18+
4. Capture architectural reasoning in `design.md` when the solution spans multiple systems, introduces new patterns, or demands trade-off discussion before committing to specs.
19+
5. Draft spec deltas in `changes/<id>/specs/<capability>/spec.md` (one folder per capability) using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement and cross-reference related capabilities when relevant.
20+
6. Draft `tasks.md` as an ordered list of small, verifiable work items that deliver user-visible progress, include validation (tests, tooling), and highlight dependencies or parallelizable work.
21+
7. Validate with `openspec validate <id> --strict --no-interactive` and resolve every issue before sharing the proposal.
22+
23+
**Reference**
24+
- Use `openspec show <id> --json --deltas-only` or `openspec show <spec> --type spec` to inspect details when validation fails.
25+
- Search existing requirements with `rg -n "Requirement:|Scenario:" openspec/specs` before writing new ones.
26+
- Explore the codebase with `rg <keyword>`, `ls`, or direct file reads so proposals align with current implementation realities.
27+
<!-- OPENSPEC:END -->

.github/workflows/ci.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- develop
8+
- main
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
18+
- name: Setup Dart
19+
uses: dart-lang/setup-dart@v1
20+
21+
- name: Install workspace deps
22+
run: dart pub get
23+
24+
- name: Activate Melos
25+
run: |
26+
dart pub global activate melos 7.3.0
27+
echo "$HOME/.pub-cache/bin" >> "$GITHUB_PATH"
28+
29+
- name: Bootstrap
30+
run: melos bootstrap
31+
32+
- name: Analyze
33+
run: melos run analyze --no-select
34+
35+
- name: Format Check
36+
run: melos run format:check --no-select
37+
38+
- name: Test
39+
run: melos run test --no-select

.github/workflows/publish.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Publish
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
tags:
7+
- "v*.*.*"
8+
9+
concurrency:
10+
group: publish-${{ github.ref }}
11+
cancel-in-progress: false
12+
13+
jobs:
14+
publish:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Setup Dart
24+
uses: dart-lang/setup-dart@v1
25+
26+
- name: Install workspace deps
27+
run: dart pub get
28+
29+
- name: Activate Melos
30+
run: |
31+
dart pub global activate melos 7.3.0
32+
echo "$HOME/.pub-cache/bin" >> "$GITHUB_PATH"
33+
34+
- name: Bootstrap
35+
run: melos bootstrap
36+
37+
- name: Analyze
38+
run: melos run analyze --no-select
39+
40+
- name: Test
41+
run: melos run test --no-select
42+
43+
- name: Configure pub.dev credentials
44+
env:
45+
PUB_CREDENTIALS: ${{ secrets.PUB_CREDENTIALS }}
46+
run: |
47+
test -n "$PUB_CREDENTIALS"
48+
mkdir -p "$HOME/.config/dart"
49+
printf '%s' "$PUB_CREDENTIALS" > "$HOME/.config/dart/pub-credentials.json"
50+
51+
- name: Copy root CHANGELOG into all packages
52+
run: |
53+
for dir in packages/*; do
54+
if [ -d "$dir" ] && [ -f "$dir/pubspec.yaml" ]; then
55+
cp CHANGELOG.md "$dir/CHANGELOG.md"
56+
fi
57+
done
58+
59+
- name: Publish packages
60+
run: melos publish --no-private --no-dry-run --yes

.gitignore

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Dart/Flutter
2+
.dart_tool/
3+
.packages
4+
build/
5+
pubspec.lock
6+
7+
# Coverage
8+
coverage/
9+
10+
# IDE
11+
.idea/
12+
*.iml
13+
.vscode/
14+
15+
# OS
16+
.DS_Store
17+
Thumbs.db
18+
19+
# Melos
20+
.melos_tool/
21+
22+
# Generated
23+
*.g.dart
24+
*.freezed.dart
25+
26+
# Local environment
27+
.env
28+
.env.local

AGENTS.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!-- OPENSPEC:START -->
2+
# OpenSpec Instructions
3+
4+
These instructions are for AI assistants working in this project.
5+
6+
Always open `@/openspec/AGENTS.md` when the request:
7+
- Mentions planning or proposals (words like proposal, spec, change, plan)
8+
- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
9+
- Sounds ambiguous and you need the authoritative spec before coding
10+
11+
Use `@/openspec/AGENTS.md` to learn:
12+
- How to create and apply change proposals
13+
- Spec format and conventions
14+
- Project structure and guidelines
15+
16+
Keep this managed block so 'openspec update' can refresh the instructions.
17+
18+
<!-- OPENSPEC:END -->

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
### Added
11+
12+
- Initial release of the loom worker pool framework
13+
- `WorkerPool` with configurable worker count and execution modes
14+
- `Task<I, O>` for defining typed, reusable work units
15+
- Priority-based job scheduling (`Priority.low`, `normal`, `high`, `critical`)
16+
- Retry policies: `none`, `fixed`, `exponentialBackoff`, `linear`
17+
- Cancellation support via `CancellationToken` and `CancellationTokenSource`
18+
- Progress reporting through `TaskContext.reportProgress`
19+
- Lifecycle hooks: `onJobStart`, `onJobSuccess`, `onJobFailure`, `onRetry`, `onPoolIdle`, `onPoolShutdown`
20+
- Multiple execution backends: `MainIsolateBackend`, `IsolatePoolBackend`, `TestBackend`
21+
- `JobResult<O>` sealed class with `JobSuccess` and `JobFailure` variants
22+
- `JobHandle<O>` for tracking job status, progress, and cancellation
23+
- `Loom` singleton for global default pool access
24+
- Queue overflow strategies: `reject`, `dropOldest`, `dropNewest`
25+
- Graceful and force shutdown support
26+
- Comprehensive test suite (200 tests)
27+
- Performance benchmarks

README.md

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,101 @@
1-
# loom
1+
# Loom
2+
3+
A lightweight, flexible worker pool framework for Dart applications.
4+
5+
## Overview
6+
7+
Loom provides a robust foundation for managing concurrent task execution with:
8+
9+
- **Priority-based scheduling** - Critical tasks run first
10+
- **Automatic retry** - Configurable retry policies with backoff
11+
- **Graceful cancellation** - Cancel queued or running jobs
12+
- **Progress reporting** - Real-time progress streams
13+
- **Multiple execution modes** - Main isolate, background isolates, or test mode
14+
- **Lifecycle hooks** - Monitor pool activity
15+
16+
## Packages
17+
18+
| Package | Description |
19+
|---------|-------------|
20+
| [loom](packages/loom/) | Core worker pool framework |
21+
22+
## Getting Started
23+
24+
### Prerequisites
25+
26+
- Dart SDK ^3.10.7
27+
- [Melos](https://melos.invertase.dev/) for monorepo management
28+
29+
### Setup
30+
31+
```bash
32+
# Install melos globally
33+
dart pub global activate melos
34+
35+
# Bootstrap the workspace
36+
melos bootstrap
37+
```
38+
39+
### Common Commands
40+
41+
```bash
42+
# Run all tests
43+
melos run test
44+
45+
# Run analyzer
46+
melos run analyze
47+
48+
# Format code
49+
melos run format
50+
51+
# Run all checks (analyze + format + test)
52+
melos run check
53+
54+
# Run performance tests
55+
melos run test:perf
56+
57+
# Run example
58+
melos run run:example
59+
```
60+
61+
## Quick Example
62+
63+
```dart
64+
import 'package:loom/loom.dart';
65+
66+
void main() async {
67+
// Define a task
68+
final task = Task<String, int>.simple(
69+
name: 'parseNumber',
70+
executor: (input, ctx) async => int.parse(input),
71+
);
72+
73+
// Create a pool
74+
final pool = WorkerPool.io('my-pool');
75+
76+
// Submit work
77+
final handle = pool.submit(task, '42');
78+
final result = await handle.result;
79+
80+
print('Parsed: ${result.valueOrThrow}'); // 42
81+
82+
await pool.shutdown();
83+
}
84+
```
85+
86+
## Documentation
87+
88+
- [Loom Package README](packages/loom/README.md)
89+
- [API Documentation](packages/loom/doc/)
90+
91+
## Contributing
92+
93+
1. Fork the repository
94+
2. Create a feature branch
95+
3. Make your changes
96+
4. Run `melos run check` to verify
97+
5. Submit a pull request
98+
99+
## License
100+
101+
See [LICENSE](LICENSE) for details.

0 commit comments

Comments
 (0)