mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-06 08:25:19 +01:00
184 lines
4.3 KiB
TypeScript
184 lines
4.3 KiB
TypeScript
import {setSketchPrecision} from './sketch/sketchReader';
|
|
import {runSandbox} from './sandbox';
|
|
import {LOG_FLAGS} from './logFlags';
|
|
import {CoreContext} from "context";
|
|
import {SketchFormat_V3} from "../sketcher/io";
|
|
import {OperationRequest} from "./craft/craftPlugin";
|
|
import {ProjectModel} from "./projectManager/projectManagerPlugin";
|
|
import {DebugMode$} from "debugger/Debugger";
|
|
import {fillUpMissingFields} from "cad/craft/schema/initializeBySchema";
|
|
|
|
export const STORAGE_GLOBAL_PREFIX = 'TCAD';
|
|
export const PROJECTS_PREFIX = `${STORAGE_GLOBAL_PREFIX}.projects.`;
|
|
export const SKETCH_SUFFIX = '.sketch.';
|
|
|
|
|
|
export function activate(ctx: CoreContext) {
|
|
|
|
const [id, hints] = parseHintsFromLocation();
|
|
|
|
initProjectService(ctx, id, hints);
|
|
}
|
|
|
|
export function initProjectService(ctx: CoreContext, id: string, hints: any) {
|
|
|
|
processParams(hints, ctx);
|
|
|
|
const sketchNamespace = id + SKETCH_SUFFIX;
|
|
const sketchStorageNamespace = PROJECTS_PREFIX + sketchNamespace;
|
|
|
|
function sketchStorageKey(sketchIdId) {
|
|
return sketchStorageNamespace + sketchIdId;
|
|
}
|
|
|
|
function projectStorageKey() {
|
|
return PROJECTS_PREFIX + id;
|
|
}
|
|
|
|
function getSketchURL(sketchId) {
|
|
return sketchNamespace + sketchId;
|
|
}
|
|
|
|
function save() {
|
|
let data = {
|
|
history: ctx.craftService.modifications$.value.history,
|
|
expressions: ctx.expressionService.script$.value,
|
|
|
|
// @ts-ignore we deliberately don't uplift the type to the ApplicationContext in order to be able to use ProjectService in the headless mode
|
|
assembly: ctx.assemblyService && ctx.assemblyService.getConstraints()
|
|
};
|
|
ctx.storageService.set(projectStorageKey(), JSON.stringify(data));
|
|
}
|
|
|
|
function load() {
|
|
try {
|
|
let dataStr = ctx.storageService.get(ctx.projectService.projectStorageKey());
|
|
if (dataStr) {
|
|
let data = JSON.parse(dataStr);
|
|
upgradeIfNeeded(data);
|
|
loadData(data);
|
|
}
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
}
|
|
|
|
function upgradeIfNeeded(data: ProjectModel) {
|
|
if (data.history) {
|
|
data.history.forEach(req => {
|
|
const operation = ctx.operationService.get(req.type);
|
|
if (operation) {
|
|
fillUpMissingFields(req.params, operation.schema, ctx);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function loadData(data: ProjectModel) {
|
|
if (data.expressions) {
|
|
ctx.expressionService.load(data.expressions);
|
|
}
|
|
if (data.history) {
|
|
ctx.craftService.reset(data.history);
|
|
}
|
|
|
|
// @ts-ignore we deliberately don't uplift the type to the ApplicationContext in order to be able to use ProjectService in the headless mode
|
|
if (data.assembly && ctx.assemblyService) {
|
|
// @ts-ignore
|
|
ctx.assemblyService.loadConstraints(data.assembly);
|
|
}
|
|
|
|
}
|
|
|
|
function empty() {
|
|
loadData({
|
|
history: [],
|
|
expressions: ""
|
|
});
|
|
}
|
|
|
|
ctx.projectService = {
|
|
id, sketchStorageKey, projectStorageKey, sketchStorageNamespace, getSketchURL, save, load, loadData, empty,
|
|
hints
|
|
};
|
|
|
|
}
|
|
|
|
function parseHintsFromLocation() {
|
|
let hints = window.location.hash.substring(1);
|
|
if (!hints) {
|
|
hints = window.location.search.substring(1);
|
|
}
|
|
if (!hints) {
|
|
hints = "DEFAULT";
|
|
}
|
|
return parseHints(hints);
|
|
}
|
|
|
|
function parseHints(hints) {
|
|
let [id, ...paramsArr] = hints.split('&');
|
|
let params = paramsArr.reduce((params, part) => {
|
|
let [key, value] = part.split('=');
|
|
if (key) {
|
|
if (!value) {
|
|
value = true;
|
|
}
|
|
params[key] = value;
|
|
}
|
|
return params;
|
|
}, {});
|
|
return [id, params];
|
|
}
|
|
|
|
function processParams(params, context) {
|
|
if (params.sketchPrecision) {
|
|
setSketchPrecision(parseInt(params.sketchPrecision));
|
|
}
|
|
if (params.sandbox) {
|
|
setTimeout(() => runSandbox(context));
|
|
}
|
|
|
|
const LOG_FLAGS_PREFIX = "LOG.";
|
|
Object.keys(params).forEach(key => {
|
|
if (key.startsWith(LOG_FLAGS_PREFIX)) {
|
|
LOG_FLAGS[key.substring(LOG_FLAGS_PREFIX.length)] = true
|
|
}
|
|
});
|
|
|
|
if (params.debug) {
|
|
DebugMode$.next(true);
|
|
}
|
|
}
|
|
|
|
export interface ProjectService {
|
|
|
|
readonly id: string;
|
|
|
|
readonly sketchStorageNamespace: string;
|
|
|
|
hints: any;
|
|
|
|
sketchStorageKey(sketchId: string): string;
|
|
|
|
projectStorageKey(): string
|
|
|
|
getSketchURL(sketchId: string): string
|
|
|
|
save(): void;
|
|
|
|
load(): void
|
|
|
|
loadData(data: ProjectModel);
|
|
|
|
empty(): void;
|
|
|
|
}
|
|
|
|
declare module 'context' {
|
|
interface CoreContext {
|
|
|
|
projectService: ProjectService;
|
|
}
|
|
}
|
|
|
|
|