@leejungkiin/awkit 1.7.4 → 1.7.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.
- package/README.md +42 -5
- package/bin/awk.js +579 -15
- package/core/GEMINI.md +4 -0
- package/core/GEMINI.md.bak +4 -0
- package/core/GreetingEngine/index.js +225 -0
- package/core/GreetingEngine/locales/en.json +6 -0
- package/core/GreetingEngine/locales/ja.json +6 -0
- package/core/GreetingEngine/locales/vi.json +6 -0
- package/core/GreetingEngine/test.js +37 -0
- package/docs/PRD.md +57 -0
- package/docs/brainstorm_multi_agent_cli.md +211 -0
- package/docs/history/PRD.v1.md +55 -0
- package/docs/history/PRD.v2.md +57 -0
- package/docs/history/memoizedfibonacci_spec.v1.md +127 -0
- package/docs/specs/greetingapp_spec.md +97 -0
- package/docs/specs/memoizedfibonacci_spec.md +211 -0
- package/package.json +1 -1
- package/scripts/multi-model-pipeline.js +292 -50
- package/scripts/qwen-exec.js +147 -0
- package/skills/claude-planner/SKILL.md +24 -0
- package/skills/codex-conductor/SKILL.md +25 -1
- package/skills/qwen-conductor/SKILL.md +100 -0
- package/workflows/multi-agent-pipeline.md +52 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Product Requirement Document (PRD) - GreetingApp
|
|
2
|
+
|
|
3
|
+
## Revision History
|
|
4
|
+
| Version | Date | Description | Author |
|
|
5
|
+
|---|---|---|---|
|
|
6
|
+
| v1.0 | 2026-06-22 | Initial PRD for GreetingApp | Antigravity Orchestrator |
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 1. Executive Summary
|
|
11
|
+
GreetingApp is a micro-application designed to deliver personalized, localized, and dynamic greetings to users. It adapts to the user's name, current time of day, and language preferences.
|
|
12
|
+
|
|
13
|
+
## 2. Objectives & Goals
|
|
14
|
+
- Provide dynamic greetings based on user local time (Morning, Afternoon, Evening, Night).
|
|
15
|
+
- Support multi-language greetings (English, Vietnamese, Japanese).
|
|
16
|
+
- Track user greeting history and statistics.
|
|
17
|
+
- Expose both CLI and REST API interfaces.
|
|
18
|
+
|
|
19
|
+
## 3. User Personas & Use Cases
|
|
20
|
+
- **End User:** Wants to see a welcoming, contextual message when logging in or using the CLI.
|
|
21
|
+
- **Developer:** Wants an easy-to-integrate greeting microservice API for downstream services.
|
|
22
|
+
|
|
23
|
+
## 4. Functional Requirements
|
|
24
|
+
1. **Dynamic Greeting Generation:**
|
|
25
|
+
- Detects local time of user.
|
|
26
|
+
- Personalizes with name (fallback to "Guest").
|
|
27
|
+
2. **Localization (i18n):**
|
|
28
|
+
- Supports: English (`en`), Vietnamese (`vi`), Japanese (`ja`).
|
|
29
|
+
3. **Greeting Analytics / History:**
|
|
30
|
+
- Stores logs of generated greetings (User, Timestamp, Language).
|
|
31
|
+
- Exposes statistics (e.g., total greetings generated, most active user).
|
|
32
|
+
4. **Interfaces:**
|
|
33
|
+
- Command Line Interface (CLI): `awkit greet --name=Alice`
|
|
34
|
+
- REST API endpoint: `GET /api/greet?name=Alice&lang=vi`
|
|
35
|
+
|
|
36
|
+
## 5. Non-Functional Requirements
|
|
37
|
+
- **Performance:** Response time for greeting generation under 50ms.
|
|
38
|
+
- **Reliability:** Storage fallback to memory if database/file storage is offline.
|
|
39
|
+
- **Extensibility:** Easy configuration to add new languages.
|
|
40
|
+
|
|
41
|
+
## 6. System Flow & Sequence Diagram
|
|
42
|
+
```mermaid
|
|
43
|
+
sequenceDiagram
|
|
44
|
+
autonumber
|
|
45
|
+
actor User
|
|
46
|
+
participant Client as CLI / API Client
|
|
47
|
+
participant Engine as Greeting Engine
|
|
48
|
+
participant DB as Storage / History DB
|
|
49
|
+
|
|
50
|
+
User->>Client: Triggers greeting command/request (name, lang)
|
|
51
|
+
Client->>Engine: Resolve greeting configuration
|
|
52
|
+
Engine->>Engine: Validate input & detect Time of Day
|
|
53
|
+
Engine->>DB: Log transaction (user, time, format)
|
|
54
|
+
DB-->>Engine: Log confirmation
|
|
55
|
+
Engine->>Client: Return formatted greeting string
|
|
56
|
+
Client->>User: Display greeting output
|
|
57
|
+
```
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Technical Specification — MemoizedFibonacci
|
|
2
|
+
|
|
3
|
+
## Revision History
|
|
4
|
+
|
|
5
|
+
| Version | Date | Author | Description |
|
|
6
|
+
| :--- | :--- | :--- | :--- |
|
|
7
|
+
| 1.0 | 2026-06-22 | Antigravity Orchestrator | Initial technical design with Mermaid diagram, class architecture, and caching strategy. |
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. System Architecture
|
|
12
|
+
|
|
13
|
+
The `MemoizedFibonacci` feature consists of three primary layers:
|
|
14
|
+
1. **API & Interface Layer:** Exposes synchronous and asynchronous methods to users.
|
|
15
|
+
2. **LRU Cache Layer:** Manages in-memory storage of computed sequences with automatic eviction based on Least Recently Used patterns.
|
|
16
|
+
3. **Computation Engine:** Performs iterative sequence calculations to prevent call stack overflow, handles dynamic upgrading to `BigInt` for large numbers, and schedules asynchronous chunks for heavy inputs.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 2. API Design & Core Interface
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
interface FibonacciConfig {
|
|
24
|
+
maxCacheSize?: number; // Maximum number of entries in the cache (default: 1000)
|
|
25
|
+
useBigInt?: boolean; // Force BigInt computation even for small inputs (default: false)
|
|
26
|
+
asyncThreshold?: number; // Input size to trigger asynchronous execution (default: 50000)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface CacheStats {
|
|
30
|
+
hits: number;
|
|
31
|
+
misses: number;
|
|
32
|
+
size: number;
|
|
33
|
+
evictions: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
class MemoizedFibonacci {
|
|
37
|
+
private cache: Map<number, number | bigint>;
|
|
38
|
+
private lruList: number[]; // Tracks usage order (least recently used at the front)
|
|
39
|
+
private config: Required<FibonacciConfig>;
|
|
40
|
+
private stats: CacheStats;
|
|
41
|
+
|
|
42
|
+
constructor(config?: FibonacciConfig);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Calculates Fibonacci of n. Automatically picks sync/async mode based on threshold.
|
|
46
|
+
*/
|
|
47
|
+
public async calculate(n: number): Promise<number | bigint>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Synchronously calculates Fibonacci of n.
|
|
51
|
+
* Throws warning/error if n is larger than asyncThreshold.
|
|
52
|
+
*/
|
|
53
|
+
public calculateSync(n: number): number | bigint;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Retreives cache usage statistics.
|
|
57
|
+
*/
|
|
58
|
+
public getStats(): CacheStats;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Clears all cache entries and metrics.
|
|
62
|
+
*/
|
|
63
|
+
public clearCache(): void;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Private helper implementing iterative Fibonacci sequence.
|
|
67
|
+
*/
|
|
68
|
+
private computeIterative(n: number, isBigInt: boolean): number | bigint;
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 3. Detailed Logic Flow (Mermaid Diagram)
|
|
75
|
+
|
|
76
|
+
The following diagram illustrates the routing, validation, precision selection, and caching logic:
|
|
77
|
+
|
|
78
|
+
```mermaid
|
|
79
|
+
graph TD
|
|
80
|
+
A[Start: Calculate F(n)] --> B{Validate input n >= 0}
|
|
81
|
+
B -- No --> C[Throw Error: Invalid Input]
|
|
82
|
+
B -- Yes --> D{Check Cache for n}
|
|
83
|
+
D -- Hit (Yes) --> E[Update LRU Order]
|
|
84
|
+
E --> F[Return Cached Value]
|
|
85
|
+
D -- Miss (No) --> G{Check Precision Mode: n > 78 or useBigInt}
|
|
86
|
+
G -- Standard Number (n <= 78) --> H[Compute using standard arithmetic]
|
|
87
|
+
G -- BigInt (n > 78) --> I{Is n >= asyncThreshold?}
|
|
88
|
+
I -- No (Sync BigInt) --> J[Compute iteratively using BigInt]
|
|
89
|
+
I -- Yes (Async BigInt) --> K[Offload computation to worker thread / chunked loop]
|
|
90
|
+
K --> L[Iterate asynchronously without blocking event loop]
|
|
91
|
+
H --> M[Store Result in Cache]
|
|
92
|
+
J --> M
|
|
93
|
+
L --> M
|
|
94
|
+
M --> N{Cache Size > maxCacheSize?}
|
|
95
|
+
N -- Yes --> O[Evict Least Recently Used entry]
|
|
96
|
+
O --> P[Return Computed Result]
|
|
97
|
+
N -- No --> P
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 4. Key Implementation Mechanics
|
|
103
|
+
|
|
104
|
+
### 4.1 LRU Eviction Implementation
|
|
105
|
+
To avoid linear scanning for evictions, the cache is backed by:
|
|
106
|
+
- A `Map` mapping `n` to the value (either `Number` or `BigInt`).
|
|
107
|
+
- A doubly-linked list or ordered array (`lruList`) tracking usage keys. On a cache hit, the key is moved to the end. On a cache insertion, if the map exceeds `maxCacheSize`, the key at the front of `lruList` is deleted from both the list and the map.
|
|
108
|
+
|
|
109
|
+
### 4.2 Precision Safeguards
|
|
110
|
+
- **Standard Float Limits:** Standard numbers in JavaScript lose precision above $F(78)$ ($F(78) = 8944394323791464$, whereas $F(79) = 14472334024559020$ which exceeds `Number.MAX_SAFE_INTEGER`).
|
|
111
|
+
- **Automatic BigInt Upgrade:** If the class configuration is not explicitly set, inputs $n \ge 79$ automatically upgrade execution to `BigInt` mode.
|
|
112
|
+
|
|
113
|
+
### 4.3 Async Slicing / Non-blocking Loop
|
|
114
|
+
For large values of $n$ (e.g. $n \ge 500,000$), calculating Fibonacci in a single synchronous loop blocks the JS single-threaded event loop for several milliseconds. The `MemoizedFibonacci` class handles this via:
|
|
115
|
+
- **Chunked execution:** Splitting the loop into chunks of 10,000 iterations and yielding back control using `setImmediate` or `setTimeout(..., 0)` to allow standard event-loop ticks to execute.
|
|
116
|
+
- Alternatively, utilizing **Worker Threads** via `node:worker_threads` for CPU offloading in Node.js environments.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 5. Error Handling & Edge Cases
|
|
121
|
+
|
|
122
|
+
| Condition | System Response |
|
|
123
|
+
| :--- | :--- |
|
|
124
|
+
| Negative Input ($n < 0$) | Throws `RangeError: Input must be a non-negative integer.` |
|
|
125
|
+
| Floating point Input (e.g., $n = 3.5$) | Automatically truncated using `Math.floor(n)` with a console warning, or throws a `TypeError`. |
|
|
126
|
+
| Out of Memory Risk ($n > 1,000,000$) | Rejects promise with a warning about resource exhaustion unless a `force` flag is set. |
|
|
127
|
+
| Cache Collision (Standard vs BigInt) | Values in cache are stored with consistent type based on configuration to avoid mixed-type arithmetic downstream. |
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Technical Specification - GreetingApp
|
|
2
|
+
|
|
3
|
+
## Revision History
|
|
4
|
+
| Version | Date | Description | Author |
|
|
5
|
+
|---|---|---|---|
|
|
6
|
+
| v1.0 | 2026-06-22 | Technical specification for GreetingApp | Antigravity Orchestrator |
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 1. System Architecture
|
|
11
|
+
The GreetingApp consists of three major components:
|
|
12
|
+
1. **Greeting Engine (Core):** Performs validation, detects time-of-day categories, maps to localization files, and builds the string.
|
|
13
|
+
2. **Storage Layer:** A lightweight JSON/SQLite file logger to record history.
|
|
14
|
+
3. **Interfaces:**
|
|
15
|
+
- CLI Controller: Handles flags and standard output formatting.
|
|
16
|
+
- REST Controller: Express.js routes and JSON responses.
|
|
17
|
+
|
|
18
|
+
## 2. Detailed Component Specs
|
|
19
|
+
|
|
20
|
+
### 2.1 Greeting Engine (`core/GreetingEngine`)
|
|
21
|
+
- **Input:**
|
|
22
|
+
- `name`: string (optional, default: "Guest")
|
|
23
|
+
- `lang`: string (optional, default: "en")
|
|
24
|
+
- `timezone`: string (optional, default: system timezone)
|
|
25
|
+
- **Time Periods:**
|
|
26
|
+
- `Morning`: 05:00 - 11:59
|
|
27
|
+
- `Afternoon`: 12:00 - 17:59
|
|
28
|
+
- `Evening`: 18:00 - 21:59
|
|
29
|
+
- `Night`: 22:00 - 04:59
|
|
30
|
+
- **Localization Files (`locales/*.json`):**
|
|
31
|
+
- Example `en.json`:
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"morning": "Good morning, {name}!",
|
|
35
|
+
"afternoon": "Good afternoon, {name}!",
|
|
36
|
+
"evening": "Good evening, {name}!",
|
|
37
|
+
"night": "Good night, {name}!"
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2.2 Storage Schema
|
|
42
|
+
A SQLite or JSON lines file containing:
|
|
43
|
+
- `id`: UUID / Auto-increment integer
|
|
44
|
+
- `name`: String
|
|
45
|
+
- `language`: String
|
|
46
|
+
- `timestamp`: ISO-8601 string
|
|
47
|
+
- `greeting_message`: String
|
|
48
|
+
|
|
49
|
+
## 3. Interface Design
|
|
50
|
+
|
|
51
|
+
### 3.1 CLI Interface
|
|
52
|
+
`awkit greet [options]`
|
|
53
|
+
- `--name, -n`: Name of the user to greet.
|
|
54
|
+
- `--lang, -l`: Language code (en, vi, ja).
|
|
55
|
+
- `--help, -h`: Show usage description.
|
|
56
|
+
|
|
57
|
+
### 3.2 REST API Specification
|
|
58
|
+
`GET /api/greet`
|
|
59
|
+
- **Query Parameters:**
|
|
60
|
+
- `name` (string)
|
|
61
|
+
- `lang` (string)
|
|
62
|
+
- **Response (200 OK):**
|
|
63
|
+
- Content-Type: `application/json`
|
|
64
|
+
- Body:
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"status": "success",
|
|
68
|
+
"data": {
|
|
69
|
+
"message": "Good morning, Alice!",
|
|
70
|
+
"name": "Alice",
|
|
71
|
+
"lang": "en",
|
|
72
|
+
"timestamp": "2026-06-22T05:35:15Z"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 4. Error Handling
|
|
78
|
+
- **Invalid Language:** Fallback to `en` and log warning.
|
|
79
|
+
- **Invalid Input characters:** Sanitize inputs to prevent command line injection or XSS (on API side).
|
|
80
|
+
|
|
81
|
+
## 5. Flow Diagram
|
|
82
|
+
```mermaid
|
|
83
|
+
graph TD
|
|
84
|
+
A[Start Request] --> B{Validate Inputs}
|
|
85
|
+
B -- Invalid --> C[Use Defaults: Guest/en]
|
|
86
|
+
B -- Valid --> D[Resolve User Local Time]
|
|
87
|
+
C --> D
|
|
88
|
+
D --> E{Determine Time of Day}
|
|
89
|
+
E -->|05:00-11:59| F[Morning Template]
|
|
90
|
+
E -->|12:00-17:59| G[Afternoon Template]
|
|
91
|
+
E -->|18:00-21:59| H[Evening Template]
|
|
92
|
+
E -->|22:00-04:59| I[Night Template]
|
|
93
|
+
F & G & H & I --> J[Replace {name} in Template]
|
|
94
|
+
J --> K[Log Transaction to History DB]
|
|
95
|
+
K --> L[Format Output CLI/REST]
|
|
96
|
+
L --> M[End Request]
|
|
97
|
+
```
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Technical Specification — MemoizedFibonacci
|
|
2
|
+
|
|
3
|
+
## Revision History
|
|
4
|
+
|
|
5
|
+
| Version | Date | Author | Description |
|
|
6
|
+
| :--- | :--- | :--- | :--- |
|
|
7
|
+
| 1.0 | 2026-06-22 | Antigravity Orchestrator | Initial technical design with Mermaid diagram, class architecture, and caching strategy. |
|
|
8
|
+
| 1.1 | 2026-06-22 | Antigravity Orchestrator | Refined LRU caching mechanism using ES6 Map insertion ordering. Added explicit detail on Async Slicing and Testing Strategy. |
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. System Architecture
|
|
13
|
+
|
|
14
|
+
The `MemoizedFibonacci` feature consists of three primary layers:
|
|
15
|
+
1. **API & Interface Layer:** Exposes synchronous and asynchronous methods to users.
|
|
16
|
+
2. **LRU Cache Layer:** Manages in-memory storage of computed sequences with automatic eviction based on Least Recently Used patterns.
|
|
17
|
+
3. **Computation Engine:** Performs iterative sequence calculations to prevent call stack overflow, handles dynamic upgrading to `BigInt` for large numbers, and schedules asynchronous chunks for heavy inputs.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 2. API Design & Core Interface
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
interface FibonacciConfig {
|
|
25
|
+
maxCacheSize?: number; // Maximum number of entries in the cache (default: 1000)
|
|
26
|
+
useBigInt?: boolean; // Force BigInt computation even for small inputs (default: false)
|
|
27
|
+
asyncThreshold?: number; // Input size to trigger asynchronous execution (default: 50000)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface CacheStats {
|
|
31
|
+
hits: number;
|
|
32
|
+
misses: number;
|
|
33
|
+
size: number;
|
|
34
|
+
evictions: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
class MemoizedFibonacci {
|
|
38
|
+
// Built-in ES6 Map maintains insertion order.
|
|
39
|
+
// By deleting and re-inserting a key on access, the most recently used keys move to the end.
|
|
40
|
+
// The first key in map.keys() represents the Least Recently Used (LRU) element.
|
|
41
|
+
private cache: Map<number, number | bigint>;
|
|
42
|
+
private config: Required<FibonacciConfig>;
|
|
43
|
+
private stats: CacheStats;
|
|
44
|
+
|
|
45
|
+
constructor(config?: FibonacciConfig);
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Calculates Fibonacci of n. Automatically picks sync/async mode based on threshold.
|
|
49
|
+
* Returns a Promise resolving to number or bigint.
|
|
50
|
+
*/
|
|
51
|
+
public calculate(n: number): Promise<number | bigint>;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Synchronously calculates Fibonacci of n.
|
|
55
|
+
* Throws RangeError if n exceeds asyncThreshold to protect the thread.
|
|
56
|
+
*/
|
|
57
|
+
public calculateSync(n: number): number | bigint;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Checks if the value for n is currently cached.
|
|
61
|
+
*/
|
|
62
|
+
public isCached(n: number): boolean;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Dynamically updates the cache capacity limit. Evicts items if size exceeds new limit.
|
|
66
|
+
*/
|
|
67
|
+
public setMaxCacheSize(size: number): void;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Retrieves cache usage statistics.
|
|
71
|
+
*/
|
|
72
|
+
public getStats(): CacheStats;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Clears all cache entries and resets statistics.
|
|
76
|
+
*/
|
|
77
|
+
public clearCache(): void;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Internal helper implementing iterative computation.
|
|
81
|
+
*/
|
|
82
|
+
private computeIterative(n: number, isBigInt: boolean): number | bigint;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Internal helper performing non-blocking chunked computation.
|
|
86
|
+
*/
|
|
87
|
+
private computeAsyncChunked(n: number, chunkSize: number): Promise<bigint>;
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 3. Detailed Logic Flow (Mermaid Diagram)
|
|
94
|
+
|
|
95
|
+
The following diagram illustrates the routing, validation, precision selection, and caching logic:
|
|
96
|
+
|
|
97
|
+
```mermaid
|
|
98
|
+
graph TD
|
|
99
|
+
A[Start: Calculate F(n)] --> B{Validate input n >= 0}
|
|
100
|
+
B -- No --> C[Throw RangeError: Invalid Input]
|
|
101
|
+
B -- Yes --> D{Check Cache for n}
|
|
102
|
+
|
|
103
|
+
D -- Hit (Yes) --> E[Update Map Insertion Order: Delete & Re-insert]
|
|
104
|
+
E --> F[Increment Hit Metric]
|
|
105
|
+
F --> G[Return Cached Value]
|
|
106
|
+
|
|
107
|
+
D -- Miss (No) --> H[Increment Miss Metric]
|
|
108
|
+
H --> I{Check Precision Mode: n > 78 or useBigInt}
|
|
109
|
+
|
|
110
|
+
I -- Standard Number (n <= 78) --> J[Compute iteratively using standard Number]
|
|
111
|
+
I -- BigInt (n > 78) --> K{Is n >= asyncThreshold?}
|
|
112
|
+
|
|
113
|
+
K -- No (Sync BigInt) --> L[Compute iteratively using BigInt]
|
|
114
|
+
K -- Yes (Async BigInt) --> M[Invoke computeAsyncChunked]
|
|
115
|
+
|
|
116
|
+
M --> N[Loop in chunks of size 10,000 using setImmediate]
|
|
117
|
+
N --> O[Yield control back to Event Loop after each chunk]
|
|
118
|
+
|
|
119
|
+
J --> P[Store Result in Cache]
|
|
120
|
+
L --> P
|
|
121
|
+
O --> P
|
|
122
|
+
|
|
123
|
+
P --> Q{Cache Size > maxCacheSize?}
|
|
124
|
+
Q -- Yes --> R[Evict map.keys.next.value oldest entry]
|
|
125
|
+
R --> S[Increment Eviction Metric]
|
|
126
|
+
S --> T[Return Computed Result]
|
|
127
|
+
Q -- No --> T
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 4. Key Implementation Mechanics
|
|
133
|
+
|
|
134
|
+
### 4.1 LRU Eviction Implementation (ES6 Map)
|
|
135
|
+
Instead of managing a separate `lruList` array (which incurs $O(N)$ lookup/splice operations), the implementation relies entirely on the ordered property of JavaScript's `Map`.
|
|
136
|
+
* **Read (Cache Hit):**
|
|
137
|
+
```javascript
|
|
138
|
+
const value = this.cache.get(key);
|
|
139
|
+
this.cache.delete(key);
|
|
140
|
+
this.cache.set(key, value); // Re-inserts at the end of the Map
|
|
141
|
+
```
|
|
142
|
+
* **Write (Cache Miss & Capacity Exceeded):**
|
|
143
|
+
```javascript
|
|
144
|
+
this.cache.set(key, value);
|
|
145
|
+
if (this.cache.size > this.config.maxCacheSize) {
|
|
146
|
+
const oldestKey = this.cache.keys().next().value;
|
|
147
|
+
this.cache.delete(oldestKey); // Deletes the oldest insertion
|
|
148
|
+
this.stats.evictions++;
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
This architecture yields highly efficient $O(1)$ operations for both cache lookup and replacement.
|
|
152
|
+
|
|
153
|
+
### 4.2 Precision Safeguards & Double Limits
|
|
154
|
+
- **Standard Float Limits:** Standard numbers in JavaScript lose precision above $F(78)$ ($F(78) = 8944394323791464$, whereas $F(79) = 14472334024559020$ which exceeds `Number.MAX_SAFE_INTEGER`).
|
|
155
|
+
- **Automatic BigInt Upgrade:** If the class configuration is not explicitly set, inputs $n \ge 79$ automatically upgrade execution to `BigInt` mode.
|
|
156
|
+
|
|
157
|
+
### 4.3 Async Slicing / Non-blocking Loop
|
|
158
|
+
For large values of $n$ (e.g. $n \ge 100,000$), calculating Fibonacci in a single synchronous loop blocks the JS single-threaded event loop.
|
|
159
|
+
We employ a chunked calculation pattern:
|
|
160
|
+
```javascript
|
|
161
|
+
private async computeAsyncChunked(n: number, chunkSize: number = 10000): Promise<bigint> {
|
|
162
|
+
let prev = 0n;
|
|
163
|
+
let curr = 1n;
|
|
164
|
+
let i = 2;
|
|
165
|
+
|
|
166
|
+
const runChunk = (): Promise<bigint> => {
|
|
167
|
+
return new Promise((resolve) => {
|
|
168
|
+
setImmediate(() => {
|
|
169
|
+
const target = Math.min(i + chunkSize, n + 1);
|
|
170
|
+
for (; i < target; i++) {
|
|
171
|
+
const next = prev + curr;
|
|
172
|
+
prev = curr;
|
|
173
|
+
curr = next;
|
|
174
|
+
}
|
|
175
|
+
if (i <= n) {
|
|
176
|
+
resolve(runChunk()); // Recursively queue the next chunk
|
|
177
|
+
} else {
|
|
178
|
+
resolve(curr);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
return runChunk();
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 5. Error Handling & Edge Cases
|
|
191
|
+
|
|
192
|
+
| Condition | System Response |
|
|
193
|
+
| :--- | :--- |
|
|
194
|
+
| Negative Input ($n < 0$) | Throws `RangeError: Input must be a non-negative integer.` |
|
|
195
|
+
| Floating point Input (e.g., $n = 3.5$) | Throws `TypeError: Input must be an integer.` |
|
|
196
|
+
| Maximum Guardrail Breach ($n > 1,000,000$) | Throws `RangeError: Calculation size exceeds maximum guardrail of 1,000,000.` |
|
|
197
|
+
| Sync Call beyond Threshold ($n > asyncThreshold$) | Throws `RangeError: Input exceeds asyncThreshold. Use calculate() instead.` |
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## 6. Testing Strategy
|
|
202
|
+
|
|
203
|
+
### 6.1 Unit Tests
|
|
204
|
+
* **Core Calculations:** Verify $F(0) = 0$, $F(1) = 1$, $F(10) = 55$, and $F(78) = 8944394323791464$.
|
|
205
|
+
* **BigInt Accuracy:** Verify $F(79)$ is correctly calculated as `14472334024559020n` (with tailing `n` specifying bigint).
|
|
206
|
+
* **Caching Performance:** Retrieve $F(50)$ twice. The second call must trigger a cache hit and have a latency under 1 microsecond.
|
|
207
|
+
* **LRU Eviction:** Set cache limit to 3. Populate cache with keys 1, 2, 3. Read key 1 (making it most recently used). Insert key 4. Verify key 2 is evicted.
|
|
208
|
+
|
|
209
|
+
### 6.2 Performance & Memory Benchmarks
|
|
210
|
+
* **Sync vs Async Threshold:** Test the threshold boundary. Verify that calling `calculate(49999)` completes synchronously within milliseconds, and `calculate(50001)` returns a Promise and yields event loop control.
|
|
211
|
+
* **Leak Testing:** Execute calculation loop of random values up to $n = 10,000$ for 100,000 iterations. Verify heap memory remains flat (no leakage outside the bounds of `maxCacheSize`).
|