UNPKG

@speckle/shared

Version:

Shared code between various Speckle JS packages

160 lines 6.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.formatSerializedViewerState = exports.isSerializedViewerState = exports.SERIALIZED_VIEWER_STATE_VERSION = void 0; const _lodash_1 = require("#lodash"); const index_js_1 = require("../errors/index.js"); const index_js_2 = require("../../core/index.js"); /** Redefining these is unfortunate. Especially since they are not part of viewer-core */ var MeasurementType; (function (MeasurementType) { MeasurementType[MeasurementType["PERPENDICULAR"] = 0] = "PERPENDICULAR"; MeasurementType[MeasurementType["POINTTOPOINT"] = 1] = "POINTTOPOINT"; MeasurementType[MeasurementType["AREA"] = 2] = "AREA"; MeasurementType[MeasurementType["POINT"] = 3] = "POINT"; })(MeasurementType || (MeasurementType = {})); /** * v1 -> v1.1 * - ui.filters.propertyFilter.isApplied field added * - ui.spotlightUserId swapped for spotlightUserSessionId * v1.1 -> v1.2 * - ui.diff added * v1.2 -> v1.3 * - ui.filters.selectedObjectIds removed in favor of ui.filters.selectedObjectApplicationIds */ exports.SERIALIZED_VIEWER_STATE_VERSION = 1.3; /** * Note: This only does superficial validation. To really ensure that all of the keys are there, even if prefilled with default values, make sure you invoke * formatSerializedViewerState() on the state afterwards */ const isSerializedViewerState = (val) => { if (!val) return false; const keys = [ 'projectId', 'sessionId', 'resources', 'ui', 'viewer' ]; if (!(0, _lodash_1.isObjectLike)(val)) return false; const valKeys = Object.keys(val); if ((0, _lodash_1.intersection)(valKeys, keys).length !== keys.length) return false; return true; }; exports.isSerializedViewerState = isSerializedViewerState; const initializeMissingData = (state) => { const throwInvalidError = (missingPath) => { throw new index_js_1.UnformattableSerializedViewerStateError('Required data missing from SerializedViewerState: ' + missingPath); }; const defaultMeasurementOptions = { visible: false, type: MeasurementType.POINTTOPOINT, vertexSnap: false, units: 'm', precision: 2 }; const measurementOptions = { ...defaultMeasurementOptions, ...state.ui?.measurement?.options }; const selectedObjectApplicationIds = { // Parse legacy object ids array as object ...(state.ui?.filters?.selectedObjectIds?.reduce((ret, id) => { ret[id] = null; return ret; }, {}) ?? {}), // Sanitize incoming object ...(0, index_js_2.coerceUndefinedValuesToNull)(state.ui?.filters?.selectedObjectApplicationIds || {}) }; return { projectId: state.projectId || throwInvalidError('projectId'), sessionId: state.sessionId || `nullSessionId-${Math.random() * 1000}`, viewer: { ...(state.viewer || {}), metadata: { ...(state.viewer?.metadata || {}), filteringState: state.viewer?.metadata?.filteringState || null } }, resources: { ...(state.resources || {}), request: { ...(state.resources?.request || {}), resourceIdString: state.resources?.request?.resourceIdString || throwInvalidError('resources.request.resourceIdString'), threadFilters: { ...(state.resources?.request?.threadFilters || {}), includeArchived: state.resources?.request?.threadFilters?.includeArchived || false, loadedVersionsOnly: state.resources?.request?.threadFilters?.loadedVersionsOnly || false } } }, ui: { ...(state.ui || {}), threads: { ...(state.ui?.threads || {}), openThread: { ...(state.ui?.threads?.openThread || {}), threadId: state.ui?.threads?.openThread?.threadId || null, isTyping: state.ui?.threads?.openThread?.isTyping || false, newThreadEditor: state.ui?.threads?.openThread?.newThreadEditor || false } }, diff: { ...(state.ui?.diff || {}), command: state.ui?.diff?.command || null, time: state.ui?.diff?.time || 0.5, mode: state.ui?.diff?.mode || 1 }, spotlightUserSessionId: state.ui?.spotlightUserSessionId || null, filters: { ...(state.ui?.filters || {}), isolatedObjectIds: state.ui?.filters?.isolatedObjectIds || [], hiddenObjectIds: state.ui?.filters?.hiddenObjectIds || [], selectedObjectApplicationIds, propertyFilter: { ...(state.ui?.filters?.propertyFilter || {}), key: state.ui?.filters?.propertyFilter?.key || null, isApplied: state.ui?.filters?.propertyFilter?.isApplied || false } }, camera: { ...(state.ui?.camera || {}), position: state.ui?.camera?.position || throwInvalidError('ui.camera.position'), target: state.ui?.camera?.target || throwInvalidError('ui.camera.target'), isOrthoProjection: state.ui?.camera?.isOrthoProjection || false, zoom: state.ui?.camera?.zoom || 1 }, viewMode: state.ui?.viewMode || 0, sectionBox: state.ui?.sectionBox?.min?.length && state.ui?.sectionBox.max?.length ? // Complains otherwise state.ui.sectionBox : null, lightConfig: { ...(state.ui?.lightConfig || {}), intensity: state.ui?.lightConfig?.intensity, indirectLightIntensity: state.ui?.lightConfig?.indirectLightIntensity, elevation: state.ui?.lightConfig?.elevation, azimuth: state.ui?.lightConfig?.azimuth }, explodeFactor: state.ui?.explodeFactor || 0, selection: state.ui?.selection || null, measurement: { enabled: state.ui?.measurement?.enabled ?? false, options: measurementOptions } } }; }; /** * Formats SerializedViewerState by bringing it up to date with the structure of the latest version * and ensuring missing keys are initialized with default values */ const formatSerializedViewerState = (state) => { const finalState = initializeMissingData(state); return finalState; }; exports.formatSerializedViewerState = formatSerializedViewerState; //# sourceMappingURL=state.js.map