Adds a listener to an event type.
When an event of the type pType fires, the callback pListener will be called. This function
returns a unique string id that may be used in removeEventListenerById to allow simple
listener removal.
It is possible to add an object that will be included in the callback to avoid creating too many closures.
Calling twice addEventListener with the same parameters results in the second call to be ignored,
only unique pairs callback / object are allowed, in order to avoid calling multiple times the same
thing.
The id of the inserted callback (actually an UUID).
Adds a listener to an event type.
When an event of the type pType fires, the callback pListener will be called. This function
returns a unique string id that may be used in removeEventListenerById to allow simple
listener removal.
The id of the inserted callback (actually an UUID).
Asynchronous - Sends a close request concerning the current data session on the proxy.
This actually cleans up the data retained by the proxy and cleans up the resources allocated to the InfiniteEngineInterface.
When the data session is effectively closed, the promise is resolved.
A promise.
Asynchronous - starts the open data session procedure.
A connection is established between the client and the 3djuump Infinite proxy. Security tokens are exchanged and initialization data is retrieved from the proxy and the cache if relevant. This operation may take from a few seconds to several minutes depending on the size of the build to work with.
Additional functionalities may be required with pAddedScopes.
When opening a data session, the user may request the rights to :
The promise is then resolved with the correct AsyncDataSessionInterfaceOpenResult value.
Optional pRestrictionTags: string[]Optional pAddedScopes: DataSessionInterfaceScopes[]A promise. The promise is resolved with the reason (success, failed, already closed).
Asynchronously opens a DataSessionInterface in secondary data session mode.
Once a DataSessionInterface has been fully loaded with openDataSession, a secondary DataSessionInterface may be open with asyncOpenSecondaryDataSession with the result of requestNewSecondaryDataSession called on the primary DataSessionInterface.
/**
* Sample to illustrate the asynchronous use of the primary/secondary session mechanism of DirectorySessionInterface
* and DataSessionInterface.
*/
import {
InfiniteCacheFactory, DirectorySessionFactory,
InfiniteCacheInterface, DirectorySessionInterface,
DataSessionInterface,
DataSessionInterfaceSignal, DirectorySessionInterfaceSignal,
SecondaryDirectorySessionInterfaceInfo,
SecondaryDataSessionInterfaceInfo,
AsyncDirectorySessionWaitForLoadedResult,
AsyncDirectorySessionWaitForLoadedResultReason,
AsyncDataSessionInterfaceOpenResult,
} from 'generated_files/documentation/appinfiniteapi';
// this sample holds the code to be use in the primary tab (primaryCode)
// and in the secondary tab (secondaryCode)
// a callback to receive messages
type tMessageHandler = (pMessage: any) => void;
// we suppose that there exists a message system
let sendMessage : (pMessage: any) => void;
// we suppose that we can register a handler to receive messages
let registerMessageHandler : (pMessageHandler: tMessageHandler) => void;
// the primary code
const primaryCode = () : void =>
{
// created previously
// this is the directory session that will server as primary session
// this DirectorySessionInterface should already be logged in
let lOriginalDirectorySession : DirectorySessionInterface;
// created previously
// this is the data session that will server as primary session
// this DataSessionInterface should already be connected
let lOriginalDataSession : DataSessionInterface;
// create a secondary session info to init the future secondary DirectorySessionInterface
const lSecondaryDirectorySessionInfo : SecondaryDirectorySessionInterfaceInfo | undefined = lOriginalDirectorySession.requestNewSecondaryDirectorySession();
if(lSecondaryDirectorySessionInfo === undefined)
{
// output some fancy error message
console.error('secondary directory session info creation failed');
return;
}
// create a secondary data session info to init the future secondary DataSessionInterface
// warning : this call will hold resources in the primary DataSessionInterface
// when the secondary data session is no longer useful
// release resources with unregisterSecondaryDataSession
// warning: there is a finite number of secondary data sessions that may be created
let lSecondaryDataSessionInfo : SecondaryDataSessionInterfaceInfo | undefined = lOriginalDataSession.requestNewSecondaryDataSession();
if(lSecondaryDataSessionInfo === undefined)
{
// output some fancy error message
console.error('secondary data session info creation failed');
return;
}
// called when the DirectorySessionInterface updates its tokens
const lDirectorySessionTokenUpdate = () : void => {
const lHttpBearer : string = lOriginalDirectorySession.getHttpBearer();
// only update tokens when the directory session is connected
if(lHttpBearer.length > 0)
{
// send the new directory session tokens to the secondary session
sendMessage({
type: 'directorySessionTokens',
httpBearer: lHttpBearer,
authenticationBearer: lOriginalDirectorySession.getAuthenticationBearer(),
extendedAuthenticationBearer: lOriginalDirectorySession.getExtendedAuthenticationBearer(),
});
}
};
// called when the DataSessionInterface updates its tokens
const lDataSessionTokenUpdate = () : void => {
const lDataSessionBearer : string = lOriginalDataSession.getDataSessionBearer();
// only update tokens when the data session is connected
if(lDataSessionBearer.length > 0)
{
// send the new data session tokens to the secondary session
sendMessage({
type: 'dataSessionTokens',
dataSessionBearer: lDataSessionBearer,
extendedDataSessionBearer: lOriginalDataSession.getExtendedDataSessionBearer(),
});
}
};
// message callback, receive messages from the secondary session
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// cleanup the secondary data session resources
case 'dataSessionCleanup':
if(lSecondaryDataSessionInfo !== undefined)
{
lOriginalDataSession.unregisterSecondaryDataSession(lSecondaryDataSessionInfo);
// cleanup only once
lSecondaryDataSessionInfo = undefined;
}
break;
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};
// and register the token update functions on token update
lOriginalDirectorySession.addEventListener(DirectorySessionInterfaceSignal.TokenUpdated, lDirectorySessionTokenUpdate);
lOriginalDataSession.addEventListener(DataSessionInterfaceSignal.TokenUpdated, lDataSessionTokenUpdate);
// register callbacks
registerMessageHandler(onMessage);
// we are ready, send the infos to load a new secondary directory and data session
sendMessage({
type: 'init',
directorySession: lSecondaryDirectorySessionInfo,
dataSession: lSecondaryDataSessionInfo,
// build id is required to create a data session on the correct build
buildId: lOriginalDataSession.getBuildId()
});
};
// the secondary session code
const secondaryCode = () : void =>
{
// create a directory session
const sDirectoryUrl : string = 'https://my_directory:443/directory';
// before connection, this is a "normal" one
const lSecondaryDirectorySession : DirectorySessionInterface = DirectorySessionFactory.CreateDirectorySession(sDirectoryUrl);
// Create a cache to avoid requesting heavy data from the server if data has been retrieved already
const lCache: InfiniteCacheInterface = InfiniteCacheFactory.CreateInfiniteCache();
// the new data session
// we cannot create it right now, we must wait for secondary session info and directory session login
let lSecondaryDataSession : DataSessionInterface;
// hold the open secondary info for future call
let lSecondaryDataSessionInterfaceInfo : SecondaryDataSessionInterfaceInfo;
// the build id we will be connected to
let lDataSessionBuildId : string = '';
// message callback, receive secondary sessions info and tokens
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// secondary sessions infos
case 'init':
{
lSecondaryDataSessionInterfaceInfo = pMessage.dataSession;
lDataSessionBuildId = pMessage.buildId;
lSecondaryDirectorySession.asyncOpenSecondaryDirectorySession(pMessage.directorySession).then(
(pOpenResult: AsyncDirectorySessionWaitForLoadedResult) : void => {
if(pOpenResult.reason !== AsyncDirectorySessionWaitForLoadedResultReason.OpenResult_LoginSuccess)
{
// and output some message if the data session opening failed
console.error('directory session opening failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// weird, we should have a build id at this time
if(lDataSessionBuildId.length === 0)
{
// and output some message if the data session creation failed
console.error('data session creation failed, empty build id');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// actually create the DataSessionInterface
lSecondaryDataSession = lSecondaryDirectorySession.createDataSession(lDataSessionBuildId, lCache);
if(lSecondaryDataSession === undefined)
{
// and output some message if the data session creation failed
console.error('data session creation failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// open it in secondary session mode
lSecondaryDataSession.asyncOpenSecondaryDataSession(lSecondaryDataSessionInterfaceInfo).then(
(pDataSessionResult: AsyncDataSessionInterfaceOpenResult) : void =>
{
if(pDataSessionResult !== AsyncDataSessionInterfaceOpenResult.OpenResult_Success)
{
// and output some message if the data session opening failed
console.error('secondary data session opening failed');
// get rid of data
lSecondaryDataSession.dispose();
lSecondaryDataSession = undefined;
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
// and do some fancy things there :)
// we are connected correctly
}
);
}
);
break;
}
case 'directorySessionTokens':
{
// do nothing if the directory session is not connected
if(!lSecondaryDirectorySession.isAuthenticated())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDirectorySession.setTokenValues(pMessage.httpBearer, pMessage.authenticationBearer, pMessage.extendedAuthenticationBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
case 'dataSessionTokens':
{
// do nothing if the data session is not connected nor created
if(lSecondaryDataSession === undefined || !lSecondaryDataSession.isConnected())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDataSession.setTokenValues(pMessage.dataSessionBearer, pMessage.extendedDataSessionBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};
// register callbacks
registerMessageHandler(onMessage);
};
// in the primary part
primaryCode();
// in the secondary part
secondaryCode();
A promise. The promise is resolved with the reason (success, failed, already closed).
Binds the given InfiniteEngineInterface to this DataSessionInterface.
The DMU will then be rendered on this InfiniteEngineInterface.
This call is equivalent to calling InfiniteEngineInterface.bindDataSession on the InfiniteEngineInterface.
There may be a delay between the call to bindInfiniteEngine and the data being displayed on the InfiniteEngineInterface. Please test using InfiniteEngineInterface.isLoaded, and if data is not loaded, wait for InfiniteEngineInterfaceSignal.DataSessionLoaded.
true if pEngine was actually bound (if already bound, does nothing).
Cancels the calculation of all running WorkingSetInterfaces, FilterItemInterfaces.
The relevant interfaces will asynchronously trigger a "cancel" and "ready" signal when the canceling is done.
Sends a close request concerning the current data session on the proxy.
This actually cleans up the data retained by the proxy and cleans up the resources allocated to the InfiniteEngineInterface.
When the data session is effectively closed, then the DataSessionInterfaceSignal.DataSessionClosed signal is sent.
Instantiates an annotation retrieval procedure to retrieve the content of a view of annotations.
Please see Annotations for more explanations about annotations.
Annotation views may be linked to part instances. The list of annotation views for a part instance
are retrieved by an IdCardGetterInterface, then individual views may be retrieved by
a AnnotationGetterInterface.
A new AnnotationGetterInterface, undefined if the DMU is not loaded.
Creates a new annotation view to be used in the annotation renderer (AnnotationRendererInterface).
The annotation data may be obtained through AnnotationViewInterface.toJSON
or JSON.stringify(pAnnotationView).
An AnnotationViewInterface if the call was successful, undefined if the call failed.
Creates an AttachedDocumentInfoInterface to be used in a DocumentContentGetterInterface.
If the user knows the attached document id and the mime type of an attached document, then a
DocumentContentGetterInterface can be used to retrieve the corresponding attached document.
Instantiates an attribute value enumerator.
An attribute value enumerator is used to query available attribute values of a string attribute.
The AttributeValuesEnumeratorInterface is bound to the given DataSessionInterface.
Get rid of the object with AttributeValuesEnumeratorInterface.dispose.
Optional pObjectId: stringA new attribute values enumerator to the currently loaded DMU, undefined if the DMU is not loaded or if an error occurred.
Instantiates a data retrieval procedure to retrieve the metadata documents
of the children of a list of part instance ids.
Such a list of metadata documents can be merged and customized to
display an metadata information of the children of a part instance.
A new ChildrenIdCardGetterInterface, undefined if the DMU is not loaded.
Instantiates a data retrieval procedure to retrieve the content of an attached document.
Attached document are documents (images, html pages, links, pdf documents, etc ...)
that may be linked to part instances. The list of available documents for a part instance
are retrieved by an IdCardGetterInterface, then individual documents may be retrieved by
a DocumentContentGetterInterface.
A new DocumentContentGetterInterface, undefined if the DMU is not loaded.
Instantiates a converter to translate a document id to its corresponding part instance ids and geometric instance ids.
A DocumentIdConverterInterface may be used in a search procedure.
A DocumentIdConverterInterface, undefined if the DMU is not loaded.
Instantiates an axis aligned bounding box filter.
A FilterAABBInterface is a FilterItemInterface that elects part instances
whom triangles intersect the FilterAABBInterface AABB.
The FilterAABBInterface should be used inside a container (WorkingSetInterface, FilterSetInterface).
The FilterAABBInterface is bound to the given DataSessionInterface.
Get rid of the object with FilterAABBInterface.dispose.
Optional pFilterId: stringA new FilterAABBInterface, undefined if the DMU is not loaded or if an error occurred.
Instantiates an all part instances filter.
A FilterAllPartsInterface is a FilterItemInterface that elects all part instances
of the DMU. It is the most optimized way to create a filter that contains all part instances.
The FilterAllPartsInterface should be used inside a container (WorkingSetInterface, FilterSetInterface).
The FilterAllPartsInterface is bound to the currently DataSessionInterface.
Get rid of the object with FilterAllPartsInterface.dispose.
Optional pFilterId: stringA new FilterAllPartsInterface, undefined if the DMU is not loaded or if an error occurred.
Instantiates a metadata text attribute value filter.
A FilterAttributeInterface is a FilterItemInterface that elects part instances
that contain in their joined attribute set a string attribute whose value matches with the ones contained inside
the FilterAttributeInterface.
The FilterAttributeInterface should be used inside a container (WorkingSetInterface, FilterSetInterface or FilterCompoundInterface).
The FilterAttributeInterface is bound to the given DataSessionInterface.
Get rid of the object with FilterAttributeInterface.dispose.
Optional pFilterId: stringA new FilterAttributeInterface, undefined if the DMU is not loaded or if an error occurred.
Instantiates a metadata boolean attribute value filter.
A FilterBooleanInterface is a FilterItemInterface that elects part instances
that contain in their joined attribute set a boolean attribute (true, false) whose value
is set by
the FilterBooleanInterface.
The FilterBooleanInterface should be used inside a container (WorkingSetInterface, FilterSetInterface or FilterCompoundInterface).
The FilterBooleanInterface is bound to the given DataSessionInterface.
Get rid of the object with FilterBooleanInterface.dispose.
Optional pFilterId: stringA new FilterBooleanInterface, undefined if the DMU is not loaded or if an error occurred.
Instantiates a group metadata filter.
A FilterCompoundInterface is a group filter that elects documents
whose metadata satisfy the clauses contained inside (FilterAttributeInterface,
FilterRangeInterface, FilterHasFieldInterface, FilterBooleanInterface).
When the set of documents that match the clauses are found, then part instances that
are referenced by these documents are elected.
The FilterCompoundInterface should be used inside a container (WorkingSetInterface, FilterSetInterface).
The FilterCompoundInterface is bound to the given DataSessionInterface.
Get rid of the object with FilterCompoundInterface.dispose.
Optional pFilterId: stringA new FilterCompoundInterface, undefined if the DMU is not loaded or if an error occurred.
Instantiates an oriented bounding box diagonal SQUARED length filter.
A FilterDiagonalInterface is a FilterItemInterface that elects part instances
whom oriented bounding box diagonal SQUARED length is contained within the ranges
specified in the FilterDiagonalInterface.
The FilterDiagonalInterface should be used inside a container (WorkingSetInterface, FilterSetInterface).
The FilterDiagonalInterface is bound to the given DataSessionInterface.
Get rid of the object with FilterCompoundInterface.dispose.
Optional pFilterId: stringA new FilterDiagonalInterface, undefined if the DMU is not loaded or if an error occurred.
Instantiates a metadata attribute filter.
A FilterHasFieldInterface is a FilterItemInterface that elects part instances
that contain in their joined attribute set an attribute whose name
is set by the FilterHasFieldInterface.
The FilterHasFieldInterface should be used inside a container (WorkingSetInterface, FilterSetInterface or FilterCompoundInterface).
The FilterHasFieldInterface is bound to the given DataSessionInterface.
Get rid of the object with FilterHasFieldInterface.dispose.
Optional pFilterId: stringA new FilterHasFieldInterface, undefined if the DMU is not loaded or if an error occurred.
Instantiates a query string filter.
A FilterLiteralInterface is a FilterItemInterface that elects part instances
that have at least one individual metadata document that satisfies the string query set by the FilterLiteralInterface.
Such a query should be written in the 3djuump Infinite literal and search query language.
The FilterLiteralInterface should be used inside a container (WorkingSetInterface, FilterSetInterface).
The FilterLiteralInterface is bound to the given DataSessionInterface.
Get rid of the object with FilterLiteralInterface.dispose.
Optional pFilterId: stringA new FilterLiteralInterface, undefined if the DMU is not loaded or if an error occurred.
Instantiates a part instance ids list filter.
A FilterPartInstanceListInterface is a FilterItemInterface that elects part instances
whose part instance id is contained in the FilterPartInstanceListInterface part instance ids list.
WARNING : using a FilterPartInstanceListInterface is very risky since part instance ids are recomputed at
each new 3djuump Infinite build process.
The FilterPartInstanceListInterface should be used inside a container (WorkingSetInterface, FilterSetInterface).
The FilterPartInstanceListInterface is bound to the given DataSessionInterface.
Get rid of the object with FilterPartInstanceListInterface.dispose.
Optional pFilterId: stringA new FilterPartInstanceListInterface, undefined if the DMU is not loaded or if an error occurred.
Instantiates a metadata numeric attribute value filter.
A FilterRangeInterface is a FilterItemInterface that elects part instances
that contain in their joined attribute set a numeric attribute (number, date, number range, date range) whose value
is contained within the ranges contained inside
the FilterRangeInterface.
The FilterRangeInterface should be used inside a container (WorkingSetInterface, FilterSetInterface or FilterCompoundInterface).
The FilterRangeInterface is bound to the given DataSessionInterface.
Get rid of the object with FilterRangeInterface.dispose.
Optional pFilterId: stringA new FilterRangeInterface, undefined if the DMU is not loaded or if an error occurred.
Instantiates a "group" filter.
A FilterSetInterface is a FilterItemInterface that allows grouping FilterItemInterfaces to introduce an operator precedence between them. It is similar to a "parenthesis" system (see GroupOperator).
The FilterSetInterface can be used inside a container (WorkingSetInterface, FilterSetInterface), but beware there is a hard coded limit on the number of imbricated FilterSetInterface (a FilterSetInterface inside a FilterSetInterface inside a FilterSetInterface etc).
Please refer to FilterSetInterface and FilterItemInterface.getDepthContribution.
The FilterSetInterface is bound to the given DataSessionInterface.
Get rid of the object with FilterSetInterface.dispose.
Optional pFilterId: stringA new FilterSetInterface, undefined if the DMU is not loaded or if an error occurred.
Instantiates a converter to translate geometric instance ids to their corresponding part instance ids.
This is the opposite of the PartInstanceConverterInterface.
A new GeometricInstanceConverterInterface, undefined if the DMU is not loaded.
Instantiates a data retrieval procedure to retrieve the metadata documents
associated to a list of part instance ids and their ancestors.
Such a list of metadata documents can be merged and customized to
display an "id-card" of a part instance and its ancestors.
A new IdCardGetterInterface, undefined if the DMU is not loaded.
Instantiates a converter to translate part instances ids to their corresponding geometric instance ids.
This is the opposite of the GeometricInstanceConverterInterface.
A new PartInstanceConverterInterface, undefined if the DMU is not loaded.
Instantiates an a matrix retrieval procedure to get the matrices of a part instance.
A new PartInstanceMatrixGetterInterface, undefined if the DMU is not loaded.
Instantiates a search procedure.
A SearchInterface is used to trigger search query(ies) in the 3djuump Infinite metadata documents, and returns matching metadata documents. The SearchInterface relies on the 3djuump Infinite literal and search query language.
A new SearchInterface, undefined if the DMU is not loaded.
Instantiates a working set.
The WorkingSetInterface is bound to the given DataSessionInterface.
Get rid of the object with WorkingSetInterface.dispose.
Optional pWorkingSetId: stringA new working set to the currently loaded DMU, undefined if the DMU is not loaded or if an error occurred.
Gets rid of this object.
After this call, this object can no longer be used.
If the object is an InfiniteObjectDispatcherInterface, then the InfiniteObjectDispatcherInterfaceSignal.ObjectDisposed signal is emitted.
Further uses of the object (with the exception of isDisposed, getInfiniteObjectType and application id retrieval) will log a message with LogLevel.LL_UsingDisposedObject.
Creates a 2D export Job request that will processed by the 3djuump Infinite backend.
An export job is composed by a list of WorkingSetInterface that may be modified by a color modifier (a WorkingSet2DExportInterface), and an export format Export2DOutputFormatInterface.
Returns an ExportJobInterface that will be used to monitor the progress of the
export job request, and when ready, the export job results may be downloaded.
If the call failed, undefined is returned (e.g. calling export2D before the DataSessionInterface is loaded).
pFormat is an array allowing to request multiple viewpoints and file formats at once.
Once created, all available ExportJobInterface can be retrieved with getExportProcedures.
Optional pCutPlanes: string | ObjectOptional pApplicationId: stringAn export Job ExportJobInterface if the call succeeded else undefined.
Creates a 3D export Job request that will processed by the 3djuump Infinite backend.
An export job is composed by a list of WorkingSetInterface that may be modified by a color modifier (a WorkingSet3DExportInterface), and an export format Export3DOutputFormatInterface.
Returns an ExportJobInterface that will be used to monitor the progress of the
export job request, and when ready, the export job result may be downloaded.
If the call failed, undefined is returned (e.g. calling export3D before the DataSessionInterface is loaded).
Once created, all available ExportJobInterface can be retrieved with getExportProcedures.
Optional pApplicationId: stringAn export Job ExportJobInterface if the call succeeded else undefined.
Creates a SVG export Job request that will processed by the 3djuump Infinite backend.
An export job is composed by a list of WorkingSetInterface that may be modified by a color modifier (a WorkingSet2DExportInterface), and an export format ExportSVGOutputFormatInterface.
Returns an ExportJobInterface that will be used to monitor the progress of the
export job request, and when ready, the export job results may be downloaded.
If the call failed, undefined is returned (e.g. calling exportSVG before the DataSessionInterface is loaded).
pFormat is an array allowing to request multiple viewpoints and file formats at once.
Once created, all available ExportJobInterface can be retrieved with getExportProcedures.
Optional pCutPlanes: string | ObjectOptional pApplicationId: stringAn export Job ExportJobInterface if the call succeeded else undefined.
Sets the content of the DataSessionInterface from a former call to toJSON.
This call will reuse all available WorkingSetInterface (resetting WorkingSetInterface.blockSignals) and filters to match the given context definition.
{
"$defs": {
"all": {
"additionalProperties": false,
"properties": {
"enabled": {
"default": true,
"description": "If disabled, this filter is completely ignored during all the computations",
"example": true,
"type": "boolean"
},
"id": {
"description": "an object id : only ascii non control and non blank characters",
"example": "123e4567e89b12d3a456426614174000",
"maxLength": 64,
"pattern": "^[\\x21-\\x7E]{1,64}$",
"type": "string"
},
"inverted": {
"description": "When 'inverted', a filter elects all the `part instances` that would not be selected if it was not inverted.",
"example": true,
"type": "boolean"
},
"operator": {
"default": "and",
"description": "Operator to apply with this filter and its closest enabled predecessor in its parent container.",
"enum": [
"or",
"and",
"minus"
],
"example": "or",
"type": "string"
},
"type": {
"const": "all",
"description": "Type of the filter",
"type": "string"
},
"version": {
"description": "Define the version of the object",
"example": 1,
"type": "integer"
}
},
"required": [
"type",
"operator",
"enabled",
"inverted",
"id"
],
"title": "Filter all definition",
"type": "object"
},
"attribute": {
"additionalProperties": false,
"properties": {
"attribute": {
"description": "Name of the attribute to filter with",
"example": "PartNumber",
"minLength": 0,
"type": "string"
},
"containsValues": {
"description": "Elects all the `part instances` having the attribute whose name set with attribute in their `joined attribute set` that have a value that contains at least one of the values in the given string array",
"items": {
"type": "string"
},
"type": "array"
},
"enabled": {
"default": true,
"description": "If disabled, this filter is completely ignored during all the computations",
"example": true,
"type": "boolean"
},
"exactValues": {
"description": "Elects all the `part instances` having the attribute whose name set with `attribute` in their `joined attribute set` that have a value exactly included in the given string array.",
"items": {
"type": "string"
},
"type": "array"
},
"id": {
"description": "an object id : only ascii non control and non blank characters",
"example": "123e4567e89b12d3a456426614174000",
"maxLength": 64,
"pattern": "^[\\x21-\\x7E]{1,64}$",
"type": "string"
},
"inverted": {
"description": "When 'inverted', a filter elects all the `part instances` that would not be selected if it was not inverted.",
"example": true,
"type": "boolean"
},
"na": {
"description": "Include `part instances` with the `N/A` value",
"type": "boolean"
},
"operator": {
"default": "and",
"description": "Operator to apply with this filter and its closest enabled predecessor in its parent container.",
"enum": [
"or",
"and",
"minus"
],
"example": "or",
"type": "string"
},
"type": {
"const": "attribute",
"description": "Type of the filter",
"type": "string"
},
"version": {
"description": "Define the version of the object",
"example": 1,
"type": "integer"
}
},
"required": [
"type",
"enabled",
"operator",
"inverted",
"exactValues",
"containsValues",
"na",
"attribute",
"id"
],
"title": "Filter attribute definition",
"type": "object"
},
"boolean": {
"additionalProperties": false,
"properties": {
"attribute": {
"description": "Name of the attribute to filter with",
"example": "PartNumber",
"minLength": 0,
"type": "string"
},
"enabled": {
"default": true,
"description": "If disabled, this filter is completely ignored during all the computations",
"example": true,
"type": "boolean"
},
"id": {
"description": "an object id : only ascii non control and non blank characters",
"example": "123e4567e89b12d3a456426614174000",
"maxLength": 64,
"pattern": "^[\\x21-\\x7E]{1,64}$",
"type": "string"
},
"inverted": {
"description": "When 'inverted', a filter elects all the `part instances` that would not be selected if it was not inverted.",
"example": true,
"type": "boolean"
},
"operator": {
"default": "and",
"description": "Operator to apply with this filter and its closest enabled predecessor in its parent container.",
"enum": [
"or",
"and",
"minus"
],
"example": "or",
"type": "string"
},
"type": {
"const": "boolean",
"description": "Type of the filter",
"type": "string"
},
"value": {
"default": false,
"description": "Boolean value of the filter",
"example": false,
"type": "boolean"
},
"version": {
"description": "Define the version of the object",
"example": 1,
"type": "integer"
}
},
"required": [
"type",
"operator",
"enabled",
"inverted",
"attribute",
"value",
"id"
],
"title": "Filter boolean definition",
"type": "object"
},
"box": {
"additionalProperties": false,
"properties": {
"enabled": {
"default": true,
"description": "If disabled, this filter is completely ignored during all the computations",
"example": true,
"type": "boolean"
},
"id": {
"description": "an object id : only ascii non control and non blank characters",
"example": "123e4567e89b12d3a456426614174000",
"maxLength": 64,
"pattern": "^[\\x21-\\x7E]{1,64}$",
"type": "string"
},
"inverted": {
"description": "When 'inverted', a filter elects all the `part instances` that would not be selected if it was not inverted.",
"example": true,
"type": "boolean"
},
"max": {
"description": "Define the coordinates [x,y,z] of the max point of the AABB",
"items": {
"type": "number"
},
"maxItems": 3,
"minItems": 3,
"type": "array"
},
"min": {
"description": "Define the coordinates [x,y,z] of the min point of the AABB",
"items": {
"type": "number"
},
"maxItems": 3,
"minItems": 3,
"type": "array"
},
"operator": {
"default": "and",
"description": "Operator to apply with this filter and its closest enabled predecessor in its parent container.",
"enum": [
"or",
"and",
"minus"
],
"example": "or",
"type": "string"
},
"overlap": {
"description": "Specify if AABB test is included or overlap",
"example": true,
"type": "boolean"
},
"precision": {
"description": "Numeric precision will be subtracted/added to min/max point of AABB",
"type": "number"
},
"type": {
"const": "box",
"description": "Type of the filter",
"type": "string"
},
"version": {
"description": "Define the version of the object",
"example": 1,
"type": "integer"
}
},
"required": [
"type",
"operator",
"inverted",
"enabled",
"min",
"max",
"overlap",
"precision",
"id"
],
"title": "Filter box definition",
"type": "object"
},
"compound": {
"additionalProperties": false,
"properties": {
"enabled": {
"default": true,
"description": "If disabled, this filter is completely ignored during all the computations",
"example": true,
"type": "boolean"
},
"id": {
"description": "an object id : only ascii non control and non blank characters",
"example": "123e4567e89b12d3a456426614174000",
"maxLength": 64,
"pattern": "^[\\x21-\\x7E]{1,64}$",
"type": "string"
},
"inverted": {
"description": "When 'inverted', a filter elects all the `part instances` that would not be selected if it was not inverted.",
"example": true,
"type": "boolean"
},
"operator": {
"default": "and",
"description": "Operator to apply with this filter and its closest enabled predecessor in its parent container.",
"enum": [
"or",
"and",
"minus"
],
"example": "or",
"type": "string"
},
"subfilters": {
"description": "list of metadata sub filters",
"items": {
"$ref": "#/$defs/compoundfilters"
},
"type": "array"
},
"type": {
"const": "compound",
"description": "Type of the filter",
"type": "string"
},
"version": {
"description": "Define the version of the object",
"example": 1,
"type": "integer"
}
},
"required": [
"type",
"operator",
"enabled",
"inverted",
"subfilters",
"id"
],
"title": "Filter compound definition",
"type": "object"
},
"compoundfilters": {
"oneOf": [
{
"$ref": "#/$defs/boolean"
},
{
"$ref": "#/$defs/hasfield"
},
{
"$ref": "#/$defs/attribute"
},
{
"$ref": "#/$defs/range"
}
]
},
"datasessioncontext": {
"additionalProperties": false,
"properties": {
"type": {
"const": "datasessioncontext",
"description": "Type of context",
"type": "string"
},
"version": {
"description": "Define the version of the object",
"example": 1,
"type": "integer"
},
"workingsets": {
"description": "List of working sets",
"items": {
"$ref": "#/$defs/workingset"
},
"type": "array"
}
},
"required": [
"type",
"version",
"workingsets"
],
"type": "object"
},
"dependencyItem": {
"additionalProperties": false,
"properties": {
"id": {
"description": "an object id : only ascii non control and non blank characters",
"example": "123e4567e89b12d3a456426614174000",
"maxLength": 64,
"pattern": "^[\\x21-\\x7E]{1,64}$",
"type": "string"
},
"op": {
"default": "and",
"description": "Operator to apply with this filter and its closest enabled predecessor in its parent container.",
"enum": [
"or",
"and",
"minus"
],
"example": "or",
"type": "string"
}
},
"required": [
"op",
"id"
],
"type": "object"
},
"diagonal": {
"additionalProperties": false,
"properties": {
"enabled": {
"default": true,
"description": "If disabled, this filter is completely ignored during all the computations",
"example": true,
"type": "boolean"
},
"id": {
"description": "an object id : only ascii non control and non blank characters",
"example": "123e4567e89b12d3a456426614174000",
"maxLength": 64,
"pattern": "^[\\x21-\\x7E]{1,64}$",
"type": "string"
},
"inverted": {
"description": "When 'inverted', a filter elects all the `part instances` that would not be selected if it was not inverted.",
"example": true,
"type": "boolean"
},
"operator": {
"default": "and",
"description": "Operator to apply with this filter and its closest enabled predecessor in its parent container.",
"enum": [
"or",
"and",
"minus"
],
"example": "or",
"type": "string"
},
"rangeitems": {
"description": "List of range item",
"items": {
"$ref": "#/$defs/rangeitem"
},
"type": "array"
},
"type": {
"const": "diagonal",
"description": "Type of the filter",
"type": "string"
},
"version": {
"description": "Define the version of the object",
"example": 1,
"type": "integer"
}
},
"required": [
"type",
"operator",
"enabled",
"inverted",
"rangeitems",
"id"
],
"title": "Filter diagonal definition",
"type": "object"
},
"filter": {
"oneOf": [
{
"$ref": "#/$defs/box"
},
{
"$ref": "#/$defs/all"
},
{
"$ref": "#/$defs/attribute"
},
{
"$ref": "#/$defs/boolean"
},
{
"$ref": "#/$defs/literal"
},
{
"$ref": "#/$defs/compound"
},
{
"$ref": "#/$defs/diagonal"
},
{
"$ref": "#/$defs/hasfield"
},
{
"$ref": "#/$defs/partinstanceidlist"
},
{
"$ref": "#/$defs/range"
},
{
"$ref": "#/$defs/filterset"
}
]
},
"filterset": {
"additionalProperties": false,
"properties": {
"enabled": {
"default": true,
"description": "If disabled, this filter is completely ignored during all the computations",
"example": true,
"type": "boolean"
},
"id": {
"description": "an object id : only ascii non control and non blank characters",
"example": "123e4567e89b12d3a456426614174000",
"maxLength": 64,
"pattern": "^[\\x21-\\x7E]{1,64}$",
"type": "string"
},
"inverted": {
"description": "When 'inverted', a filter elects all the `part instances` that would not be selected if it was not inverted.",
"example": true,
"type": "boolean"
},
"operator": {
"default": "and",
"description": "Operator to apply with this filter and its closest enabled predecessor in its parent container.",
"enum": [
"or",
"and",
"minus"
],
"example": "or",
"type": "string"
},
"subfilters": {
"description": "List of sub filters",
"items": {
"oneOf": [
{
"$ref": "#/$defs/box"
},
{
"$ref": "#/$defs/all"
},
{
"$ref": "#/$defs/attribute"
},
{
"$ref": "#/$defs/boolean"
},
{
"$ref": "#/$defs/literal"
},
{
"$ref": "#/$defs/compound"
},
{
"$ref": "#/$defs/diagonal"
},
{
"$ref": "#/$defs/hasfield"
},
{
"$ref": "#/$defs/partinstanceidlist"
},
{
"$ref": "#/$defs/range"
},
{
"$ref": "#/$defs/filterset"
}
]
},
"type": "array"
},
"type": {
"const": "set",
"description": "Type of the filter",
"type": "string"
},
"version": {
"description": "Define the version of the object",
"example": 1,
"type": "integer"
}
},
"required": [
"type",
"enabled",
"operator",
"inverted",
"subfilters",
"id"
],
"title": "Filter set definition",
"type": "object"
},
"hasfield": {
"additionalProperties": false,
"properties": {
"attribute": {
"description": "Name of the attribute to filter with",
"example": "PartNumber",
"minLength": 0,
"type": "string"
},
"enabled": {
"default": true,
"description": "If disabled, this filter is completely ignored during all the computations",
"example": true,
"type": "boolean"
},
"id": {
"description": "an object id : only ascii non control and non blank characters",
"example": "123e4567e89b12d3a456426614174000",
"maxLength": 64,
"pattern": "^[\\x21-\\x7E]{1,64}$",
"type": "string"
},
"inverted": {
"description": "When 'inverted', a filter elects all the `part instances` that would not be selected if it was not inverted.",
"example": true,
"type": "boolean"
},
"operator": {
"default": "and",
"description": "Operator to apply with this filter and its closest enabled predecessor in its parent container.",
"enum": [
"or",
"and",
"minus"
],
"example": "or",
"type": "string"
},
"type": {
"const": "hasfield",
"description": "Type of the filter",
"type": "string"
},
"version": {
"description": "Define the version of the object",
"example": 1,
"type": "integer"
}
},
"required": [
"type",
"operator",
"enabled",
"inverted",
"attribute",
"id"
],
"title": "Filter Has field definition",
"type": "object"
},
"literal": {
"additionalProperties": false,
"properties": {
"enabled": {
"default": true,
"description": "If disabled, this filter is completely ignored during all the computations",
"example": true,
"type": "boolean"
},
"id": {
"description": "an object id : only ascii non control and non blank characters",
"example": "123e4567e89b12d3a456426614174000",
"maxLength": 64,
"pattern": "^[\\x21-\\x7E]{1,64}$",
"type": "string"
},
"inverted": {
"description": "When 'inverted', a filter elects all the `part instances` that would not be selected if it was not inverted.",
"example": true,
"type": "boolean"
},
"operator": {
"default": "and",
"description": "Operator to apply with this filter and its closest enabled predecessor in its parent container.",
"enum": [
"or",
"and",
"minus"
],
"example": "or",
"type": "string"
},
"query": {
"description": "Sets the query string in the 3djuump infinite literal and search query language",
"example": ":PartNumber=='bolt'",
"type": "string"
},
"type": {
"const": "literal",
"description": "Type of the filter",
"type": "string"
},
"version": {
"description": "Define the version of the object",
"example": 1,
"type": "integer"
}
},
"required": [
"type",
"operator",
"enabled",
"inverted",
"query",
"id"
],
"title": "Filter literal definition",
"type": "object"
},
"partinstanceidlist": {
"additionalProperties": false,
"properties": {
"buildid": {
"description": "Id of the build use to create the part list instance",
"type": "string"
},
"enabled": {
"default": true,
"description": "If disabled, this filter is completely ignored during all the computations",
"example": true,
"type": "boolean"
},
"id": {
"description": "an object id : only ascii non control and non blank characters",
"example": "123e4567e89b12d3a456426614174000",
"maxLength": 64,
"pattern": "^[\\x21-\\x7E]{1,64}$",
"type": "string"
},
"inverted": {
"description": "When 'inverted', a filter elects all the `part instances` that would not be selected if it was not inverted.",
"example": true,
"type": "boolean"
},
"list": {
"description": "List of part instance ids",
"items": {
"type": "number"
},
"type": "array"
},
"operator": {
"default": "and",
"description": "Operator to apply with this filter and its closest enabled predecessor in its parent container.",
"enum": [
"or",
"and",
"minus"
],
"example": "or",
"type": "string"
},
"type": {
"const": "partinstanceidlist",
"description": "Type of the filter",
"type": "string"
},
"version": {
"description": "Define the version of the object",
"example": 1,
"type": "integer"
}
},
"required": [
"type",
"operator",
"enabled",
"inverted",
"buildid",
"list",
"id"
],
"title": "Filter Part instance list definition",
"type": "object"
},
"range": {
"additionalProperties": false,
"properties": {
"attribute": {
"description": "Name of the attribute to filter with",
"example": "PartNumber",
"minLength": 0,
"type": "string"
},
"enabled": {
"default": true,
"description": "If disabled, this filter is completely ignored during all the computations",
"example": true,
"type": "boolean"
},
"id": {
"description": "an object id : only ascii non control and non blank characters",
"example": "123e4567e89b12d3a456426614174000",
"maxLength": 64,
"pattern": "^[\\x21-\\x7E]{1,64}$",
"type": "string"
},
"inverted": {
"description": "When 'inverted', a filter elects all the `part instances` that would not be selected if it was not inverted.",
"example": true,
"type": "boolean"
},
"operator": {
"default": "and",
"description": "Operator to apply with this filter and its closest enabled predecessor in its parent container.",
"enum": [
"or",
"and",
"minus"
],
"example": "or",
"type": "string"
},
"rangeitems": {
"description": "List of range item",
"items": {
"$ref": "#/$defs/rangeitem"
},
"type": "array"
},
"type": {
"const": "range",
"description": "Type of the filter",
"type": "string"
},
"version": {
"description": "Define the version of the object",
"example": 1,
"type": "integer"
}
},
"required": [
"type",
"operator",
"enabled",
"inverted",
"attribute",
"rangeitems",
"id"
],
"title": "Filter range definition",
"type": "object"
},
"rangeitem": {
"additionalProperties": false,
"properties": {
"includedLower": {
"description": "Sets if the lower bound value should be included or excluded",
"type": "boolean"
},
"includedUpper": {
"description": "Sets if the upper bound value should be included or excluded",
"type": "boolean"
},
"lower": {
"description": "Lower bound of the range item",
"type": "number"
},
"upper": {
"description": "Upper bound of the range item",
"type": "number"
}
},
"required": [
"includedLower",
"includedUpper"
],
"title": "Range item definition",
"type": "object"
},
"retrievalType": {
"enum": [
"none",
"geometric_instance_ids",
"geometric_and_part_instance_ids"
],
"type": "string"
},
"workingset": {
"additionalProperties": false,
"properties": {
"behavior": {
"description": "The way data is computed inside the working set",
"type": "integer"
},
"configurationids": {
"items": {
"description": "ID of a JSON document",
"maxLength": 255,
"minLength": 1,
"pattern": "^[^_].{0,255}$",
"type": "string"
},
"type": "array"
},
"dependencies": {
"items": {
"$ref": "#/$defs/dependencyItem"
},
"type": "array"
},
"enabled": {
"type": "boolean"
},
"filters": {
"description": "List of sub filters",
"items": {
"$ref": "#/$defs/filter"
},
"type": "array"
},
"id": {
"description": "an object id : only ascii non control and non blank characters",
"example": "123e4567e89b12d3a456426614174000",
"maxLength": 64,
"pattern": "^[\\x21-\\x7E]{1,64}$",
"type": "string"
},
"retrieval": {
"$ref": "#/$defs/retrievalType"
},
"type": {
"const": "workingset",
"type": "string"
},
"version": {
"description": "Define the version of the object",
"example": 1,
"type": "integer"
}
},
"required": [
"id",
"type",
"filters",
"dependencies",
"enabled",
"retrieval",
"configurationids",
"behavior"
],
"title": "WorkingSet definition",
"type": "object"
}
},
"$ref": "#/$defs/datasessioncontext",
"$schema": "https://json-schema.org/draft-07/schema#"
}
true if the data is set.
Gets the list of available annotation types.
Please see Annotations for more explanations about annotations.
Modifying this array in place results in undefined behavior.
DO NOT modify this array.
Gets the attributes dictionary of the DMU.
The AttributesDictionaryInterface is a read only interface to know all the available attributes and their types.
Gets the list of bound InfiniteEngineInterface from this DataSessionInterface.
true if the call succeeded.
Gets the list of configurations.
Please see configurations for more explanations about configurations.
Modifying this array in place results in undefined behavior.
DO NOT modify this array.
Gets the data session token that may be used in other requests to prove the authentication to the 3djuump Infinite architecture.
Any http request should have the header x-infinite-bearer : <DataSessionInterface.getDataSessionBearer()>.
If the data session is not connected, returns an empty string.
The data session token used to prove the authentication.
Gets the Axis Aligned Bounding Box of the currently loaded DMU.
Returns false if no DMU is loaded (DataSessionInterfaceSignal.DMULoadingSuccess).
true if a DMU is loaded and pDmuAABBOut is updated.
Gets the Unit of the DMU currently loaded.
Returns Unit.U_Invalid if no DMU is loaded (DataSessionInterfaceSignal.DMULoadingSuccess).
The Unit of the DMU (millimeters, centimeters, meters, etc).
Gets the list of available ExportJobInterface that have been created with export3D.
true if the call was successful.
Gets the extended data session token that may be used in other requests to prove the authentication to the 3djuump Infinite architecture.
The extended bearer is heavier than getDataSessionBearer and is available only if the directory session was connected with an extended bearer request (Please refer to DirectorySessionInterface.getSamePageAuthenticationUrl and DirectorySessionInterface.getPopupBasedAuthenticationUrl).
Any http request may have the header x-infinite-bearer : <DataSessionInterface.getExtendedDataSessionBearer()>.
If the data session is not connected, returns an empty string.
The extended data session token used to prove the authentication.
Gets the axis aligned bounding box of the given geometric instance id.
Call this function after the DMU has been loaded (DataSessionInterfaceSignal.DMULoadingSuccess) with a previously created AABB.
Returns true if the given geometric instance id is valid.
geometric instance id to query.geometric instance.true if pAABBOut is updated.
Gets the diagonal squared length of the Oriented Bounding Box (OBB) of the given geometric instance id.
Returns -1 if pGeometricInstanceId is an invalid geometric instance id, or the diagonal squared length of the OBB if it is valid.
geometric instance id to query.The diagonal squared length of the OBB of the geometric instance or -1 if invalid.
Gets the maximum diagonal squared length of all the Oriented Bounding Box (OBB) of all the geometric instances.
Returns the maximum diagonal squared length of the current DMU, or -1 if a DMU has not been loaded (DataSessionInterfaceSignal.DMULoadingSuccess).
The maximum diagonal squared length of the current DMU, or -1 if no DMU is loaded.
Gets the minimum diagonal squared length of all the Oriented Bounding Box (OBB) of all the geometric instances.
Returns the minimum diagonal squared length of the current DMU, or -1 if a DMU has not been loaded ().
The minimum diagonal squared length of the current DMU, or -1 if no DMU is loaded.
Gets the granted scopes that have been granted while opening the build.
The user may have requested a set of scopes when calling openDataSession, but some requested scopes may not be granted (perhaps they were not available to the user). This call tells the scopes that have been granted when the build have been opened.
Gets the security tags used that have been granted while opening the build.
The user may have requested a set of tags when calling openDataSession, but some requested restriction tags may not be granted (perhaps they were not part of the given build, etc ...). This call tells the extra tags that have been granted when the build have been opened.
Tells the type of the given interface.
The type of the given interface.
Gets the maximum geometric instance id of the DMU.
Valid geometric instance ids range from 1 to getMaximumGeometricId() included.
Please refer to Main ID Types for more information.
Returns the maximum geometric instance id if a DMU is loaded (DataSessionInterfaceSignal.DMULoadingSuccess,
0 else.
The maximum geometric instance id, 0 if no DMU is loaded.
Gets the maximum part instance leaf id of the DMU.
Valid part leaf instance ids range from 1 to getMaximumPartInstanceLeafId() included.
Please refer to Main ID Types for more information.
Returns the maximum part instance id if a DMU is loaded (DataSessionInterfaceSignal.DMULoadingSuccess,
0 else.
The maximum leaf part instance id, 0 if no DMU is loaded.
Gets the progress on the openDataSession call.
Such a progress is a float value between 0 and 1.
1 is returned when the open procedure is over.
The progress of the openDataSession procedure.
Gets the original matrix of the given geometric instance id, independently to any transformation that may be applied
to the given geometry.
Call this function after the DMU has been loaded (DataSessionInterfaceSignal.DMULoadingSuccess) with a previously created AABB.
Returns true if the given geometric instance id is valid.
geometric instance id to query.geometric instance.true if pMatrixOut is updated.
Gets a project document by its id.
Available project documents are :
Please refer to the integration manual to have more information about these documents.
It is very unlikely any developer will use these versioned documents.
Example (illustration purpose only):
const lDocs = [
{
"id": "com.3djuump:defaultsettings",
"profiles": [],
"settings": {
"backfaceculling": false,
"dynamiclowdefprofiles": {
"high": 2097152,
"standard": 1048576
},
"fieldofview": {
"degree": 25,
"orientation": "vertical"
},
"frameorientation": {
"dir": [
-1,
0,
0
],
"up": [
0,
0,
1
]
}
},
"subtype": "defaultsettings",
"tasksettings": {
"PresentationTask": {
"aspectratio": [
16,
9
]
}
},
"ts": 1591950944,
"type": "projectdocument",
"version": "8.0"
},
{
"id": "com.3djuump:indexinfo",
"internal": {
"effectivity": {
"SB": {
"nested": [
"effectivity"
],
"type": "keyword",
"values": [
"SB1",
"not_SB1"
]
},
"engine": {
"nested": [
"effectivity"
],
"type": "keyword",
"values": [
"A",
"B"
]
}
},
"metadata": {
"system": {
"type": "text",
"values": [
"Structure",
"Interior",
"Exterior",
"windows",
"Wheel base"
]
},
"test.nested.text": {
"nested": [
"metadata",
"test",
"nested"
],
"type": "text",
"values": [
"A",
"B",
"C"
]
},
"test.bool": {
"type": "boolean"
},
"test.date": {
"max": 1528114033000,
"min": 1528114033000,
"type": "date"
},
"test.date_range": {
"type": "date_range"
},
"test.double_range": {
"type": "double_range"
},
"test.int": {
"max": 1,
"min": 1,
"type": "double"
}
}
},
"seq": 814,
"subtype": "indexinfo",
"type": "indexdocument",
"version": 1
},
{
"id": "com.3djuump:scripts",
"scriptbase64": "base64 string",
"subtype": "scripts",
"taskscripts": {
"AnnotationTask": "base64 string"
},
"ts": 1598877573,
"type": "projectdocument",
"version": "8.0"
}
];
Returns the json document as a string if the given document is available in the 3djuump Infinite project.
The document as a string, or undefined if the document could not be found or the DMU is not loaded.
Gets the source model id of the given geometric instance id.
2 geometric instance ids with the same source model id
means the 2 instances have the same geometric representation, but with different matrices.
A valid source model id is a strictly positive integer. Returns 0 in case of error
(invalid geometric instance id).
geometric instance id to query.The source model id of the geometric instance.
Computes the axis aligned bounding box of the given geometric instances.
This consists in the union of all the AABB of the geometric instances expressed by their
geometric instance ids.
Call this function once the DMU has been loaded (DataSessionInterfaceSignal.DMULoadingSuccess) with a previously created AABB.
Returns true if at least one geometric instance id inside pGeometricInstanceIds is valid. Invalid geometric instance ids
are silently discarded.
geometric instance ids to query.true if at least one geometric instance id inside pGeometricInstanceIds is valid and pAABBOut is therefore updated.
Gets a WorkingSetInterface by its id.
The correct WorkingSetInterface or undefined if not found.
Gets all WorkingSetInterface.
Tells if the EventDispatcher has such a callback registered for the given event type.
true if such a listener is installed for the given type of event.
Tells if the DMU has features.
Features are lines and circles that are detected on the 3D data.
Prior to the infinite architecture 4.1 version, features did not exist.
As such, any DMU migrated from versions prior to the 4.1 version will not have
any feature. DMU created after (or equal) the 4.1 versions have the feature detection
algorithm running.
Calling this function before receiving DataSessionInterfaceSignal.DMULoadingSuccess event
will return false.
true if the currently loaded DMU has features.
Tells if the data session is connected to a proxy.
If the proxy has not yet received the DataSessionInterfaceSignal.DMULoadingSuccess or DataSessionInterfaceSignal.DMULoadingFailed signal, returns true.
Returns true if openDataSession has been called and closeDataSession has not yet been called.
true if all initialization data have been parsed.
Tells if this object has been gotten rid off.
true if dispose has been called on this object.
Tells if the data session is ready to be used (i.e. all necessary data has been loaded).
Returns true if openDataSession has been called, the DataSessionInterfaceSignal.DMULoadingSuccess has been called and closeDataSession has not yet been called.
true if all initialization data have been parsed.
Tells if the DataSessionInterface is configured as "Primary" session behavior.
The DataSessionInterface is by default configured as "Primary".
The primary session behavior consists in querying the bearers (getDataSessionBearer, getExtendedDataSessionBearer) regularly while a secondary DataSessionInterface should receive the new bearers with setTokenValues. This primary/secondary session mechanism allows to use multiple data sessions objects that share the same data session on the server. This may be useful to share the same data session upon multiple tabs of the browser.
true if the DataSessionInterface is configured as a primary session behavior.
Starts the open data session procedure.
A connection is established between the client and the 3djuump Infinite proxy. Security tokens are exchanged and initialization data is retrieved from the proxy and the cache if relevant. This operation may take from a few seconds to several minutes depending on the size of the data to work with.
When data is ready, the DataSessionInterfaceSignal.DMULoadingSuccess signal is sent.
If an error occurs, then the DataSessionInterfaceSignal.DMULoadingFailed signal is sent.
Additional functionalities may be required with pAddedScopes.
When opening a data session, the user may request the rights to :
pRestrictionTags should not contain duplicates.
Optional pRestrictionTags: string[]Optional pAddedScopes: DataSessionInterfaceScopes[]true if the data session open procedure can be started. Returns false in case the DataSessionInterface has already been opened.
Opens a DataSessionInterface in secondary session mode.
Once a DataSessionInterface has been fully loaded with openDataSession, a secondary DataSessionInterface may be open with openSecondaryDataSession with the result of requestNewSecondaryDataSession called on the primary DataSessionInterface.
/**
* Sample to illustrate the use of the primary/secondary session mechanism of DirectorySessionInterface and DataSessionInterface.
*/
import {
InfiniteCacheFactory, DirectorySessionFactory,
InfiniteCacheInterface, DirectorySessionInterface,
DataSessionInterface,
DataSessionInterfaceSignal, DirectorySessionInterfaceSignal,
SecondaryDirectorySessionInterfaceInfo,
SecondaryDataSessionInterfaceInfo,
AuthenticationGetURLResult,
} from 'generated_files/documentation/appinfiniteapi';
// this sample holds the code to be use in the primary tab (primaryCode)
// and in the secondary tab (secondaryCode)
// a callback to receive messages
type tMessageHandler = (pMessage: any) => void;
// we suppose that there exists a message system
let sendMessage : (pMessage: any) => void;
// we suppose that we can register a handler to receive messages
let registerMessageHandler : (pMessageHandler: tMessageHandler) => void;
// the primary code
const primaryCode = () : void =>
{
// created previously
// this is the directory session that will server as primary session
// this DirectorySessionInterface should already be logged in
let lOriginalDirectorySession : DirectorySessionInterface;
// created previously
// this is the data session that will server as primary session
// this DataSessionInterface should already be primary session
let lOriginalDataSession : DataSessionInterface;
// create a secondary session info to init the future secondary DirectorySessionInterface
const lSecondaryDirectorySessionInfo : SecondaryDirectorySessionInterfaceInfo | undefined = lOriginalDirectorySession.requestNewSecondaryDirectorySession();
if(lSecondaryDirectorySessionInfo === undefined)
{
// output some fancy error message
console.error('secondary directory session info creation failed');
return;
}
// create a secondary session info to init the future secondary DataSessionInterface
// warning : this call will hold resources in the primary DataSessionInterface
// when the secondary data session is no longer useful
// release resources with unregisterSecondaryDataSession
// warning: there is a finite number of secondary data sessions that may be created
let lSecondaryDataSessionInfo : SecondaryDataSessionInterfaceInfo | undefined = lOriginalDataSession.requestNewSecondaryDataSession();
if(lSecondaryDataSessionInfo === undefined)
{
// output some fancy error message
console.error('secondary data session info creation failed');
return;
}
// called when the DirectorySessionInterface updates its tokens
const lDirectorySessionTokenUpdate = () : void => {
const lHttpBearer : string = lOriginalDirectorySession.getHttpBearer();
// only update tokens when the directory session is connected
if(lHttpBearer.length > 0)
{
// send the new directory session tokens to the secondary
sendMessage({
type: 'directorySessionTokens',
httpBearer: lHttpBearer,
authenticationBearer: lOriginalDirectorySession.getAuthenticationBearer(),
extendedAuthenticationBearer: lOriginalDirectorySession.getExtendedAuthenticationBearer(),
});
}
};
// called when the DataSessionInterface updates its tokens
const lDataSessionTokenUpdate = () : void => {
const lDataSessionBearer : string = lOriginalDataSession.getDataSessionBearer();
// only update tokens when the data session is connected
if(lDataSessionBearer.length > 0)
{
// send the new data session tokens to the secondary session
sendMessage({
type: 'dataSessionTokens',
dataSessionBearer: lDataSessionBearer,
extendedDataSessionBearer: lOriginalDataSession.getExtendedDataSessionBearer(),
});
}
};
// message callback, receive messages from the secondary session
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// cleanup the secondary session resources
case 'dataSessionCleanup':
if(lSecondaryDataSessionInfo !== undefined)
{
lOriginalDataSession.unregisterSecondaryDataSession(lSecondaryDataSessionInfo);
// cleanup only once
lSecondaryDataSessionInfo = undefined;
}
break;
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};
// and register the token update functions on token update
lOriginalDirectorySession.addEventListener(DirectorySessionInterfaceSignal.TokenUpdated, lDirectorySessionTokenUpdate);
lOriginalDataSession.addEventListener(DataSessionInterfaceSignal.TokenUpdated, lDataSessionTokenUpdate);
// register callbacks
registerMessageHandler(onMessage);
// we are ready, send the infos to load a new secondary directory and data session
sendMessage({
type: 'init',
directorySession: lSecondaryDirectorySessionInfo,
dataSession: lSecondaryDataSessionInfo,
// build id is required to create a data session on the correct build
buildId: lOriginalDataSession.getBuildId()
});
};
// the secondary session code
const secondaryCode = () : void =>
{
// create a directory session
const sDirectoryUrl : string = 'https://my_directory:443/directory';
// before connection, this is a "normal" one
const lSecondaryDirectorySession : DirectorySessionInterface = DirectorySessionFactory.CreateDirectorySession(sDirectoryUrl);
// Create a cache to avoid requesting heavy data from the server if data has been retrieved already
const lCache: InfiniteCacheInterface = InfiniteCacheFactory.CreateInfiniteCache();
// the new data session
// we cannot create it right now, we must wait for secondary session info and directory session login
let lSecondaryDataSession : DataSessionInterface;
// hold the open secondary session info for future call
let lSecondaryDataSessionInterfaceInfo : SecondaryDataSessionInterfaceInfo;
// the build id we will be connected to
let lDataSessionBuildId : string = '';
// Success callback on DirectorySessionInterface login
const onLoginSuccess = () : void => {
// weird, we should have a build id at this time
if(lDataSessionBuildId.length === 0)
{
// and output some message if the data session creation failed
console.error('data session creation failed, empty build id');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// actually create the DataSessionInterface
lSecondaryDataSession = lSecondaryDirectorySession.createDataSession(lDataSessionBuildId, lCache);
if(lSecondaryDataSession === undefined)
{
// and output some message if the data session creation failed
console.error('data session creation failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// open it in secondary session mode
if(!lSecondaryDataSession.openSecondaryDataSession(lSecondaryDataSessionInterfaceInfo))
{
// and output some message if the data session opening failed
console.error('secondary data session opening failed');
// get rid of data
lSecondaryDataSession.dispose();
lSecondaryDataSession = undefined;
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
// and then we must wait for the DataSessionInterface to be connected
};
// message callback, receive secondary sessions info and tokens
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// secondary sessions infos
case 'init':
{
lSecondaryDataSessionInterfaceInfo = pMessage.dataSession;
lDataSessionBuildId = pMessage.buildId;
const lResult : AuthenticationGetURLResult = lSecondaryDirectorySession.openSecondaryDirectorySession(pMessage.directorySession);
if(lResult !== AuthenticationGetURLResult.AuthenticationPending)
{
// and output some message if the data session opening failed
console.error('directory session opening failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
case 'directorySessionTokens':
{
// do nothing if the directory session is not connected
if(!lSecondaryDirectorySession.isAuthenticated())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDirectorySession.setTokenValues(pMessage.httpBearer, pMessage.authenticationBearer, pMessage.extendedAuthenticationBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
case 'dataSessionTokens':
{
// do nothing if the data session is not connected nor created
if(lSecondaryDataSession === undefined || !lSecondaryDataSession.isConnected())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDataSession.setTokenValues(pMessage.dataSessionBearer, pMessage.extendedDataSessionBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};
// register callbacks
lSecondaryDirectorySession.addEventListener(DirectorySessionInterfaceSignal.LoginSuccess, onLoginSuccess);
registerMessageHandler(onMessage);
};
// in the primary part
primaryCode();
// in the secondary part
secondaryCode();
true if the call succeeded.
Removes a listener from an event type.
If no such listener is found, then the function returns false and does nothing. You must use the exact parameters that were used in addEventListener to actually remove the listener.
The listener function that gets removed.
The listener object that was used when addEventListener was called.
true if the callback was removed else false.
Removes a listener from an event type.
If no such listener is found, then the function returns false and does nothing. You must use the exact parameters that were used in addEventListener to actually remove the listener.
The listener function that gets removed.
true if the callback was removed else false.
Removes a listener by its id.
If no such listener is found, then the function returns false and does nothing. You must use the return value of addEventListener to actually remove the listener.
true if the callback was removed else false.
Creates a SecondaryDataSessionInterfaceInfo in order to create a new secondary DataSessionInterface.
Once called, the secondary DataSessionInterface will be considered open, and unregisterSecondaryDataSession must be called on the same object in order to reclaim the resources associated with the given secondary DataSessionInterface.
This opaque object may be streamed to another tab (for example) and then used with openSecondaryDataSession and unregisterSecondaryDataSession. Please make sure openSecondaryDataSession will be used with the same buildid that was used to create the DataSessionInterface (DirectorySessionInterface.createDataSession).
/**
* Sample to illustrate the use of the primary/secondary session mechanism of DirectorySessionInterface and DataSessionInterface.
*/
import {
InfiniteCacheFactory, DirectorySessionFactory,
InfiniteCacheInterface, DirectorySessionInterface,
DataSessionInterface,
DataSessionInterfaceSignal, DirectorySessionInterfaceSignal,
SecondaryDirectorySessionInterfaceInfo,
SecondaryDataSessionInterfaceInfo,
AuthenticationGetURLResult,
} from 'generated_files/documentation/appinfiniteapi';
// this sample holds the code to be use in the primary tab (primaryCode)
// and in the secondary tab (secondaryCode)
// a callback to receive messages
type tMessageHandler = (pMessage: any) => void;
// we suppose that there exists a message system
let sendMessage : (pMessage: any) => void;
// we suppose that we can register a handler to receive messages
let registerMessageHandler : (pMessageHandler: tMessageHandler) => void;
// the primary code
const primaryCode = () : void =>
{
// created previously
// this is the directory session that will server as primary session
// this DirectorySessionInterface should already be logged in
let lOriginalDirectorySession : DirectorySessionInterface;
// created previously
// this is the data session that will server as primary session
// this DataSessionInterface should already be primary session
let lOriginalDataSession : DataSessionInterface;
// create a secondary session info to init the future secondary DirectorySessionInterface
const lSecondaryDirectorySessionInfo : SecondaryDirectorySessionInterfaceInfo | undefined = lOriginalDirectorySession.requestNewSecondaryDirectorySession();
if(lSecondaryDirectorySessionInfo === undefined)
{
// output some fancy error message
console.error('secondary directory session info creation failed');
return;
}
// create a secondary session info to init the future secondary DataSessionInterface
// warning : this call will hold resources in the primary DataSessionInterface
// when the secondary data session is no longer useful
// release resources with unregisterSecondaryDataSession
// warning: there is a finite number of secondary data sessions that may be created
let lSecondaryDataSessionInfo : SecondaryDataSessionInterfaceInfo | undefined = lOriginalDataSession.requestNewSecondaryDataSession();
if(lSecondaryDataSessionInfo === undefined)
{
// output some fancy error message
console.error('secondary data session info creation failed');
return;
}
// called when the DirectorySessionInterface updates its tokens
const lDirectorySessionTokenUpdate = () : void => {
const lHttpBearer : string = lOriginalDirectorySession.getHttpBearer();
// only update tokens when the directory session is connected
if(lHttpBearer.length > 0)
{
// send the new directory session tokens to the secondary
sendMessage({
type: 'directorySessionTokens',
httpBearer: lHttpBearer,
authenticationBearer: lOriginalDirectorySession.getAuthenticationBearer(),
extendedAuthenticationBearer: lOriginalDirectorySession.getExtendedAuthenticationBearer(),
});
}
};
// called when the DataSessionInterface updates its tokens
const lDataSessionTokenUpdate = () : void => {
const lDataSessionBearer : string = lOriginalDataSession.getDataSessionBearer();
// only update tokens when the data session is connected
if(lDataSessionBearer.length > 0)
{
// send the new data session tokens to the secondary session
sendMessage({
type: 'dataSessionTokens',
dataSessionBearer: lDataSessionBearer,
extendedDataSessionBearer: lOriginalDataSession.getExtendedDataSessionBearer(),
});
}
};
// message callback, receive messages from the secondary session
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// cleanup the secondary session resources
case 'dataSessionCleanup':
if(lSecondaryDataSessionInfo !== undefined)
{
lOriginalDataSession.unregisterSecondaryDataSession(lSecondaryDataSessionInfo);
// cleanup only once
lSecondaryDataSessionInfo = undefined;
}
break;
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};
// and register the token update functions on token update
lOriginalDirectorySession.addEventListener(DirectorySessionInterfaceSignal.TokenUpdated, lDirectorySessionTokenUpdate);
lOriginalDataSession.addEventListener(DataSessionInterfaceSignal.TokenUpdated, lDataSessionTokenUpdate);
// register callbacks
registerMessageHandler(onMessage);
// we are ready, send the infos to load a new secondary directory and data session
sendMessage({
type: 'init',
directorySession: lSecondaryDirectorySessionInfo,
dataSession: lSecondaryDataSessionInfo,
// build id is required to create a data session on the correct build
buildId: lOriginalDataSession.getBuildId()
});
};
// the secondary session code
const secondaryCode = () : void =>
{
// create a directory session
const sDirectoryUrl : string = 'https://my_directory:443/directory';
// before connection, this is a "normal" one
const lSecondaryDirectorySession : DirectorySessionInterface = DirectorySessionFactory.CreateDirectorySession(sDirectoryUrl);
// Create a cache to avoid requesting heavy data from the server if data has been retrieved already
const lCache: InfiniteCacheInterface = InfiniteCacheFactory.CreateInfiniteCache();
// the new data session
// we cannot create it right now, we must wait for secondary session info and directory session login
let lSecondaryDataSession : DataSessionInterface;
// hold the open secondary session info for future call
let lSecondaryDataSessionInterfaceInfo : SecondaryDataSessionInterfaceInfo;
// the build id we will be connected to
let lDataSessionBuildId : string = '';
// Success callback on DirectorySessionInterface login
const onLoginSuccess = () : void => {
// weird, we should have a build id at this time
if(lDataSessionBuildId.length === 0)
{
// and output some message if the data session creation failed
console.error('data session creation failed, empty build id');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// actually create the DataSessionInterface
lSecondaryDataSession = lSecondaryDirectorySession.createDataSession(lDataSessionBuildId, lCache);
if(lSecondaryDataSession === undefined)
{
// and output some message if the data session creation failed
console.error('data session creation failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// open it in secondary session mode
if(!lSecondaryDataSession.openSecondaryDataSession(lSecondaryDataSessionInterfaceInfo))
{
// and output some message if the data session opening failed
console.error('secondary data session opening failed');
// get rid of data
lSecondaryDataSession.dispose();
lSecondaryDataSession = undefined;
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
// and then we must wait for the DataSessionInterface to be connected
};
// message callback, receive secondary sessions info and tokens
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// secondary sessions infos
case 'init':
{
lSecondaryDataSessionInterfaceInfo = pMessage.dataSession;
lDataSessionBuildId = pMessage.buildId;
const lResult : AuthenticationGetURLResult = lSecondaryDirectorySession.openSecondaryDirectorySession(pMessage.directorySession);
if(lResult !== AuthenticationGetURLResult.AuthenticationPending)
{
// and output some message if the data session opening failed
console.error('directory session opening failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
case 'directorySessionTokens':
{
// do nothing if the directory session is not connected
if(!lSecondaryDirectorySession.isAuthenticated())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDirectorySession.setTokenValues(pMessage.httpBearer, pMessage.authenticationBearer, pMessage.extendedAuthenticationBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
case 'dataSessionTokens':
{
// do nothing if the data session is not connected nor created
if(lSecondaryDataSession === undefined || !lSecondaryDataSession.isConnected())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDataSession.setTokenValues(pMessage.dataSessionBearer, pMessage.extendedDataSessionBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};
// register callbacks
lSecondaryDirectorySession.addEventListener(DirectorySessionInterfaceSignal.LoginSuccess, onLoginSuccess);
registerMessageHandler(onMessage);
};
// in the primary part
primaryCode();
// in the secondary part
secondaryCode();
/**
* Sample to illustrate the asynchronous use of the primary/secondary session mechanism of DirectorySessionInterface
* and DataSessionInterface.
*/
import {
InfiniteCacheFactory, DirectorySessionFactory,
InfiniteCacheInterface, DirectorySessionInterface,
DataSessionInterface,
DataSessionInterfaceSignal, DirectorySessionInterfaceSignal,
SecondaryDirectorySessionInterfaceInfo,
SecondaryDataSessionInterfaceInfo,
AsyncDirectorySessionWaitForLoadedResult,
AsyncDirectorySessionWaitForLoadedResultReason,
AsyncDataSessionInterfaceOpenResult,
} from 'generated_files/documentation/appinfiniteapi';
// this sample holds the code to be use in the primary tab (primaryCode)
// and in the secondary tab (secondaryCode)
// a callback to receive messages
type tMessageHandler = (pMessage: any) => void;
// we suppose that there exists a message system
let sendMessage : (pMessage: any) => void;
// we suppose that we can register a handler to receive messages
let registerMessageHandler : (pMessageHandler: tMessageHandler) => void;
// the primary code
const primaryCode = () : void =>
{
// created previously
// this is the directory session that will server as primary session
// this DirectorySessionInterface should already be logged in
let lOriginalDirectorySession : DirectorySessionInterface;
// created previously
// this is the data session that will server as primary session
// this DataSessionInterface should already be connected
let lOriginalDataSession : DataSessionInterface;
// create a secondary session info to init the future secondary DirectorySessionInterface
const lSecondaryDirectorySessionInfo : SecondaryDirectorySessionInterfaceInfo | undefined = lOriginalDirectorySession.requestNewSecondaryDirectorySession();
if(lSecondaryDirectorySessionInfo === undefined)
{
// output some fancy error message
console.error('secondary directory session info creation failed');
return;
}
// create a secondary data session info to init the future secondary DataSessionInterface
// warning : this call will hold resources in the primary DataSessionInterface
// when the secondary data session is no longer useful
// release resources with unregisterSecondaryDataSession
// warning: there is a finite number of secondary data sessions that may be created
let lSecondaryDataSessionInfo : SecondaryDataSessionInterfaceInfo | undefined = lOriginalDataSession.requestNewSecondaryDataSession();
if(lSecondaryDataSessionInfo === undefined)
{
// output some fancy error message
console.error('secondary data session info creation failed');
return;
}
// called when the DirectorySessionInterface updates its tokens
const lDirectorySessionTokenUpdate = () : void => {
const lHttpBearer : string = lOriginalDirectorySession.getHttpBearer();
// only update tokens when the directory session is connected
if(lHttpBearer.length > 0)
{
// send the new directory session tokens to the secondary session
sendMessage({
type: 'directorySessionTokens',
httpBearer: lHttpBearer,
authenticationBearer: lOriginalDirectorySession.getAuthenticationBearer(),
extendedAuthenticationBearer: lOriginalDirectorySession.getExtendedAuthenticationBearer(),
});
}
};
// called when the DataSessionInterface updates its tokens
const lDataSessionTokenUpdate = () : void => {
const lDataSessionBearer : string = lOriginalDataSession.getDataSessionBearer();
// only update tokens when the data session is connected
if(lDataSessionBearer.length > 0)
{
// send the new data session tokens to the secondary session
sendMessage({
type: 'dataSessionTokens',
dataSessionBearer: lDataSessionBearer,
extendedDataSessionBearer: lOriginalDataSession.getExtendedDataSessionBearer(),
});
}
};
// message callback, receive messages from the secondary session
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// cleanup the secondary data session resources
case 'dataSessionCleanup':
if(lSecondaryDataSessionInfo !== undefined)
{
lOriginalDataSession.unregisterSecondaryDataSession(lSecondaryDataSessionInfo);
// cleanup only once
lSecondaryDataSessionInfo = undefined;
}
break;
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};
// and register the token update functions on token update
lOriginalDirectorySession.addEventListener(DirectorySessionInterfaceSignal.TokenUpdated, lDirectorySessionTokenUpdate);
lOriginalDataSession.addEventListener(DataSessionInterfaceSignal.TokenUpdated, lDataSessionTokenUpdate);
// register callbacks
registerMessageHandler(onMessage);
// we are ready, send the infos to load a new secondary directory and data session
sendMessage({
type: 'init',
directorySession: lSecondaryDirectorySessionInfo,
dataSession: lSecondaryDataSessionInfo,
// build id is required to create a data session on the correct build
buildId: lOriginalDataSession.getBuildId()
});
};
// the secondary session code
const secondaryCode = () : void =>
{
// create a directory session
const sDirectoryUrl : string = 'https://my_directory:443/directory';
// before connection, this is a "normal" one
const lSecondaryDirectorySession : DirectorySessionInterface = DirectorySessionFactory.CreateDirectorySession(sDirectoryUrl);
// Create a cache to avoid requesting heavy data from the server if data has been retrieved already
const lCache: InfiniteCacheInterface = InfiniteCacheFactory.CreateInfiniteCache();
// the new data session
// we cannot create it right now, we must wait for secondary session info and directory session login
let lSecondaryDataSession : DataSessionInterface;
// hold the open secondary info for future call
let lSecondaryDataSessionInterfaceInfo : SecondaryDataSessionInterfaceInfo;
// the build id we will be connected to
let lDataSessionBuildId : string = '';
// message callback, receive secondary sessions info and tokens
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// secondary sessions infos
case 'init':
{
lSecondaryDataSessionInterfaceInfo = pMessage.dataSession;
lDataSessionBuildId = pMessage.buildId;
lSecondaryDirectorySession.asyncOpenSecondaryDirectorySession(pMessage.directorySession).then(
(pOpenResult: AsyncDirectorySessionWaitForLoadedResult) : void => {
if(pOpenResult.reason !== AsyncDirectorySessionWaitForLoadedResultReason.OpenResult_LoginSuccess)
{
// and output some message if the data session opening failed
console.error('directory session opening failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// weird, we should have a build id at this time
if(lDataSessionBuildId.length === 0)
{
// and output some message if the data session creation failed
console.error('data session creation failed, empty build id');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// actually create the DataSessionInterface
lSecondaryDataSession = lSecondaryDirectorySession.createDataSession(lDataSessionBuildId, lCache);
if(lSecondaryDataSession === undefined)
{
// and output some message if the data session creation failed
console.error('data session creation failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// open it in secondary session mode
lSecondaryDataSession.asyncOpenSecondaryDataSession(lSecondaryDataSessionInterfaceInfo).then(
(pDataSessionResult: AsyncDataSessionInterfaceOpenResult) : void =>
{
if(pDataSessionResult !== AsyncDataSessionInterfaceOpenResult.OpenResult_Success)
{
// and output some message if the data session opening failed
console.error('secondary data session opening failed');
// get rid of data
lSecondaryDataSession.dispose();
lSecondaryDataSession = undefined;
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
// and do some fancy things there :)
// we are connected correctly
}
);
}
);
break;
}
case 'directorySessionTokens':
{
// do nothing if the directory session is not connected
if(!lSecondaryDirectorySession.isAuthenticated())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDirectorySession.setTokenValues(pMessage.httpBearer, pMessage.authenticationBearer, pMessage.extendedAuthenticationBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
case 'dataSessionTokens':
{
// do nothing if the data session is not connected nor created
if(lSecondaryDataSession === undefined || !lSecondaryDataSession.isConnected())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDataSession.setTokenValues(pMessage.dataSessionBearer, pMessage.extendedDataSessionBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};
// register callbacks
registerMessageHandler(onMessage);
};
// in the primary part
primaryCode();
// in the secondary part
secondaryCode();
A new SecondaryDataSessionInterfaceInfo if the call succeeded.
Relaunches the idle timer.
For security reasons, the data session is closed when no event has been received for a long time, this duration depends on the server configuration. You may reset the idle timer at some time to avoid the user from being disconnected.
When the user will be soon disconnected, then the DataSessionInterfaceSignal.IdleWarningDataSession signal is sent, if the user interacts with the system or
restartIdleTimer is called, then the DataSessionReactivated signal is sent.
If no user interaction takes place, then the data session is closed, the DataSessionInterfaceSignal.IdleDataSession signal is sent (no DataSessionInterfaceSignal.DataSessionClosed signal will be sent).
You will have to call closeDataSession to clean up the resources.
Updates the bearers of a secondary DataSessionInterface on a regular basis.
The primary DataSessionInterface that was used to call requestNewSecondaryDataSession must be monitored with the signal DataSessionInterfaceSignal.TokenUpdated and queried with getDataSessionBearer and getExtendedDataSessionBearer, and then the created secondary DataSessionInterface must be updated with setTokenValues.
/**
* Sample to illustrate the use of the primary/secondary session mechanism of DirectorySessionInterface and DataSessionInterface.
*/
import {
InfiniteCacheFactory, DirectorySessionFactory,
InfiniteCacheInterface, DirectorySessionInterface,
DataSessionInterface,
DataSessionInterfaceSignal, DirectorySessionInterfaceSignal,
SecondaryDirectorySessionInterfaceInfo,
SecondaryDataSessionInterfaceInfo,
AuthenticationGetURLResult,
} from 'generated_files/documentation/appinfiniteapi';
// this sample holds the code to be use in the primary tab (primaryCode)
// and in the secondary tab (secondaryCode)
// a callback to receive messages
type tMessageHandler = (pMessage: any) => void;
// we suppose that there exists a message system
let sendMessage : (pMessage: any) => void;
// we suppose that we can register a handler to receive messages
let registerMessageHandler : (pMessageHandler: tMessageHandler) => void;
// the primary code
const primaryCode = () : void =>
{
// created previously
// this is the directory session that will server as primary session
// this DirectorySessionInterface should already be logged in
let lOriginalDirectorySession : DirectorySessionInterface;
// created previously
// this is the data session that will server as primary session
// this DataSessionInterface should already be primary session
let lOriginalDataSession : DataSessionInterface;
// create a secondary session info to init the future secondary DirectorySessionInterface
const lSecondaryDirectorySessionInfo : SecondaryDirectorySessionInterfaceInfo | undefined = lOriginalDirectorySession.requestNewSecondaryDirectorySession();
if(lSecondaryDirectorySessionInfo === undefined)
{
// output some fancy error message
console.error('secondary directory session info creation failed');
return;
}
// create a secondary session info to init the future secondary DataSessionInterface
// warning : this call will hold resources in the primary DataSessionInterface
// when the secondary data session is no longer useful
// release resources with unregisterSecondaryDataSession
// warning: there is a finite number of secondary data sessions that may be created
let lSecondaryDataSessionInfo : SecondaryDataSessionInterfaceInfo | undefined = lOriginalDataSession.requestNewSecondaryDataSession();
if(lSecondaryDataSessionInfo === undefined)
{
// output some fancy error message
console.error('secondary data session info creation failed');
return;
}
// called when the DirectorySessionInterface updates its tokens
const lDirectorySessionTokenUpdate = () : void => {
const lHttpBearer : string = lOriginalDirectorySession.getHttpBearer();
// only update tokens when the directory session is connected
if(lHttpBearer.length > 0)
{
// send the new directory session tokens to the secondary
sendMessage({
type: 'directorySessionTokens',
httpBearer: lHttpBearer,
authenticationBearer: lOriginalDirectorySession.getAuthenticationBearer(),
extendedAuthenticationBearer: lOriginalDirectorySession.getExtendedAuthenticationBearer(),
});
}
};
// called when the DataSessionInterface updates its tokens
const lDataSessionTokenUpdate = () : void => {
const lDataSessionBearer : string = lOriginalDataSession.getDataSessionBearer();
// only update tokens when the data session is connected
if(lDataSessionBearer.length > 0)
{
// send the new data session tokens to the secondary session
sendMessage({
type: 'dataSessionTokens',
dataSessionBearer: lDataSessionBearer,
extendedDataSessionBearer: lOriginalDataSession.getExtendedDataSessionBearer(),
});
}
};
// message callback, receive messages from the secondary session
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// cleanup the secondary session resources
case 'dataSessionCleanup':
if(lSecondaryDataSessionInfo !== undefined)
{
lOriginalDataSession.unregisterSecondaryDataSession(lSecondaryDataSessionInfo);
// cleanup only once
lSecondaryDataSessionInfo = undefined;
}
break;
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};
// and register the token update functions on token update
lOriginalDirectorySession.addEventListener(DirectorySessionInterfaceSignal.TokenUpdated, lDirectorySessionTokenUpdate);
lOriginalDataSession.addEventListener(DataSessionInterfaceSignal.TokenUpdated, lDataSessionTokenUpdate);
// register callbacks
registerMessageHandler(onMessage);
// we are ready, send the infos to load a new secondary directory and data session
sendMessage({
type: 'init',
directorySession: lSecondaryDirectorySessionInfo,
dataSession: lSecondaryDataSessionInfo,
// build id is required to create a data session on the correct build
buildId: lOriginalDataSession.getBuildId()
});
};
// the secondary session code
const secondaryCode = () : void =>
{
// create a directory session
const sDirectoryUrl : string = 'https://my_directory:443/directory';
// before connection, this is a "normal" one
const lSecondaryDirectorySession : DirectorySessionInterface = DirectorySessionFactory.CreateDirectorySession(sDirectoryUrl);
// Create a cache to avoid requesting heavy data from the server if data has been retrieved already
const lCache: InfiniteCacheInterface = InfiniteCacheFactory.CreateInfiniteCache();
// the new data session
// we cannot create it right now, we must wait for secondary session info and directory session login
let lSecondaryDataSession : DataSessionInterface;
// hold the open secondary session info for future call
let lSecondaryDataSessionInterfaceInfo : SecondaryDataSessionInterfaceInfo;
// the build id we will be connected to
let lDataSessionBuildId : string = '';
// Success callback on DirectorySessionInterface login
const onLoginSuccess = () : void => {
// weird, we should have a build id at this time
if(lDataSessionBuildId.length === 0)
{
// and output some message if the data session creation failed
console.error('data session creation failed, empty build id');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// actually create the DataSessionInterface
lSecondaryDataSession = lSecondaryDirectorySession.createDataSession(lDataSessionBuildId, lCache);
if(lSecondaryDataSession === undefined)
{
// and output some message if the data session creation failed
console.error('data session creation failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// open it in secondary session mode
if(!lSecondaryDataSession.openSecondaryDataSession(lSecondaryDataSessionInterfaceInfo))
{
// and output some message if the data session opening failed
console.error('secondary data session opening failed');
// get rid of data
lSecondaryDataSession.dispose();
lSecondaryDataSession = undefined;
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
// and then we must wait for the DataSessionInterface to be connected
};
// message callback, receive secondary sessions info and tokens
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// secondary sessions infos
case 'init':
{
lSecondaryDataSessionInterfaceInfo = pMessage.dataSession;
lDataSessionBuildId = pMessage.buildId;
const lResult : AuthenticationGetURLResult = lSecondaryDirectorySession.openSecondaryDirectorySession(pMessage.directorySession);
if(lResult !== AuthenticationGetURLResult.AuthenticationPending)
{
// and output some message if the data session opening failed
console.error('directory session opening failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
case 'directorySessionTokens':
{
// do nothing if the directory session is not connected
if(!lSecondaryDirectorySession.isAuthenticated())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDirectorySession.setTokenValues(pMessage.httpBearer, pMessage.authenticationBearer, pMessage.extendedAuthenticationBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
case 'dataSessionTokens':
{
// do nothing if the data session is not connected nor created
if(lSecondaryDataSession === undefined || !lSecondaryDataSession.isConnected())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDataSession.setTokenValues(pMessage.dataSessionBearer, pMessage.extendedDataSessionBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};
// register callbacks
lSecondaryDirectorySession.addEventListener(DirectorySessionInterfaceSignal.LoginSuccess, onLoginSuccess);
registerMessageHandler(onMessage);
};
// in the primary part
primaryCode();
// in the secondary part
secondaryCode();
true if the call succeeded.
Gets a deep copy of the internal data of the DataSessionInterface.
Please refer to JSON.stringify.
Optional pKey: anyThe internal DataSessionInterface data.
Unbinds the given InfiniteEngineInterface from this DataSessionInterface.
This call then removes the loaded GPU resources in the InfiniteEngineInterface.
This call is equivalent to calling InfiniteEngineInterface.bindDataSession(undefined) on the InfiniteEngineInterface.
true if pEngine was actually unbound.
Un-registers a secondary DataSessionInterface when the created secondary DataSessionInterface is no longer in use.
The exact same SecondaryDataSessionInterfaceInfo that was created with requestNewSecondaryDataSession should be used.
/**
* Sample to illustrate the use of the primary/secondary session mechanism of DirectorySessionInterface and DataSessionInterface.
*/
import {
InfiniteCacheFactory, DirectorySessionFactory,
InfiniteCacheInterface, DirectorySessionInterface,
DataSessionInterface,
DataSessionInterfaceSignal, DirectorySessionInterfaceSignal,
SecondaryDirectorySessionInterfaceInfo,
SecondaryDataSessionInterfaceInfo,
AuthenticationGetURLResult,
} from 'generated_files/documentation/appinfiniteapi';
// this sample holds the code to be use in the primary tab (primaryCode)
// and in the secondary tab (secondaryCode)
// a callback to receive messages
type tMessageHandler = (pMessage: any) => void;
// we suppose that there exists a message system
let sendMessage : (pMessage: any) => void;
// we suppose that we can register a handler to receive messages
let registerMessageHandler : (pMessageHandler: tMessageHandler) => void;
// the primary code
const primaryCode = () : void =>
{
// created previously
// this is the directory session that will server as primary session
// this DirectorySessionInterface should already be logged in
let lOriginalDirectorySession : DirectorySessionInterface;
// created previously
// this is the data session that will server as primary session
// this DataSessionInterface should already be primary session
let lOriginalDataSession : DataSessionInterface;
// create a secondary session info to init the future secondary DirectorySessionInterface
const lSecondaryDirectorySessionInfo : SecondaryDirectorySessionInterfaceInfo | undefined = lOriginalDirectorySession.requestNewSecondaryDirectorySession();
if(lSecondaryDirectorySessionInfo === undefined)
{
// output some fancy error message
console.error('secondary directory session info creation failed');
return;
}
// create a secondary session info to init the future secondary DataSessionInterface
// warning : this call will hold resources in the primary DataSessionInterface
// when the secondary data session is no longer useful
// release resources with unregisterSecondaryDataSession
// warning: there is a finite number of secondary data sessions that may be created
let lSecondaryDataSessionInfo : SecondaryDataSessionInterfaceInfo | undefined = lOriginalDataSession.requestNewSecondaryDataSession();
if(lSecondaryDataSessionInfo === undefined)
{
// output some fancy error message
console.error('secondary data session info creation failed');
return;
}
// called when the DirectorySessionInterface updates its tokens
const lDirectorySessionTokenUpdate = () : void => {
const lHttpBearer : string = lOriginalDirectorySession.getHttpBearer();
// only update tokens when the directory session is connected
if(lHttpBearer.length > 0)
{
// send the new directory session tokens to the secondary
sendMessage({
type: 'directorySessionTokens',
httpBearer: lHttpBearer,
authenticationBearer: lOriginalDirectorySession.getAuthenticationBearer(),
extendedAuthenticationBearer: lOriginalDirectorySession.getExtendedAuthenticationBearer(),
});
}
};
// called when the DataSessionInterface updates its tokens
const lDataSessionTokenUpdate = () : void => {
const lDataSessionBearer : string = lOriginalDataSession.getDataSessionBearer();
// only update tokens when the data session is connected
if(lDataSessionBearer.length > 0)
{
// send the new data session tokens to the secondary session
sendMessage({
type: 'dataSessionTokens',
dataSessionBearer: lDataSessionBearer,
extendedDataSessionBearer: lOriginalDataSession.getExtendedDataSessionBearer(),
});
}
};
// message callback, receive messages from the secondary session
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// cleanup the secondary session resources
case 'dataSessionCleanup':
if(lSecondaryDataSessionInfo !== undefined)
{
lOriginalDataSession.unregisterSecondaryDataSession(lSecondaryDataSessionInfo);
// cleanup only once
lSecondaryDataSessionInfo = undefined;
}
break;
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};
// and register the token update functions on token update
lOriginalDirectorySession.addEventListener(DirectorySessionInterfaceSignal.TokenUpdated, lDirectorySessionTokenUpdate);
lOriginalDataSession.addEventListener(DataSessionInterfaceSignal.TokenUpdated, lDataSessionTokenUpdate);
// register callbacks
registerMessageHandler(onMessage);
// we are ready, send the infos to load a new secondary directory and data session
sendMessage({
type: 'init',
directorySession: lSecondaryDirectorySessionInfo,
dataSession: lSecondaryDataSessionInfo,
// build id is required to create a data session on the correct build
buildId: lOriginalDataSession.getBuildId()
});
};
// the secondary session code
const secondaryCode = () : void =>
{
// create a directory session
const sDirectoryUrl : string = 'https://my_directory:443/directory';
// before connection, this is a "normal" one
const lSecondaryDirectorySession : DirectorySessionInterface = DirectorySessionFactory.CreateDirectorySession(sDirectoryUrl);
// Create a cache to avoid requesting heavy data from the server if data has been retrieved already
const lCache: InfiniteCacheInterface = InfiniteCacheFactory.CreateInfiniteCache();
// the new data session
// we cannot create it right now, we must wait for secondary session info and directory session login
let lSecondaryDataSession : DataSessionInterface;
// hold the open secondary session info for future call
let lSecondaryDataSessionInterfaceInfo : SecondaryDataSessionInterfaceInfo;
// the build id we will be connected to
let lDataSessionBuildId : string = '';
// Success callback on DirectorySessionInterface login
const onLoginSuccess = () : void => {
// weird, we should have a build id at this time
if(lDataSessionBuildId.length === 0)
{
// and output some message if the data session creation failed
console.error('data session creation failed, empty build id');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// actually create the DataSessionInterface
lSecondaryDataSession = lSecondaryDirectorySession.createDataSession(lDataSessionBuildId, lCache);
if(lSecondaryDataSession === undefined)
{
// and output some message if the data session creation failed
console.error('data session creation failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// open it in secondary session mode
if(!lSecondaryDataSession.openSecondaryDataSession(lSecondaryDataSessionInterfaceInfo))
{
// and output some message if the data session opening failed
console.error('secondary data session opening failed');
// get rid of data
lSecondaryDataSession.dispose();
lSecondaryDataSession = undefined;
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
// and then we must wait for the DataSessionInterface to be connected
};
// message callback, receive secondary sessions info and tokens
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// secondary sessions infos
case 'init':
{
lSecondaryDataSessionInterfaceInfo = pMessage.dataSession;
lDataSessionBuildId = pMessage.buildId;
const lResult : AuthenticationGetURLResult = lSecondaryDirectorySession.openSecondaryDirectorySession(pMessage.directorySession);
if(lResult !== AuthenticationGetURLResult.AuthenticationPending)
{
// and output some message if the data session opening failed
console.error('directory session opening failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
case 'directorySessionTokens':
{
// do nothing if the directory session is not connected
if(!lSecondaryDirectorySession.isAuthenticated())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDirectorySession.setTokenValues(pMessage.httpBearer, pMessage.authenticationBearer, pMessage.extendedAuthenticationBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
case 'dataSessionTokens':
{
// do nothing if the data session is not connected nor created
if(lSecondaryDataSession === undefined || !lSecondaryDataSession.isConnected())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDataSession.setTokenValues(pMessage.dataSessionBearer, pMessage.extendedDataSessionBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};
// register callbacks
lSecondaryDirectorySession.addEventListener(DirectorySessionInterfaceSignal.LoginSuccess, onLoginSuccess);
registerMessageHandler(onMessage);
};
// in the primary part
primaryCode();
// in the secondary part
secondaryCode();
true if the call succeeded.
Triggers the calculation of all modified WorkingSetInterface, FilterItemInterfaces.
All the modified items are updated on the server according to their inter-dependencies.
The relevant interfaces will asynchronously trigger a "ready" signal when their calculation is over.
The DataSessionInterface is the formalization of the connection between a 3djuump Infinite proxy and the client.
The DataSessionInterface is created from a connected DirectorySessionInterface and a proxy by the use of the DirectorySessionInterface.createDataSession function.
The open data session procedure is detailed below :
The DataSession can only be opened once, when closed, there is no way to reuse this object. You will have to call again the DirectorySessionInterface.createDataSession function.
Connecting a DataSessionInterface to an InfiniteEngineInterface.
The DataSessionInterface may be linked with an InfiniteEngineInterface to render the content of the DMU. Please use bindInfiniteEngine, or InfiniteEngineInterface.bindDataSession.
Tags System.
There exists two types of tags :
Each user is assigned a set of tags (UserData.viewtags inside a ConnectionData), that may be :
A user is allowed to open a build if its full list of the Build open tags are contained inside the Build.
NB: If a build is contained inside the ConnectionData, then the user has the required tags (Build.tags are only informational).
Intersecting the Build.extratags and UserData.viewtags tells the extra tags that may be used to see security protected data. These tags may be used to open a Build with fewer security levels, with openDataSession. Passing undefined with openDataSession means opening the Build with the full set of allowed view tags of the User. You may query the list of extra tags that have been granted with getGrantedSecurityTags once the data session is connected.
Added functionalities.
The data session may be open with added functionalities (scopes). When opening a data session, the user may request the rights to :
These rights are represented by DataSessionInterfaceScopes, when using openDataSession.
Idle System.
In order to save resources on the proxy, the api features an automatic data session closing mechanism when the user is not interacting with the application. The DataSessionInterface will be closed if DataSessionInterface.restartIdleTimer is not called on user interactions.
It is composed of three pseudo-states :
The idle system.
Please see DirectorySessionInterface for more explanations about sessions.
All metadata filters, search procedure, data retrieval procedures are created from this interface.
The DataSessionInterface, once successfully connected to a 3djuump Infinite build (see DataSessionInterfaceSignal.DMULoadingSuccess) provides access to
Id converters and data retrieval interfaces are somewhat autonomous. They only rely on a WorkingSetInterface to be used.
However, filtering interfaces are linked together, making difficult to find the correct order to update them and when. For these reasons, and to avoid too many requests being sent to the 3djuump Infinite server, the update is triggered by the DataSessionInterface that handles the dependency graph of all these items, and updates only the required interfaces with update.
All these interfaces (filtering, id conversion, data retrieval) work asynchronously : they all feature some kind of "ready" signal telling the result is available, just call EventDispatcherInterface.addEventListener with the correct signal on the required interfaces.
These interfaces has a InfiniteObjectInterface.dispose function to get rid of them. Do not forget to call these functions to save memory and CPU usage.
The only way to create sets of
part instancesis to use a WorkingSetInterface that allows computing the result of the intersection of filtering queries with some Infinite configurations (see ConfigurationInterface, WorkingSetInterface) and optionally other WorkingSetInterface(s). Available configurations (created by the 3djuump Infinite maintainer) are accessed through getConfigurationList, they are then "included" by id in a WorkingSetInterface.DMU statistics (Axis Aligned Bounding Box (AABB) of each
geometric instance, diagonal length of eachgeometric instance, min/max of diagonal length, DMU AABB, DMU Unit, maximumgeometric instance id, maximumpart instance id) and the metadata dictionary (AttributesDictionaryInterface) are accessed through the DataSessionInterface.or asynchronously :
The DataSessionInterface may be bound to an InfiniteEngineInterface in order to provide a rendering of the DMU.
Primary / Secondary session mechanism.
The same DataSessionInterface may be shared upon multiple tabs. In order to do so, one DataSessionInterface plays the role of the 'primary' session while others play the role of secondary sessions. A secondary DirectorySessionInterface must be created and opened with DirectorySessionInterface.openSecondaryDirectorySession, and a new DataSessionInterface must be created from the secondary DirectorySessionInterface. The secondary DataSessionInterface must be opened with openSecondaryDataSession, and regularly updated with setTokenValues when the primary DataSessionInterface triggers a DataSessionInterfaceSignal.TokenUpdated (and bearers are retrieved with getDataSessionBearer, and getExtendedDataSessionBearer).
or asynchronously :
Please keep in mind that only a finite number of secondary DataSessionInterface may be created, indeed, creating a secondary DataSessionInterface holds resources on the primary DataSessionInterface. Thus, it is required to call unregisterSecondaryDataSession on the primary DataSessionInterface when a secondary DataSessionInterface is no longer in use.
See
DataSessionInterfaceSignal