diff --git a/package.json b/package.json index 035a1fe49..064cad697 100644 --- a/package.json +++ b/package.json @@ -175,6 +175,7 @@ "get-port": "3.2.0", "glob-parent": "3.1.0", "import-fresh": "2.0.0", + "is-plain-object": "2.0.4", "js-string-escape": "1.0.1", "js-yaml": "3.11.0", "loader-utils": "1.1.0", diff --git a/src/alva-util/index.ts b/src/alva-util/index.ts index a830cd2ab..91ede8520 100644 --- a/src/alva-util/index.ts +++ b/src/alva-util/index.ts @@ -3,4 +3,5 @@ export * from './ensure-array'; export * from './guess-name'; export * from './noop'; export * from './parse-json'; +export * from './to-json'; export * from './set-search'; diff --git a/src/alva-util/parse-json.ts b/src/alva-util/parse-json.ts index 14fe9cc4d..359163e01 100644 --- a/src/alva-util/parse-json.ts +++ b/src/alva-util/parse-json.ts @@ -1,3 +1,5 @@ +import * as Types from '../types'; + export type ParseResult = ParseSuccess | ParseError; export interface ParseSuccess { @@ -22,7 +24,32 @@ export function parseJSON(data: string): ParseResult { return { type: ParseResultType.Success, data, - result: JSON.parse(data) + result: JSON.parse(data, (key, value: unknown) => { + if (typeof value !== 'object' || value === null) { + return value; + } + + const ob = value as object; + + if (!ob.hasOwnProperty('type') || !ob.hasOwnProperty('data')) { + return value; + } + + const candidate = ob as { type: unknown; data: unknown }; + + if (typeof candidate.type !== 'string' || !Array.isArray(candidate.data)) { + return value; + } + + const refined = ob as { type: string; data: unknown[] }; + + switch (refined.type) { + case Types.SerialializationType.Set: + return new Set(refined.data); + default: + return value; + } + }) }; } catch (error) { return { diff --git a/src/alva-util/to-json.ts b/src/alva-util/to-json.ts new file mode 100644 index 000000000..495da2f36 --- /dev/null +++ b/src/alva-util/to-json.ts @@ -0,0 +1,11 @@ +import * as Types from '../types'; + +export function toJSON(input: unknown): string { + return JSON.stringify(input, (_, value) => { + if (value instanceof Set) { + return { type: Types.SerialializationType.Set, data: Array.from(value) }; + } + + return value; + }); +} diff --git a/src/electron/clipboard.ts b/src/electron/clipboard.ts index 5a98104d3..5d2a3aa2a 100644 --- a/src/electron/clipboard.ts +++ b/src/electron/clipboard.ts @@ -8,7 +8,7 @@ export function setClipboard(payload: Message.Clipboard['payload']): void { Electron.clipboard.writeBuffer( 'application/alva', Buffer.from( - JSON.stringify({ + AlvaUtil.toJSON({ type: Message.MessageType.Clipboard, id: uuid.v4(), payload diff --git a/src/model/element/element.ts b/src/model/element/element.ts index 0c07dba7b..1e567d42c 100644 --- a/src/model/element/element.ts +++ b/src/model/element/element.ts @@ -129,7 +129,6 @@ export class Element { if (!this.pattern) { return []; } - return this.pattern.getProperties(); } diff --git a/src/model/pattern-library/pattern-library.ts b/src/model/pattern-library/pattern-library.ts index ed823d08b..bedaa98e1 100644 --- a/src/model/pattern-library/pattern-library.ts +++ b/src/model/pattern-library/pattern-library.ts @@ -201,11 +201,17 @@ export class PatternLibrary { return isEqual(this.toJSON(), b.toJSON()); } + @Mobx.action public addPattern(pattern: Pattern): void { this.patterns.set(pattern.getId(), pattern); } + @Mobx.action public addProperty(property: AnyPatternProperty): void { + if (property.getPropertyName() === 'thing') { + console.log('addProperty', property); + } + this.patternProperties.set(property.getId(), property); } diff --git a/src/model/pattern/pattern.ts b/src/model/pattern/pattern.ts index 0d394b96a..4f1c58160 100644 --- a/src/model/pattern/pattern.ts +++ b/src/model/pattern/pattern.ts @@ -151,6 +151,7 @@ export class Pattern { }; } + @Mobx.action public update(pattern: Pattern, context?: PatternContext): void { this.contextId = pattern.getContextId(); this.description = pattern.getDescription(); diff --git a/src/model/project.ts b/src/model/project.ts index d51022c46..bee3861de 100644 --- a/src/model/project.ts +++ b/src/model/project.ts @@ -15,6 +15,7 @@ import * as Types from '../types'; import { UserStore } from './user-store'; import { UserStoreEnhancer, defaultCode, defaultJavaScript } from './user-store-enhancer'; import { UserStoreReference } from './user-store-reference'; +import * as isPlainObject from 'is-plain-object'; import * as uuid from 'uuid'; export interface ProjectProperties { @@ -463,6 +464,14 @@ export class Project { return this.patterns.find(p => p.getId() === id); } + public getPatterns(): Pattern[] { + return this.patterns; + } + + public getPatternProperties(): AnyPatternProperty[] { + return this.patternProperties; + } + public getPatternLibraries(): PatternLibrary[] { return [...this.patternLibraries.values()]; } @@ -696,10 +705,6 @@ export class Project { }; } - public toString(): string { - return JSON.stringify(this.toJSON()); - } - public sync(sender: Types.Sender): void { sender.match(Message.MessageType.MobxUpdate, message => { if ( @@ -726,7 +731,7 @@ export class Project { ? ValueModel.from(change.newValue, { project: this }) : change.newValue; - if (typeof value === 'object' && !ValueModel) { + if (isPlainObject(value) && !ValueModel) { return; } @@ -750,7 +755,6 @@ export class Project { if (message.payload.change.hasOwnProperty('index')) { console.log('MobxArrayUpdatePayload', message); - // const change = message.payload.change as Message.MobxArrayUpdatePayload; } }); @@ -759,7 +763,6 @@ export class Project { const ValueModel = ModelTree.getModelByName(message.payload.valueModel); if (!parent) { - console.log('no parent', message); return; } @@ -773,8 +776,8 @@ export class Project { ? ValueModel.from(message.payload.change.newValue, { project: this }) : message.payload.change.newValue; - if (typeof value === 'object' && !ValueModel) { - console.log('no value model', message); + if (isPlainObject(value) && !ValueModel) { + return; } const member = mayBeMember as Map; @@ -785,7 +788,6 @@ export class Project { const parent = this.getObject(message.payload.name, message.payload.id); if (!parent) { - console.log(message); return; } @@ -804,7 +806,6 @@ export class Project { const ValueModel = ModelTree.getModelByName(message.payload.valueModel); if (!parent) { - console.log('no parent', message); return; } diff --git a/src/preview-document/preview-document.ts b/src/preview-document/preview-document.ts index b729b4cb2..9e991d4f9 100644 --- a/src/preview-document/preview-document.ts +++ b/src/preview-document/preview-document.ts @@ -1,4 +1,5 @@ import * as Types from '../types'; +import * as AlvaUtil from '../alva-util'; export interface PreviewDocumentConfig { data: Types.SerializedProject; @@ -115,7 +116,7 @@ export const previewDocument = (config: PreviewDocumentConfig) => `