Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Commit

Permalink
fix: ensure proper ser/de of pattern data
Browse files Browse the repository at this point in the history
  • Loading branch information
marionebl committed Sep 10, 2018
1 parent 80875c3 commit 9388d66
Show file tree
Hide file tree
Showing 15 changed files with 96 additions and 22 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions src/alva-util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
29 changes: 28 additions & 1 deletion src/alva-util/parse-json.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as Types from '../types';

export type ParseResult<T> = ParseSuccess<T> | ParseError;

export interface ParseSuccess<T> {
Expand All @@ -22,7 +24,32 @@ export function parseJSON<T>(data: string): ParseResult<T> {
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 {
Expand Down
11 changes: 11 additions & 0 deletions src/alva-util/to-json.ts
Original file line number Diff line number Diff line change
@@ -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;
});
}
2 changes: 1 addition & 1 deletion src/electron/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion src/model/element/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ export class Element {
if (!this.pattern) {
return [];
}

return this.pattern.getProperties();
}

Expand Down
6 changes: 6 additions & 0 deletions src/model/pattern-library/pattern-library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
1 change: 1 addition & 0 deletions src/model/pattern/pattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export class Pattern {
};
}

@Mobx.action
public update(pattern: Pattern, context?: PatternContext): void {
this.contextId = pattern.getContextId();
this.description = pattern.getDescription();
Expand Down
23 changes: 12 additions & 11 deletions src/model/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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()];
}
Expand Down Expand Up @@ -696,10 +705,6 @@ export class Project {
};
}

public toString(): string {
return JSON.stringify(this.toJSON());
}

public sync(sender: Types.Sender): void {
sender.match<Message.MobxUpdateMessage>(Message.MessageType.MobxUpdate, message => {
if (
Expand All @@ -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;
}

Expand All @@ -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;
}
});

Expand All @@ -759,7 +763,6 @@ export class Project {
const ValueModel = ModelTree.getModelByName(message.payload.valueModel);

if (!parent) {
console.log('no parent', message);
return;
}

Expand All @@ -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<unknown, unknown>;
Expand All @@ -785,7 +788,6 @@ export class Project {
const parent = this.getObject(message.payload.name, message.payload.id);

if (!parent) {
console.log(message);
return;
}

Expand All @@ -804,7 +806,6 @@ export class Project {
const ValueModel = ModelTree.getModelByName(message.payload.valueModel);

if (!parent) {
console.log('no parent', message);
return;
}

Expand Down
3 changes: 2 additions & 1 deletion src/preview-document/preview-document.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as Types from '../types';
import * as AlvaUtil from '../alva-util';

export interface PreviewDocumentConfig {
data: Types.SerializedProject;
Expand Down Expand Up @@ -115,7 +116,7 @@ export const previewDocument = (config: PreviewDocumentConfig) => `<!doctype htm
<div id="preview-selection"></div>
<div id="preview-highlight"></div>
<textarea data-data="alva" style="display: none">${encodeURIComponent(
JSON.stringify({
AlvaUtil.toJSON({
data: config.data,
mode: Types.PreviewDocumentMode.Live
})
Expand Down
3 changes: 2 additions & 1 deletion src/preview-document/sketch-document.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as Fs from 'fs';
import * as Path from 'path';
import * as Types from '../types';
import * as AlvaUtil from '../alva-util';

const SCRIPT_PATHS = [
require.resolve('../scripts/exportToSketchData'),
Expand Down Expand Up @@ -43,7 +44,7 @@ const doc = (config: SketchDocumentConfig) => `<!doctype html>
<body>
<div id="preview"></div>
<textarea data-data="alva" style="display: none">${encodeURIComponent(
JSON.stringify({
AlvaUtil.toJSON({
data: config.data,
mode: Types.PreviewDocumentMode.Static
})
Expand Down
3 changes: 2 additions & 1 deletion src/preview-document/static-document.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as Fs from 'fs';
import * as Path from 'path';
import * as Types from '../types';
import * as AlvaUtil from '../alva-util';

const SCRIPT_PATHS = [
require.resolve('../scripts/Mobx'),
Expand Down Expand Up @@ -42,7 +43,7 @@ const doc = (config: StaticDocumentConfig) => `<!doctype html>
<body>
<div id="preview"></div>
<textarea data-data="alva" style="display: none">${encodeURIComponent(
JSON.stringify({
AlvaUtil.toJSON({
data: config.data,
mode: Types.PreviewDocumentMode.Static
})
Expand Down
25 changes: 22 additions & 3 deletions src/renderer/create-notifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import * as Model from '../model';
import { ViewStore } from '../store';
import * as Types from '../types';
import * as uuid from 'uuid';
import * as isPlainObject from 'is-plain-object';

export interface NotifierContext {
app: Model.AlvaApp;
store: ViewStore;
}

export function createNotifiers({ store }: NotifierContext): void {
export function createNotifiers({ app, store }: NotifierContext): void {
const opts = {
scheduler: window.requestIdleCallback
};
Expand Down Expand Up @@ -80,6 +81,7 @@ export function createNotifiers({ store }: NotifierContext): void {

if (change.hasOwnProperty('index')) {
console.log('ArrayUpdate:', change);
return;
}

if (change.hasOwnProperty('key') && !(change.object instanceof Mobx.ObservableMap)) {
Expand All @@ -106,6 +108,7 @@ export function createNotifiers({ store }: NotifierContext): void {
const name = parseChangeName(change.name);

const parent = getParentByMember(change.object, {
app,
name: change.name,
project
});
Expand Down Expand Up @@ -140,13 +143,15 @@ export function createNotifiers({ store }: NotifierContext): void {
}

const parent = getParentByMember(change.object, {
app,
name: change.name,
project
});

const name = parseChangeName(change.name);

if (!parent) {
console.log('no parent', change);
return;
}

Expand All @@ -158,7 +163,7 @@ export function createNotifiers({ store }: NotifierContext): void {
? rawValue.toJSON()
: change.newValue;

if (typeof newValue === 'object' && !newValue.model) {
if (isPlainObject(newValue) && !newValue.model) {
return;
}

Expand All @@ -183,6 +188,7 @@ export function createNotifiers({ store }: NotifierContext): void {

case Types.MobxChangeType.Delete: {
const parent = getParentByMember(change.object, {
app,
name: change.name,
project
});
Expand Down Expand Up @@ -212,6 +218,7 @@ export function createNotifiers({ store }: NotifierContext): void {

case Types.MobxChangeType.Splice: {
const parent = getParentByMember(change.object, {
app,
name: change.name,
project
});
Expand Down Expand Up @@ -253,22 +260,28 @@ export function createNotifiers({ store }: NotifierContext): void {

function getParentByMember(
member: unknown,
{ name, project }: { name: string; project: Model.Project }
{ app, name, project }: { app: Model.AlvaApp; name: string; project: Model.Project }
): Model.AnyModel | undefined {
const { parentName, parentId } = parseChangeName(name);

switch (parentName) {
case 'AlvaApp':
return app;
case 'Project':
return project;
case 'UserStore':
return project.getUserStore();
case 'Element':
case 'ElementContent':
case 'Pattern':
case 'PatternLibrary':
case 'PatternEnumProperty':
return getObjectsByName(parentName, { project }).find((e: unknown) => {
const admin = Mobx._getAdministration(e);
return admin.name === parentId;
});
default:
console.log(parentName);
return;
}
}
Expand All @@ -279,6 +292,12 @@ function getObjectsByName(name: string, { project }: { project: Model.Project })
return project.getElements();
case 'ElementContent':
return project.getElementContents();
case 'PatternLibrary':
return project.getPatternLibraries();
case 'PatternEnumProperty':
return project.getPatternProperties();
case 'Pattern':
return project.getPatterns();
}

return [];
Expand Down
5 changes: 3 additions & 2 deletions src/sender/serde.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export interface MessageHeader {
}

export function serialize(message: Message.Message): string {
const headerData = JSON.stringify({ type: message.type });
const headerData = AlvaUtil.toJSON({ type: message.type });

const headerLength = headerData.length.toString();

if (headerLength.length > OVERTURE_LENGTH) {
Expand All @@ -32,7 +33,7 @@ export function serialize(message: Message.Message): string {
}

const length = _.padStart(headerLength, OVERTURE_LENGTH, '0');
return [length, headerData, JSON.stringify(message)].join('');
return [length, headerData, AlvaUtil.toJSON(message)].join('');
}

export function deserialize(data: string): Message.Message | undefined {
Expand Down
4 changes: 4 additions & 0 deletions src/types/serialized-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,7 @@ export interface SerializedElementActionPayload {
type: Types.ElementActionPayloadType;
value: string;
}

export enum SerialializationType {
Set = 'Set'
}

0 comments on commit 9388d66

Please sign in to comment.