Skip to content

Commit f4087d6

Browse files
committed
refactor: consolidate dataSource and client initialization in App component and remove obsolete dataSource file
1 parent b8f92c3 commit f4087d6

7 files changed

Lines changed: 417 additions & 62 deletions

File tree

examples/crm-app/src/App.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ import { registerLayout } from '@object-ui/layout';
77
import '@object-ui/plugin-dashboard';
88
import { ObjectForm } from '@object-ui/plugin-form';
99
import { ObjectGrid } from '@object-ui/plugin-grid';
10-
import { dataSource } from './config/dataSource';
1110
import { registerPlaceholders } from '@object-ui/components';
1211
import { SidebarNav } from './components/SidebarNav';
13-
import { client } from './client';
12+
import { client, dataSource } from './client';
1413

1514
// Schemas
1615
import { dashboardSchema } from './schemas/dashboard';

examples/crm-app/src/client.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
import { ObjectStackClient } from '@objectstack/client';
2+
import { ObjectStackAdapter } from '@object-ui/data-objectstack';
3+
4+
// Use empty string to use current origin.
5+
// Matches MSW baseUrl: ''
6+
const BASE_URL = '/api/v1';
27

38
export const client = new ObjectStackClient({
4-
baseUrl: '/api/v1',
9+
baseUrl: BASE_URL,
10+
fetch: globalThis.fetch.bind(globalThis)
11+
});
12+
13+
export const dataSource = new ObjectStackAdapter({
14+
baseUrl: BASE_URL,
15+
token: 'mock-token',
516
fetch: globalThis.fetch.bind(globalThis)
617
});
718

819
export const initClient = async () => {
20+
console.log('[Client] Connecting...');
21+
// Only connect client (adapter connects lazily or we can connect it too)
922
await client.connect();
10-
console.log('[Client] Connected to ObjectStack');
11-
}
23+
// await dataSource.connect(); // Adapter usually auto-connects on request
24+
console.log('[Client] Connected');
25+
}

examples/crm-app/src/config/dataSource.ts

Lines changed: 0 additions & 8 deletions
This file was deleted.

examples/crm-app/src/main.tsx

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,29 @@ import './index.css';
66
import { startMockServer } from './mocks/browser';
77
import { initClient } from './client';
88

9-
async function enableMocking() {
10-
if (process.env.NODE_ENV !== 'development') {
11-
return;
9+
async function bootstrap() {
10+
// 1. Start MSW Mock Server (Critical: Must be first)
11+
if (process.env.NODE_ENV === 'development') {
12+
console.log('🛑 Bootstrapping Mock Server...');
13+
await startMockServer();
1214
}
13-
await startMockServer();
14-
await initClient(); // Ensure client is connected after server starts
15-
}
1615

17-
enableMocking().then(() => {
16+
// 2. Initialize Clients (Must happen AFTER MSW is ready)
17+
// This ensures discovery requests (/api/v1/metadata) are intercepted by MSW
18+
// instead of falling through to the Vite Dev Server (which returns 404 HTML).
19+
console.log('🔌 Connecting Clients...');
20+
await initClient();
21+
22+
// 3. Render React App
23+
console.log('🚀 Rendering App...');
1824
ReactDOM.createRoot(document.getElementById('root')!).render(
1925
<React.StrictMode>
2026
<App />
2127
</React.StrictMode>
2228
);
23-
});
29+
}
30+
31+
bootstrap().catch(err => {
32+
console.error("FATAL: Application failed to start", err);
33+
document.body.innerHTML = `<div style="color:red; padding: 20px;"><h1>Application Error</h1><pre>${err.message}</pre></div>`;
34+
});

examples/crm-app/src/mocks/browser.ts

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,61 +11,58 @@ export async function startMockServer() {
1111
if (kernel) return kernel;
1212

1313
console.log('[MSW] Starting ObjectStack Runtime (Browser Mode)...');
14+
console.log('[MSW] Loaded Config:', crmConfig ? 'Found' : 'Missing', crmConfig?.apps?.length);
1415

1516
const driver = new InMemoryDriver();
16-
17-
// Create kernel with MiniKernel architecture
1817
kernel = new ObjectKernel();
19-
20-
kernel
21-
// Register ObjectQL engine
22-
.use(new ObjectQLPlugin())
23-
// Register the driver
24-
.use(new DriverPlugin(driver, 'memory'))
25-
// Load app config as a plugin
26-
.use(new AppPlugin(crmConfig))
27-
// MSW Plugin (intercepts network requests)
28-
.use(new MSWPlugin({
29-
enableBrowser: true,
30-
baseUrl: '/api/v1',
31-
logRequests: true,
32-
customHandlers: [
33-
// Custom handlers that are not part of standard CRUD
34-
http.get('/api/bootstrap', async () => {
35-
// We use closure 'driver' variable to bypass objectql service issues
36-
try {
37-
// Use IDataEngine interface directly via driver
38-
// const user = (await driver.findOne('user', 'current')) || {};
18+
19+
try {
20+
kernel
21+
.use(new ObjectQLPlugin())
22+
.use(new DriverPlugin(driver, 'memory'));
23+
24+
if (crmConfig) {
25+
kernel.use(new AppPlugin(crmConfig));
26+
} else {
27+
console.error('❌ CRM Config is missing! Skipping AppPlugin.');
28+
}
29+
30+
kernel.use(new MSWPlugin({
31+
enableBrowser: true,
32+
baseUrl: '/api/v1', // Use root to match client
33+
logRequests: true,
34+
customHandlers: [
35+
http.get('/api/bootstrap', async () => {
3936
const contacts = await driver.find('contact', { object: 'contact' });
40-
const opportunities = await driver.find('opportunity', { object: 'opportunity' });
4137
const stats = { revenue: 125000, leads: 45, deals: 12 };
42-
4338
return HttpResponse.json({
44-
user: { name: "Demo User", role: "admin" }, // simple mock
39+
user: { name: "Demo User", role: "admin" },
4540
stats,
46-
contacts,
47-
opportunities
41+
contacts: contacts || []
4842
});
49-
} catch (e) {
50-
console.error(e);
51-
return new HttpResponse(null, { status: 500 });
52-
}
53-
})
54-
]
43+
})
44+
]
5545
}));
56-
57-
await kernel.bootstrap();
46+
47+
console.log('[Kernel] Bootstrapping...');
48+
await kernel.bootstrap();
49+
console.log('[Kernel] Bootstrap Complete');
5850

59-
// Seed Data
60-
await initializeMockData(driver);
51+
// Seed Data
52+
if (crmConfig) {
53+
await initializeMockData(driver);
54+
}
55+
} catch (err: any) {
56+
console.error('❌ Mock Server Start Failed:', err);
57+
throw err;
58+
}
6159

6260
return kernel;
6361
}
6462

6563
// Helper to seed data into the in-memory driver
6664
async function initializeMockData(driver: InMemoryDriver) {
67-
console.log('[MockServer] Initializing mock data from manifest...');
68-
65+
console.log('[MockServer] Initializing mock data...');
6966
// @ts-ignore
7067
const manifest = crmConfig.manifest;
7168
if (manifest && manifest.data) {
@@ -78,5 +75,4 @@ async function initializeMockData(driver: InMemoryDriver) {
7875
}
7976
}
8077
}
81-
}
82-
78+
}

0 commit comments

Comments
 (0)