Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ updates:
- package-ecosystem: npm
directory: "/"
schedule:
interval: weekly
interval: monthly
target-branch: "develop"
open-pull-requests-limit: 5
groups:
Expand All @@ -19,7 +19,23 @@ updates:
- package-ecosystem: gradle
directory: "/"
schedule:
interval: weekly
interval: monthly
target-branch: "develop"
open-pull-requests-limit: 5
groups:
minor-and-patch:
update-types:
- minor
- patch
ignore:
- dependency-name: "*"
update-types:
- "version-update:semver-major"

- package-ecosystem: pub
directory: "/packages/core/flutter"
schedule:
interval: monthly
target-branch: "develop"
open-pull-requests-limit: 5
groups:
Expand Down
31 changes: 31 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Code of Conduct

## Our Pledge

We as contributors and maintainers pledge to make participation in KompKit a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

## Our Standards

**Positive behavior includes:**
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members

**Unacceptable behavior includes:**
- The use of sexualized language or imagery
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening a [GitHub issue](https://github.com/Kompkit/KompKit/issues) or contacting the maintainers directly via GitHub.

All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1.
60 changes: 55 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# KompKit

[![Version](https://img.shields.io/badge/version-0.1.0--alpha-orange.svg)](https://github.com/Kompkit/KompKit/releases)
[![Version](https://img.shields.io/badge/version-0.3.0--alpha.0-orange.svg)](https://github.com/Kompkit/KompKit/releases)
[![Web CI](https://github.com/Kompkit/KompKit/actions/workflows/web.yml/badge.svg?branch=develop)](https://github.com/Kompkit/KompKit/actions/workflows/web.yml)
[![Kotlin CI](https://github.com/Kompkit/KompKit/actions/workflows/android.yml/badge.svg?branch=develop)](https://github.com/Kompkit/KompKit/actions/workflows/android.yml)
[![Flutter CI](https://github.com/Kompkit/KompKit/actions/workflows/flutter.yml/badge.svg?branch=develop)](https://github.com/Kompkit/KompKit/actions/workflows/flutter.yml)
Expand All @@ -9,9 +9,37 @@
[![Kotlin](https://img.shields.io/badge/Kotlin-0095D5?logo=kotlin&logoColor=white)](https://kotlinlang.org/)
[![Dart](https://img.shields.io/badge/Dart-0175C2?logo=dart&logoColor=white)](https://dart.dev/)

> **⚠️ Alpha Release**: This is an early alpha version. APIs may change before stable release.
> **⚠️ Alpha Release**: This is an early alpha version. APIs may change before stable release. See [Stability Policy](#stability-policy) below.

A lightweight cross-platform utility kit providing essential functions for Web (TypeScript), Android (Kotlin), and Flutter (Dart) development. Built as a monorepo with identical APIs across platforms.
A lightweight cross-platform utility kit providing essential functions for Web (TypeScript), Android (Kotlin), and Flutter (Dart) development. Built as a monorepo with conceptual API parity across platforms.

## Why KompKit?

Most utility libraries are platform-specific. When you build a product across Web, Android, and Flutter, you end up with three different utility ecosystems, three different mental models, and three different sets of edge-case behaviors.

KompKit solves this by providing the same utilities — with the same names, the same defaults, and the same behavioral semantics — across all three platforms. You learn the API once. You use it everywhere.

**What it is:**

- A small, focused set of production-safe utility functions
- Conceptually identical across TypeScript, Kotlin, and Dart
- Idiomatic per platform — no forced unnatural APIs
- Minimal dependencies, no runtime bloat

**What it is not:**

- A replacement for lodash, Kotlin stdlib, or Dart's core libraries
- A UI component library
- A framework or abstraction layer

## Target Audience

KompKit is for teams and developers who:

- Build products across **multiple platforms simultaneously** (e.g., a web app + Android app + Flutter app)
- Want **consistent utility behavior** without maintaining separate implementations per platform
- Value **minimal dependencies** and **predictable APIs**
- Are comfortable with alpha software and want to shape the API before 1.0

## Overview

Expand Down Expand Up @@ -67,7 +95,7 @@ Add to your `pubspec.yaml`:

```yaml
dependencies:
kompkit_core: ^0.2.0-alpha.0
kompkit_core: ^0.3.0-alpha.0
```

Then run:
Expand Down Expand Up @@ -183,7 +211,7 @@ KompKit/

## Version Information

- **Current Version**: `0.2.0-alpha`
- **Current Version**: `0.3.0-alpha`
- **Minimum Requirements**:
- Node.js 20+ (Web)
- JDK 17+ (Android)
Expand All @@ -192,6 +220,28 @@ KompKit/
- Kotlin 2.3+
- Dart 3.0+

## Stability Policy

KompKit is currently in **alpha**. This means:

- **APIs may change** between alpha versions without a deprecation period.
- **Pin to exact versions** in production: `"kompkit-core": "0.3.0-alpha.0"` / `kompkit_core: 0.3.0-alpha.0`.
- **Breaking changes** will be documented in [CHANGELOG.md](./docs/CHANGELOG.md) with migration notes.
- Once `1.0.0` is released, the project will follow strict [Semantic Versioning](https://semver.org/): breaking changes only in major versions.

## Platform Differences

KompKit aims for **conceptual parity**, not syntactic identity. The following differences are intentional and documented:

| Utility | Platform | Difference | Reason |
| ---------------- | -------- | -------------------------------------------------------------- | ----------------------------------------------------------- |
| `debounce` | Kotlin | Requires `CoroutineScope` parameter | Structured concurrency — no global timer API on JVM |
| `debounce` | Kotlin | Action is first parameter, scope is last | Enables idiomatic trailing lambda syntax |
| `formatCurrency` | Kotlin | Accepts `String` locale, converts to `Locale` internally | JVM `NumberFormat` requires `java.util.Locale` |
| `formatCurrency` | Dart | Accepts BCP 47 locale, normalizes hyphen→underscore internally | `intl` package uses underscore-separated locale identifiers |

All platforms accept BCP 47 locale strings (e.g., `"en-US"`). All platforms throw on invalid `currency` or `locale` inputs.

## Contributing

We welcome contributions! Please see our [Contributing Guide](./docs/CONTRIBUTING.md) for details on:
Expand Down
36 changes: 36 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Security Policy

## Supported Versions

| Version | Supported |
| --------------- | ---------------------- |
| `0.3.0-alpha.0` | ✅ Current |
| `0.2.0-alpha.0` | ❌ No longer supported |
| `0.1.0-alpha` | ❌ No longer supported |

## Reporting a Vulnerability

**Do not open a public GitHub issue for security vulnerabilities.**

Please report security vulnerabilities by emailing the maintainers via a [GitHub Security Advisory](https://github.com/Kompkit/KompKit/security/advisories/new).

Include:

- A description of the vulnerability
- Steps to reproduce
- Potential impact
- Any suggested fix (optional)

We will acknowledge receipt within 48 hours and aim to provide a fix or mitigation within 14 days for confirmed vulnerabilities.

## Scope

KompKit Core is a utility library with no network access, no file system access, and no external runtime dependencies (Web/Android). The attack surface is limited to:

- Input validation logic (`isEmail`) — regex denial-of-service (ReDoS) is in scope
- Dependency vulnerabilities in `intl` (Dart) or `kotlinx-coroutines` (Kotlin)

## Out of Scope

- Vulnerabilities in development-only dependencies (test runners, build tools)
- Issues in generated documentation
99 changes: 80 additions & 19 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,66 +46,127 @@ All modules implement identical functionality:
- **isEmail**: Email validation using regex patterns
- **formatCurrency**: Localized currency formatting

## API Parity Contract

This section defines the formal contract for cross-platform API consistency in KompKit.

### What is Guaranteed

- **Function names** are identical across all platforms (`debounce`, `isEmail`, `formatCurrency`).
- **Behavioral semantics** are identical: given the same inputs, all platforms produce the same observable output.
- **Default values** are identical: `wait = 250ms`, `currency = "EUR"`, `locale = "en-US"`.
- **Error handling philosophy** is consistent: invalid inputs that cannot produce a meaningful result throw/throw-equivalent errors. Silent fallbacks are not permitted.
- **Cancel capability**: `debounce` returns an object with a `cancel()` method on all platforms, allowing callers to discard pending executions (required for safe use in component lifecycles).

### What May Differ

- **Parameter style**: Named parameters (Dart), trailing lambdas (Kotlin), and positional parameters (TypeScript) are idiomatic per language and are not forced to match syntactically.
- **Coroutine scope (Kotlin)**: `debounce` requires a `CoroutineScope` because Kotlin's async model mandates structured concurrency. This is a platform constraint, not an API inconsistency. The scope is the last parameter to allow trailing lambda syntax.
- **Type system expression**: Dart uses `void Function(T)` return types, Kotlin uses `(T) -> Unit`, TypeScript uses a typed wrapper object. All three express the same concept.
- **Locale string format**: All platforms accept BCP 47 locale strings (e.g., `"en-US"`). Kotlin converts internally to `java.util.Locale` as required by the JVM.

### Conceptual Mental Model

Every utility follows the same mental model regardless of platform:

```
debounce(action, options) → Debounced<T> (with .cancel())
isEmail(value) → Boolean
formatCurrency(amount, options) → String
```

A developer familiar with the TypeScript API should be able to use the Kotlin or Dart API with only idiomatic adjustments — not conceptual re-learning.

### Platform Divergence Documentation

Any unavoidable divergence between platforms must be:

1. Documented in this section.
2. Explained with the platform constraint that necessitates it.
3. Kept minimal — divergence is a cost, not a feature.

**Current documented divergences:**

| Function | Divergence | Reason |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `debounce` | Kotlin requires `CoroutineScope` parameter | Structured concurrency — no global timer API |
| `debounce` | Kotlin uses trailing lambda for `action` | Idiomatic Kotlin; improves call-site readability |
| `formatCurrency` | Kotlin accepts `String` locale, converts to `Locale` internally | JVM `NumberFormat` API requires `java.util.Locale` |
| `formatCurrency` | TypeScript (V8) and Kotlin (JVM) fall back on unknown locales; Dart throws | `Intl.NumberFormat` (V8) and `Locale.forLanguageTag` (JVM) are lenient; `intl` (Dart) calls `verifiedLocale()` which throws |
| `formatCurrency` | Dart validates currency format via regex (3 uppercase letters); Kotlin via `Currency.getInstance`; TypeScript via `Intl.NumberFormat` | Platform APIs differ in how they enforce ISO 4217 — all throw on invalid codes |

---

## Implementation Strategy

### API Design

We maintain strict API consistency across platforms:
We maintain conceptual API parity across platforms:

**TypeScript:**

```typescript
export function debounce<T extends (...args: any[]) => any>(
interface Debounced<T extends (...args: any[]) => void> {
(...args: Parameters<T>): void;
cancel(): void;
}

export function debounce<T extends (...args: any[]) => void>(
fn: T,
wait: number = 250,
): T;
wait?: number, // default: 250
): Debounced<T>;

export function isEmail(value: string): boolean;

export function formatCurrency(
amount: number,
currency: string = "EUR",
locale: string = "es-ES",
currency?: string, // default: "EUR"
locale?: string, // default: "en-US"
): string;
```

**Kotlin:**

```kotlin
class Debounced<T>(private val action: (T) -> Unit) {
operator fun invoke(value: T): Unit
fun cancel(): Unit
}

fun <T> debounce(
action: (T) -> Unit,
waitMs: Long = 250L,
scope: CoroutineScope,
dest: (T) -> Unit
): (T) -> Unit
scope: CoroutineScope, // platform constraint: structured concurrency
): Debounced<T>

fun isEmail(value: String): Boolean

fun formatCurrency(
amount: Double,
currency: String = "EUR",
locale: Locale = Locale("es", "ES")
locale: String = "en-US", // converted internally to java.util.Locale
): String
```

**Dart:**

```dart
Function debounce<T>(
Function fn,
[Duration wait = const Duration(milliseconds: 250)]
);
class Debounced<T> {
void call(T arg);
void cancel();
}

VoidCallback debounceVoid(
VoidCallback fn,
[Duration wait = const Duration(milliseconds: 250)]
);
Debounced<T> debounce<T>(
void Function(T) action, [
Duration wait = const Duration(milliseconds: 250),
]);

bool isEmail(String value);

String formatCurrency(
num amount, {
String currency = "EUR",
String locale = "es_ES",
String locale = "en-US",
});
```

Expand Down
4 changes: 2 additions & 2 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.2.0-alpha] - 2026-02-09
## [0.3.0-alpha] - 2026-02-09

### Changed

Expand Down Expand Up @@ -111,7 +111,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Known Limitations

- **Alpha release**: APIs may change before stable 1.0 release
- **Local development only**: Packages not yet published to registries
- **Android not yet published**: Android/Kotlin package is not yet published to Maven; use local project reference
- **Limited utility set**: Only 3 core functions (debounce, isEmail, formatCurrency)

### Migration Notes
Expand Down
6 changes: 4 additions & 2 deletions docs/contributing.md → docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ test(web): add edge cases for email validation
npm run build

# Build web package only
npm run docs:web
npm run build:web

# Build Kotlin package only
cd packages/core/android && ./gradlew assemble
Expand Down Expand Up @@ -169,7 +169,7 @@ When adding a new utility function:

4. **Update exports**:
- Add to `packages/core/web/src/index.ts`
- Add to `packages/core/flutter/src/kompkit_core.dart`
- Add to `packages/core/flutter/lib/kompkit_core.dart`
- Kotlin exports are automatic via package structure

5. **Document with examples**:
Expand Down Expand Up @@ -267,6 +267,8 @@ Releases are managed by maintainers:
- 💬 **Discussions**: [GitHub Discussions](https://github.com/Kompkit/KompKit/discussions)
- 📧 **Maintainers**: Open an issue for direct contact

> See also: [CONTRIBUTING.md](../docs/CONTRIBUTING.md) is auto-linked by GitHub in the PR interface.

## Code of Conduct

This project follows the [Contributor Covenant Code of Conduct](https://www.contributor-covenant.org/). Please be respectful and inclusive in all interactions.
2 changes: 1 addition & 1 deletion docs/android.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

KompKit Core provides small utilities for Android applications written in Kotlin.

Status: `V0.2.0-alpha`.
Status: `V0.3.0-alpha`.

## Installation

Expand Down
Loading
Loading