Skip to content

Commit 72d3b99

Browse files
committed
refactor: update ObjectStackProtocolImplementation to use ObjectQL engine and improve registry interactions
- Changed the engine type in ObjectStackProtocolImplementation from IDataEngine to ObjectQL. - Updated methods to utilize the new engine's registry for schema and item management. - Refactored tests in registry.test.ts to instantiate SchemaRegistry instead of using static methods. - Converted static methods in SchemaRegistry to instance methods for better encapsulation and testability. - Improved logging and namespace management within SchemaRegistry.
1 parent 987e25f commit 72d3b99

9 files changed

Lines changed: 313 additions & 277 deletions

packages/objectql/src/datasource-mapping.test.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import { describe, it, expect, beforeEach } from 'vitest';
44
import { ObjectQL } from './engine.js';
5-
import { SchemaRegistry } from './registry.js';
65

76
// Mock driver for testing
87
const createMockDriver = (name: string) => ({
@@ -35,7 +34,7 @@ describe('DatasourceMapping', () => {
3534

3635
beforeEach(() => {
3736
engine = new ObjectQL();
38-
SchemaRegistry.reset();
37+
// registry is owned by engine
3938
});
4039

4140
it('should route objects by namespace', async () => {
@@ -51,7 +50,7 @@ describe('DatasourceMapping', () => {
5150
]);
5251

5352
// Register an object in crm namespace
54-
SchemaRegistry.registerObject(
53+
engine.registry.registerObject(
5554
{
5655
name: 'account',
5756
fields: { name: { type: 'text' } },
@@ -81,7 +80,7 @@ describe('DatasourceMapping', () => {
8180
]);
8281

8382
// Register system objects
84-
SchemaRegistry.registerObject(
83+
engine.registry.registerObject(
8584
{
8685
name: 'sys_user',
8786
fields: { username: { type: 'text' } },
@@ -108,7 +107,7 @@ describe('DatasourceMapping', () => {
108107
{ namespace: 'crm', datasource: 'turso', priority: 50 }, // Lower number = higher priority
109108
]);
110109

111-
SchemaRegistry.registerObject(
110+
engine.registry.registerObject(
112111
{
113112
name: 'account',
114113
fields: { name: { type: 'text' } },
@@ -136,7 +135,7 @@ describe('DatasourceMapping', () => {
136135
]);
137136

138137
// Register object in different namespace
139-
SchemaRegistry.registerObject(
138+
engine.registry.registerObject(
140139
{
141140
name: 'task',
142141
fields: { title: { type: 'text' } },
@@ -163,7 +162,7 @@ describe('DatasourceMapping', () => {
163162
]);
164163

165164
// Object explicitly sets datasource
166-
SchemaRegistry.registerObject(
165+
engine.registry.registerObject(
167166
{
168167
name: 'account',
169168
datasource: 'turso', // Explicit override

packages/objectql/src/engine.test.ts

Lines changed: 57 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,47 +3,67 @@ import { ObjectQL } from './engine';
33
import { SchemaRegistry } from './registry';
44
import type { IDataDriver } from '@objectstack/spec/contracts';
55

6-
// Mock the SchemaRegistry to avoid side effects between tests
6+
// Mock the SchemaRegistry to avoid side effects between tests.
7+
// SchemaRegistry is now a per-instance class (one per ObjectQL engine), so the
8+
// mock has to satisfy both use-sites:
9+
// 1. engine.ts does `new SchemaRegistry()` — the constructor must return a
10+
// mocked instance whose methods are the same vi.fn() references the
11+
// tests configure via `vi.mocked(SchemaRegistry.X)`.
12+
// 2. Existing tests reach for `SchemaRegistry.getObject` as if it were a
13+
// static — we preserve that by also attaching the same mocks to the
14+
// class itself.
715
vi.mock('./registry', () => {
816
const mockObjects = new Map();
917
const mockContributors = new Map();
10-
return {
11-
SchemaRegistry: {
12-
getObject: vi.fn((name) => mockObjects.get(name)),
13-
resolveObject: vi.fn((name) => mockObjects.get(name)),
14-
registerObject: vi.fn((obj, packageId, namespace, ownership, priority) => {
15-
const fqn = namespace ? `${namespace}__${obj.name}` : obj.name;
16-
mockObjects.set(fqn, { ...obj, name: fqn });
17-
// Also track contributors for getObjectOwner
18-
if (!mockContributors.has(fqn)) {
19-
mockContributors.set(fqn, []);
20-
}
21-
const contributors = mockContributors.get(fqn);
22-
contributors.push({ packageId, namespace, ownership, priority, definition: obj });
23-
return fqn;
24-
}),
25-
getObjectOwner: vi.fn((fqn) => {
26-
const contributors = mockContributors.get(fqn);
27-
return contributors?.find(c => c.ownership === 'own');
28-
}),
29-
registerNamespace: vi.fn(),
30-
registerKind: vi.fn(),
31-
registerItem: vi.fn(),
32-
registerApp: vi.fn(),
33-
installPackage: vi.fn((manifest) => ({
34-
manifest,
35-
status: 'installed',
36-
enabled: true,
37-
installedAt: new Date().toISOString(),
38-
})),
39-
reset: vi.fn(() => {
40-
mockObjects.clear();
41-
mockContributors.clear();
42-
}),
43-
metadata: {
44-
get: vi.fn(() => mockObjects) // Expose for verification if needed
18+
const instance: any = {
19+
getObject: vi.fn((name) => mockObjects.get(name)),
20+
resolveObject: vi.fn((name) => mockObjects.get(name)),
21+
registerObject: vi.fn((obj, packageId, namespace, ownership, priority) => {
22+
const fqn = namespace ? `${namespace}__${obj.name}` : obj.name;
23+
mockObjects.set(fqn, { ...obj, name: fqn });
24+
if (!mockContributors.has(fqn)) {
25+
mockContributors.set(fqn, []);
4526
}
46-
}
27+
const contributors = mockContributors.get(fqn);
28+
contributors.push({ packageId, namespace, ownership, priority, definition: obj });
29+
return fqn;
30+
}),
31+
getObjectOwner: vi.fn((fqn) => {
32+
const contributors = mockContributors.get(fqn);
33+
return contributors?.find((c: any) => c.ownership === 'own');
34+
}),
35+
registerNamespace: vi.fn(),
36+
registerKind: vi.fn(),
37+
registerItem: vi.fn(),
38+
registerApp: vi.fn(),
39+
installPackage: vi.fn((manifest) => ({
40+
manifest,
41+
status: 'installed',
42+
enabled: true,
43+
installedAt: new Date().toISOString(),
44+
})),
45+
reset: vi.fn(() => {
46+
mockObjects.clear();
47+
mockContributors.clear();
48+
}),
49+
metadata: {
50+
get: vi.fn(() => mockObjects),
51+
},
52+
};
53+
function SchemaRegistry() {
54+
return instance;
55+
}
56+
Object.assign(SchemaRegistry, instance);
57+
return {
58+
SchemaRegistry,
59+
computeFQN: (ns: string | undefined, name: string) =>
60+
(ns && ns !== 'base' && ns !== 'system') ? `${ns}__${name}` : name,
61+
parseFQN: (fqn: string) => {
62+
const idx = fqn.indexOf('__');
63+
if (idx < 0) return { namespace: undefined, shortName: fqn };
64+
return { namespace: fqn.slice(0, idx), shortName: fqn.slice(idx + 2) };
65+
},
66+
RESERVED_NAMESPACES: new Set(['base', 'system']),
4767
};
4868
});
4969

0 commit comments

Comments
 (0)