Skip to content

Commit 5026c99

Browse files
Merge pull request #12 from alichherawalla/feat/ci
Feat/ci
2 parents 7eb4c5e + 28934bc commit 5026c99

69 files changed

Lines changed: 543 additions & 455 deletions

File tree

Some content is hidden

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

.eslintrc.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
module.exports = {
22
root: true,
33
extends: '@react-native',
4+
rules: {
5+
'@typescript-eslint/no-unused-vars': [
6+
'error',
7+
{
8+
argsIgnorePattern: '^_',
9+
varsIgnorePattern: '^_',
10+
caughtErrorsIgnorePattern: '^_',
11+
},
12+
],
13+
},
414
};

.github/workflows/ci.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
8+
jobs:
9+
lint:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v4
15+
16+
- name: Setup Node.js
17+
uses: actions/setup-node@v4
18+
with:
19+
node-version: '20'
20+
cache: 'npm'
21+
22+
- name: Install dependencies
23+
run: npm ci
24+
25+
- name: Lint
26+
run: npm run lint
27+
28+
typecheck:
29+
runs-on: ubuntu-latest
30+
31+
steps:
32+
- name: Checkout code
33+
uses: actions/checkout@v4
34+
35+
- name: Setup Node.js
36+
uses: actions/setup-node@v4
37+
with:
38+
node-version: '20'
39+
cache: 'npm'
40+
41+
- name: Install dependencies
42+
run: npm ci
43+
44+
- name: Type check
45+
run: npx tsc --noEmit
46+
47+
test:
48+
runs-on: ubuntu-latest
49+
50+
steps:
51+
- name: Checkout code
52+
uses: actions/checkout@v4
53+
54+
- name: Setup Node.js
55+
uses: actions/setup-node@v4
56+
with:
57+
node-version: '20'
58+
cache: 'npm'
59+
60+
- name: Install dependencies
61+
run: npm ci
62+
63+
- name: Test
64+
run: npm test

App.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler';
1010
import { SafeAreaProvider } from 'react-native-safe-area-context';
1111
import { NavigationContainer } from '@react-navigation/native';
1212
import { AppNavigator } from './src/navigation';
13-
import { useTheme, getTheme } from './src/theme';
13+
import { useTheme } from './src/theme';
1414
import { hardwareService, modelManager, authService } from './src/services';
1515
import { useAppStore, useAuthStore } from './src/stores';
1616
import { LockScreen } from './src/screens';
@@ -51,6 +51,7 @@ function App() {
5151

5252
useEffect(() => {
5353
initializeApp();
54+
// eslint-disable-next-line react-hooks/exhaustive-deps
5455
}, []);
5556

5657
const initializeApp = async () => {

__tests__/contracts/coreMLDiffusion.contract.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* TypeScript bridge (localDreamGenerator.ts) works on both platforms.
77
*/
88

9-
import { NativeModules, NativeEventEmitter } from 'react-native';
9+
export {};
1010

1111
// The CoreMLDiffusionModule must expose the same methods as LocalDreamModule
1212
interface CoreMLDiffusionModuleInterface {

__tests__/contracts/iosDownloadManager.contract.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
* so that backgroundDownloadService.ts works on both platforms unchanged.
99
*/
1010

11-
import { NativeModules, NativeEventEmitter } from 'react-native';
1211

1312
// The iOS module must match this interface (same as Android)
1413
interface DownloadManagerModuleInterface {

__tests__/contracts/llamaContext.contract.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ describe('llama.rn Contract', () => {
2929
use_mmap: true,
3030
vocab_only: false,
3131
flash_attn: true,
32-
cache_type_k: 'f16',
33-
cache_type_v: 'f16',
32+
cache_type_k: 'f16' as const,
33+
cache_type_v: 'f16' as const,
3434
n_ctx: 4096,
3535
n_gpu_layers: 99,
3636
};
@@ -62,7 +62,7 @@ describe('llama.rn Contract', () => {
6262
gpu: true,
6363
reasonNoGPU: '',
6464
devices: ['Apple M1'],
65-
model: { metadata: { 'general.name': 'test-model' } },
65+
model: { metadata: { 'general.name': 'test-model' } } as any,
6666
androidLib: undefined,
6767
systemInfo: 'Apple M1 Pro',
6868
completion: jest.fn(),

__tests__/contracts/localDream.contract.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* matches our TypeScript expectations for image generation.
66
*/
77

8-
import { NativeModules, NativeEventEmitter } from 'react-native';
8+
export {};
99

1010
// Define the expected interface
1111
interface LocalDreamModuleInterface {
@@ -214,7 +214,7 @@ describe('LocalDream Contract', () => {
214214
};
215215
(mockLocalDreamModule.generateImage as jest.Mock).mockResolvedValue(mockResult);
216216

217-
const result = await mockLocalDreamModule.generateImage(validGenerateParams);
217+
await mockLocalDreamModule.generateImage(validGenerateParams);
218218

219219
expect(mockLocalDreamModule.generateImage).toHaveBeenCalledWith(
220220
expect.objectContaining({

__tests__/integration/generation/generationFlow.test.ts

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
* not just that they work in isolation.
1010
*/
1111

12-
import { useChatStore } from '../../../src/stores/chatStore';
1312
import { useAppStore } from '../../../src/stores/appStore';
1413
import { generationService } from '../../../src/services/generationService';
1514
import { llmService } from '../../../src/services/llm';
@@ -70,8 +69,8 @@ describe('Generation Flow Integration', () => {
7069
const conversationId = setupWithConversation({ modelId });
7170

7271
const tokens = ['Hello', ' ', 'world', '!'];
73-
let streamCallback: ((token: string) => void) | null = null;
74-
let completeCallback: (() => void) | null = null;
72+
let streamCallback: any = null;
73+
let completeCallback: any = null;
7574

7675
mockLlmService.generateResponse.mockImplementation(
7776
async (_messages, onStream, onComplete, _onError, _onThinking) => {
@@ -102,7 +101,7 @@ describe('Generation Flow Integration', () => {
102101
expect(generationService.getState().streamingContent).toBe('Hello world!');
103102

104103
// Complete generation
105-
completeCallback?.();
104+
completeCallback?.('');
106105
await generatePromise;
107106

108107
// Verify state reset
@@ -114,8 +113,8 @@ describe('Generation Flow Integration', () => {
114113
const modelId = setupWithActiveModel();
115114
const conversationId = setupWithConversation({ modelId });
116115

117-
let streamCallback: ((token: string) => void) | null = null;
118-
let completeCallback: (() => void) | null = null;
116+
let streamCallback: any = null;
117+
let completeCallback: any = null;
119118

120119
mockLlmService.generateResponse.mockImplementation(
121120
async (_messages, onStream, onComplete, _onError, _onThinking) => {
@@ -141,16 +140,16 @@ describe('Generation Flow Integration', () => {
141140
await flushPromises();
142141
expect(onFirstToken).toHaveBeenCalledTimes(1);
143142

144-
completeCallback?.();
143+
completeCallback?.('');
145144
await generatePromise;
146145
});
147146

148147
it('should transition isThinking from true to false on first token', async () => {
149148
const modelId = setupWithActiveModel();
150149
const conversationId = setupWithConversation({ modelId });
151150

152-
let streamCallback: ((token: string) => void) | null = null;
153-
let completeCallback: (() => void) | null = null;
151+
let streamCallback: any = null;
152+
let completeCallback: any = null;
154153

155154
mockLlmService.generateResponse.mockImplementation(
156155
async (_messages, onStream, onComplete, _onError, _onThinking) => {
@@ -173,7 +172,7 @@ describe('Generation Flow Integration', () => {
173172
await flushPromises();
174173
expect(generationService.getState().isThinking).toBe(false);
175174

176-
completeCallback?.();
175+
completeCallback?.('');
177176
await generatePromise;
178177
});
179178
});
@@ -183,7 +182,7 @@ describe('Generation Flow Integration', () => {
183182
const modelId = setupWithActiveModel();
184183
const conversationId = setupWithConversation({ modelId });
185184

186-
let completeCallback: (() => void) | null = null;
185+
let completeCallback: any = null;
187186

188187
mockLlmService.generateResponse.mockImplementation(
189188
async (_messages, _onStream, onComplete, _onError, _onThinking) => {
@@ -202,16 +201,16 @@ describe('Generation Flow Integration', () => {
202201
expect(chatState.streamingForConversationId).toBe(conversationId);
203202
expect(chatState.isThinking).toBe(true);
204203

205-
completeCallback?.();
204+
completeCallback?.('');
206205
await generatePromise;
207206
});
208207

209208
it('should append tokens to chatStore streamingMessage', async () => {
210209
const modelId = setupWithActiveModel();
211210
const conversationId = setupWithConversation({ modelId });
212211

213-
let streamCallback: ((token: string) => void) | null = null;
214-
let completeCallback: (() => void) | null = null;
212+
let streamCallback: any = null;
213+
let completeCallback: any = null;
215214

216215
mockLlmService.generateResponse.mockImplementation(
217216
async (_messages, onStream, onComplete, _onError, _onThinking) => {
@@ -235,7 +234,7 @@ describe('Generation Flow Integration', () => {
235234
await flushPromises();
236235
expect(getChatState().streamingMessage).toBe('Hello world');
237236

238-
completeCallback?.();
237+
completeCallback?.('');
239238
await generatePromise;
240239
});
241240

@@ -250,8 +249,8 @@ describe('Generation Flow Integration', () => {
250249
activeModelId: modelId,
251250
});
252251

253-
let streamCallback: ((token: string) => void) | null = null;
254-
let completeCallback: (() => void) | null = null;
252+
let streamCallback: any = null;
253+
let completeCallback: any = null;
255254

256255
mockLlmService.generateResponse.mockImplementation(
257256
async (_messages, onStream, onComplete, _onError, _onThinking) => {
@@ -271,7 +270,7 @@ describe('Generation Flow Integration', () => {
271270
await flushPromises();
272271

273272
// Complete generation
274-
completeCallback?.();
273+
completeCallback?.('');
275274
await generatePromise;
276275

277276
// Verify message was finalized
@@ -312,8 +311,8 @@ describe('Generation Flow Integration', () => {
312311
lastTokenCount: 75,
313312
});
314313

315-
let streamCallback: ((token: string) => void) | null = null;
316-
let completeCallback: (() => void) | null = null;
314+
let streamCallback: any = null;
315+
let completeCallback: any = null;
317316

318317
mockLlmService.generateResponse.mockImplementation(
319318
async (_messages, onStream, onComplete, _onError, _onThinking) => {
@@ -329,7 +328,7 @@ describe('Generation Flow Integration', () => {
329328
await flushPromises();
330329
streamCallback?.('Response');
331330
await flushPromises();
332-
completeCallback?.();
331+
completeCallback?.('');
333332
await generatePromise;
334333

335334
const chatState = getChatState();
@@ -347,11 +346,11 @@ describe('Generation Flow Integration', () => {
347346
const modelId = setupWithActiveModel();
348347
const conversationId = setupWithConversation({ modelId });
349348

350-
let errorCallback: ((error: Error) => void) | null = null;
349+
let _errorCallback: any = null;
351350

352351
mockLlmService.generateResponse.mockImplementation(
353352
async (_messages, _onStream, _onComplete, onError, _onThinking) => {
354-
errorCallback = onError!;
353+
_errorCallback = onError!;
355354
throw new Error('Generation failed');
356355
}
357356
);
@@ -429,7 +428,7 @@ describe('Generation Flow Integration', () => {
429428
const modelId = setupWithActiveModel();
430429
const conversationId = setupWithConversation({ modelId });
431430

432-
let streamCallback: ((token: string) => void) | null = null;
431+
let streamCallback: any = null;
433432

434433
mockLlmService.generateResponse.mockImplementation(
435434
async (_messages, onStream, _onComplete, _onError, _onThinking) => {
@@ -478,7 +477,7 @@ describe('Generation Flow Integration', () => {
478477
activeModelId: modelId,
479478
});
480479

481-
let streamCallback: ((token: string) => void) | null = null;
480+
let streamCallback: any = null;
482481

483482
mockLlmService.generateResponse.mockImplementation(
484483
async (_messages, onStream, _onComplete, _onError, _onThinking) => {
@@ -536,8 +535,8 @@ describe('Generation Flow Integration', () => {
536535
const modelId = setupWithActiveModel();
537536
const conversationId = setupWithConversation({ modelId });
538537

539-
let streamCallback: ((token: string) => void) | null = null;
540-
let completeCallback: (() => void) | null = null;
538+
let streamCallback: any = null;
539+
let completeCallback: any = null;
541540

542541
mockLlmService.generateResponse.mockImplementation(
543542
async (_messages, onStream, onComplete, _onError, _onThinking) => {
@@ -557,7 +556,7 @@ describe('Generation Flow Integration', () => {
557556
await flushPromises();
558557
streamCallback?.('Token');
559558
await flushPromises();
560-
completeCallback?.();
559+
completeCallback?.('');
561560
await generatePromise;
562561

563562
unsubscribe();
@@ -566,15 +565,15 @@ describe('Generation Flow Integration', () => {
566565
expect(values.length).toBeGreaterThan(1);
567566

568567
// First update after initial state should show generating
569-
const generatingState = values.find(v => v.isGenerating);
568+
const generatingState = values.find((v: any) => v.isGenerating);
570569
expect(generatingState).toBeDefined();
571570

572571
// Should have a state with content
573-
const contentState = values.find(v => v.streamingContent === 'Token');
572+
const contentState = values.find((v: any) => v.streamingContent === 'Token');
574573
expect(contentState).toBeDefined();
575574

576575
// Last state should be idle
577-
const lastState = values[values.length - 1];
576+
const lastState: any = values[values.length - 1];
578577
expect(lastState.isGenerating).toBe(false);
579578
});
580579
});

0 commit comments

Comments
 (0)