-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
388 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...ents/PagePanelComponents/Home/Browse3/feedback/StructuredFeedback/humanAnnotationTypes.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...omponents/PagePanelComponents/Home/Browse3/feedback/StructuredFeedback/tsHumanFeedback.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
...ents/PagePanelComponents/Home/Browse3/pages/wfReactInterface/baseObjectClassQuery.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import {expectType} from 'tsd'; | ||
|
||
import { | ||
useBaseObjectInstances, | ||
useCreateBaseObjectInstance, | ||
} from './baseObjectClassQuery'; | ||
import { | ||
TestOnlyExample, | ||
TestOnlyExampleSchema, | ||
} from './generatedBaseObjectClasses.zod'; | ||
import { | ||
TraceObjCreateReq, | ||
TraceObjCreateRes, | ||
TraceObjSchema, | ||
} from './traceServerClientTypes'; | ||
import {Loadable} from './wfDataModelHooksInterface'; | ||
|
||
type TypesAreEqual<T, U> = [T] extends [U] | ||
? [U] extends [T] | ||
? true | ||
: false | ||
: false; | ||
|
||
describe('Type Tests', () => { | ||
it('useCollectionObjects return type matches expected structure', () => { | ||
type CollectionObjectsReturn = ReturnType< | ||
typeof useBaseObjectInstances<'TestOnlyExample'> | ||
>; | ||
|
||
// Define the expected type structure | ||
type ExpectedType = Loadable< | ||
Array<TraceObjSchema<TestOnlyExample, 'TestOnlyExample'>> | ||
>; | ||
|
||
// Type assertion tests | ||
type AssertTypesAreEqual = TypesAreEqual< | ||
CollectionObjectsReturn, | ||
ExpectedType | ||
>; | ||
type Assert = AssertTypesAreEqual extends true ? true : never; | ||
|
||
// This will fail compilation if the types don't match exactly | ||
const _assert: Assert = true; | ||
expect(_assert).toBe(true); | ||
|
||
// Additional runtime sample for documentation | ||
const sampleResult: CollectionObjectsReturn = { | ||
loading: false, | ||
result: [ | ||
{ | ||
project_id: '', | ||
object_id: '', | ||
created_at: '', | ||
digest: '', | ||
version_index: 0, | ||
is_latest: 0, | ||
kind: 'object', | ||
base_object_class: 'TestOnlyExample', | ||
val: TestOnlyExampleSchema.parse({ | ||
name: '', | ||
description: '', | ||
nested_base_model: { | ||
a: 1, | ||
}, | ||
nested_base_object: '', | ||
primitive: 1, | ||
}), | ||
}, | ||
], | ||
}; | ||
|
||
expectType<ExpectedType>(sampleResult); | ||
}); | ||
|
||
it('useCreateCollectionObject return type matches expected structure', () => { | ||
type CreateCollectionObjectReturn = ReturnType< | ||
typeof useCreateBaseObjectInstance<'TestOnlyExample'> | ||
>; | ||
|
||
// Define the expected type structure | ||
type ExpectedType = ( | ||
req: TraceObjCreateReq<TestOnlyExample> | ||
) => Promise<TraceObjCreateRes>; | ||
|
||
// Type assertion tests | ||
type AssertTypesAreEqual = TypesAreEqual< | ||
CreateCollectionObjectReturn, | ||
ExpectedType | ||
>; | ||
type Assert = AssertTypesAreEqual extends true ? true : never; | ||
|
||
// This will fail compilation if the types don't match exactly | ||
const _assert: Assert = true; | ||
expect(_assert).toBe(true); | ||
|
||
// Additional runtime sample for documentation | ||
const sampleResult: CreateCollectionObjectReturn = async req => { | ||
return { | ||
digest: '', | ||
}; | ||
}; | ||
|
||
expectType<ExpectedType>(sampleResult); | ||
}); | ||
}); |
146 changes: 146 additions & 0 deletions
146
...omponents/PagePanelComponents/Home/Browse3/pages/wfReactInterface/baseObjectClassQuery.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
import {useDeepMemo} from '@wandb/weave/hookUtils'; | ||
import {useEffect, useRef, useState} from 'react'; | ||
import {z} from 'zod'; | ||
|
||
import {baseObjectClassRegistry} from './generatedBaseObjectClasses.zod'; | ||
import {TraceServerClient} from './traceServerClient'; | ||
import {useGetTraceServerClientContext} from './traceServerClientContext'; | ||
import { | ||
TraceObjCreateReq, | ||
TraceObjCreateRes, | ||
TraceObjQueryReq, | ||
TraceObjSchema, | ||
} from './traceServerClientTypes'; | ||
import {Loadable} from './wfDataModelHooksInterface'; | ||
|
||
type BaseObjectClassRegistry = typeof baseObjectClassRegistry; | ||
type BaseObjectClassRegistryKeys = keyof BaseObjectClassRegistry; | ||
type BaseObjectClassType<C extends BaseObjectClassRegistryKeys> = z.infer< | ||
BaseObjectClassRegistry[C] | ||
>; | ||
|
||
export type TraceObjSchemaForBaseObjectClass< | ||
C extends BaseObjectClassRegistryKeys | ||
> = TraceObjSchema<BaseObjectClassType<C>, C>; | ||
|
||
export const useBaseObjectInstances = <C extends BaseObjectClassRegistryKeys>( | ||
baseObjectClassName: C, | ||
req: TraceObjQueryReq | ||
): Loadable<Array<TraceObjSchemaForBaseObjectClass<C>>> => { | ||
const [objects, setObjects] = useState< | ||
Array<TraceObjSchemaForBaseObjectClass<C>> | ||
>([]); | ||
const getTsClient = useGetTraceServerClientContext(); | ||
const client = getTsClient(); | ||
const deepReq = useDeepMemo(req); | ||
const currReq = useRef(deepReq); | ||
const [loading, setLoading] = useState(true); | ||
|
||
useEffect(() => { | ||
let isMounted = true; | ||
setLoading(true); | ||
currReq.current = deepReq; | ||
getBaseObjectInstances(client, baseObjectClassName, deepReq).then( | ||
collectionObjects => { | ||
if (isMounted && currReq.current === deepReq) { | ||
setObjects(collectionObjects); | ||
setLoading(false); | ||
} | ||
} | ||
); | ||
return () => { | ||
isMounted = false; | ||
}; | ||
}, [client, baseObjectClassName, deepReq]); | ||
|
||
return {result: objects, loading}; | ||
}; | ||
|
||
const getBaseObjectInstances = async <C extends BaseObjectClassRegistryKeys>( | ||
client: TraceServerClient, | ||
baseObjectClassName: C, | ||
req: TraceObjQueryReq | ||
): Promise<Array<TraceObjSchema<BaseObjectClassType<C>, C>>> => { | ||
const knownObjectClass = baseObjectClassRegistry[baseObjectClassName]; | ||
if (!knownObjectClass) { | ||
console.warn(`Unknown object class: ${baseObjectClassName}`); | ||
return []; | ||
} | ||
|
||
const reqWithBaseObjectClass: TraceObjQueryReq = { | ||
...req, | ||
filter: {...req.filter, base_object_classes: [baseObjectClassName]}, | ||
}; | ||
|
||
const objectPromise = client.objsQuery(reqWithBaseObjectClass); | ||
|
||
const objects = await objectPromise; | ||
|
||
// We would expect that this filtering does not filter anything | ||
// out because the backend enforces the base object class, but this | ||
// is here as a sanity check. | ||
return objects.objs | ||
.map(obj => ({obj, parsed: knownObjectClass.safeParse(obj.val)})) | ||
.filter(({parsed}) => parsed.success) | ||
.filter(({obj}) => obj.base_object_class === baseObjectClassName) | ||
.map( | ||
({obj, parsed}) => | ||
({...obj, val: parsed.data} as TraceObjSchema< | ||
BaseObjectClassType<C>, | ||
C | ||
>) | ||
); | ||
}; | ||
|
||
export const useCreateBaseObjectInstance = < | ||
C extends BaseObjectClassRegistryKeys, | ||
T = BaseObjectClassType<C> | ||
>( | ||
baseObjectClassName: C | ||
): ((req: TraceObjCreateReq<T>) => Promise<TraceObjCreateRes>) => { | ||
const getTsClient = useGetTraceServerClientContext(); | ||
const client = getTsClient(); | ||
return (req: TraceObjCreateReq<T>) => | ||
createBaseObjectInstance(client, baseObjectClassName, req); | ||
}; | ||
|
||
export const createBaseObjectInstance = async < | ||
C extends BaseObjectClassRegistryKeys, | ||
T = BaseObjectClassType<C> | ||
>( | ||
client: TraceServerClient, | ||
baseObjectClassName: C, | ||
req: TraceObjCreateReq<T> | ||
): Promise<TraceObjCreateRes> => { | ||
if ( | ||
req.obj.set_base_object_class != null && | ||
req.obj.set_base_object_class !== baseObjectClassName | ||
) { | ||
throw new Error( | ||
`set_base_object_class must match baseObjectClassName: ${baseObjectClassName}` | ||
); | ||
} | ||
|
||
const knownBaseObjectClass = baseObjectClassRegistry[baseObjectClassName]; | ||
if (!knownBaseObjectClass) { | ||
throw new Error(`Unknown object class: ${baseObjectClassName}`); | ||
} | ||
|
||
const verifiedObject = knownBaseObjectClass.safeParse(req.obj.val); | ||
|
||
if (!verifiedObject.success) { | ||
throw new Error( | ||
`Invalid object: ${JSON.stringify(verifiedObject.error.errors)}` | ||
); | ||
} | ||
|
||
const reqWithBaseObjectClass: TraceObjCreateReq = { | ||
...req, | ||
obj: { | ||
...req.obj, | ||
set_base_object_class: baseObjectClassName, | ||
}, | ||
}; | ||
|
||
return client.objCreate(reqWithBaseObjectClass); | ||
}; |
Oops, something went wrong.