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

Commit

Permalink
Merge pull request #781 from aerogear/mutations-express
Browse files Browse the repository at this point in the history
  • Loading branch information
wtrocki authored Aug 25, 2020
2 parents c778323 + a994b6b commit 2e87e49
Show file tree
Hide file tree
Showing 16 changed files with 160 additions and 131 deletions.
1 change: 0 additions & 1 deletion examples/react-datastore/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useState, useEffect } from 'react';
import { CRUDEvents } from 'offix-datastore';
import { Button } from 'antd';
import 'antd/dist/antd.css';

Expand Down
8 changes: 4 additions & 4 deletions examples/react-datastore/src/components/forms/ToggleTodo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ToggleTodoProps } from "../../types";
import { schema } from './formSchema';
import { useEditTodo } from '../../datastore/hooks';

export function ToggleTodo ({ todo }: ToggleTodoProps) {
export function ToggleTodo({ todo }: ToggleTodoProps) {

const { update: editTodo } = useEditTodo();

Expand All @@ -14,11 +14,11 @@ export function ToggleTodo ({ todo }: ToggleTodoProps) {
...todo,
completed: !todo.completed,
})
.then((res: any) => console.log(res))
.catch((error: any) => console.log(error));
.then((res: any) => console.log("response", res))
.catch((error: any) => console.log("error", error));
};

return(
return (
<QuickForm schema={schema}>
<BoolField
label={todo.title}
Expand Down
12 changes: 1 addition & 11 deletions examples/react-datastore/src/datastore/generated/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@
"type": "string",
"key": "_version",
"isRequired": true
},
"_deleted": {
"type": "string",
"key": "_version",
"isRequired": true
}
}
},
Expand All @@ -56,12 +51,7 @@
"type": "string",
"key": "_version",
"isRequired": true
},
"_deleted": {
"type": "string",
"key": "_version",
"isRequired": true
}
}
}
}
}
2 changes: 0 additions & 2 deletions examples/react-datastore/src/datastore/generated/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export interface Todo {
description?: string;
completed?: boolean
_version: number;
_deleted: boolean;
}

export type TodoCreate = Omit<Todo, "_id">;
Expand All @@ -14,7 +13,6 @@ export interface User {
_id: string;
name: string
_version: number;
_deleted: boolean;
}

export type UserCreate = Omit<User, "_id">;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ const getModelProperties = (model: ModelDefinition, primaryKey: string) => {
key: "_version",
isRequired: true
};
generatedProperties._deleted = {
type: "string",
key: "_version",
isRequired: true
};
return generatedProperties;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export const createModelType = (model: ModelDefinition) => {
return `export interface ${modelName} {
${getModelProperties(model)}
_version: number;
_deleted: boolean;
}
export type ${modelName}Create = ${primaryKey ? `Omit<${modelName}, "${primaryKey}">` : modelName};
Expand Down
24 changes: 0 additions & 24 deletions packages/datastore/cli/tests/__snapshots__/Cli.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ exports[`generate with defaults 1`] = `
description: string;
comments: string[]
_version: number;
_deleted: boolean;
}
export type NoteCreate = Omit<Note, \\"_id\\">;
Expand All @@ -19,7 +18,6 @@ export interface Comment {
description: string;
noteComment: string
_version: number;
_deleted: boolean;
}
export type CommentCreate = Omit<Comment, \\"_id\\">;
Expand Down Expand Up @@ -60,11 +58,6 @@ exports[`generate with defaults 2`] = `
\\"type\\": \\"string\\",
\\"key\\": \\"_version\\",
\\"isRequired\\": true
},
\\"_deleted\\": {
\\"type\\": \\"string\\",
\\"key\\": \\"_version\\",
\\"isRequired\\": true
}
}
},
Expand Down Expand Up @@ -99,11 +92,6 @@ exports[`generate with defaults 2`] = `
\\"type\\": \\"string\\",
\\"key\\": \\"_version\\",
\\"isRequired\\": true
},
\\"_deleted\\": {
\\"type\\": \\"string\\",
\\"key\\": \\"_version\\",
\\"isRequired\\": true
}
}
}
Expand All @@ -127,7 +115,6 @@ exports[`generate with positional arguments 1`] = `
description: string;
comments: string[]
_version: number;
_deleted: boolean;
}
export type NoteCreate = Omit<Note, \\"_id\\">;
Expand All @@ -139,7 +126,6 @@ export interface Comment {
description: string;
noteComment: string
_version: number;
_deleted: boolean;
}
export type CommentCreate = Omit<Comment, \\"_id\\">;
Expand Down Expand Up @@ -180,11 +166,6 @@ exports[`generate with positional arguments 2`] = `
\\"type\\": \\"string\\",
\\"key\\": \\"_version\\",
\\"isRequired\\": true
},
\\"_deleted\\": {
\\"type\\": \\"string\\",
\\"key\\": \\"_version\\",
\\"isRequired\\": true
}
}
},
Expand Down Expand Up @@ -219,11 +200,6 @@ exports[`generate with positional arguments 2`] = `
\\"type\\": \\"string\\",
\\"key\\": \\"_version\\",
\\"isRequired\\": true
},
\\"_deleted\\": {
\\"type\\": \\"string\\",
\\"key\\": \\"_version\\",
\\"isRequired\\": true
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion packages/datastore/datastore/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
## offix-client-store
## offix-data-store

This project is in early beta. breaking changes may still occur.

Documentation:

Expand Down
44 changes: 13 additions & 31 deletions packages/datastore/datastore/src/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ export class Model<T = unknown> {
public schema: ModelSchema<T>;
public replicationConfig: ModelReplicationConfig | undefined;
public replication?: ModelChangeReplication;
public changeEventStream: PushStream<StoreChangeEvent>;
private storage: LocalStorage;
private changeEventStream: PushStream<StoreChangeEvent>;

constructor(
schema: ModelSchema<T>,
Expand Down Expand Up @@ -101,20 +101,17 @@ export class Model<T = unknown> {
}

public async save(input: Partial<T>): Promise<T> {
const db = await this.storage.createTransaction();
input = this.addPrimaryKeyIfNeeded(input);
try {
const data = await db.save(this.schema.getStoreName(), input);
await this.replication?.saveChangeForReplication(this, data, CRUDEvents.ADD, db);
await db.commit();
const data = await this.storage.save(this.schema.getStoreName(), input);
await this.replication?.saveChangeForReplication(this, data, CRUDEvents.ADD, this.storage);
const event = {
eventType: CRUDEvents.ADD,
data: [data]
};
this.changeEventStream.publish(event);
return data;
} catch (error) {
await db.rollback();
throw error;
}
}
Expand All @@ -126,20 +123,17 @@ export class Model<T = unknown> {
* @param input
*/
public async saveOrUpdate(input: Partial<T>): Promise<T> {
const db = await this.storage.createTransaction();
input = this.addPrimaryKeyIfNeeded(input);
try {
const data = await db.saveOrUpdate(this.schema.getStoreName(), this.schema.getPrimaryKey(), input);
await this.replication?.saveChangeForReplication(this, data, CRUDEvents.ADD, db);
await db.commit();
const data = await this.storage.saveOrUpdate(this.schema.getStoreName(), this.schema.getPrimaryKey(), input);
await this.replication?.saveChangeForReplication(this, data, CRUDEvents.ADD, this.storage);
const event = {
eventType: CRUDEvents.ADD,
data: [data]
};
this.changeEventStream.publish(event);
return data;
} catch (error) {
await db.rollback();
throw error;
}
}
Expand All @@ -152,19 +146,16 @@ export class Model<T = unknown> {
*/
public async update(input: Partial<T>, filter?: Filter<T>) {
invariant(filter, "filter needs to be provided for update");
const db = await this.storage.createTransaction();
try {
const data = await db.update(this.schema.getStoreName(), input, filter);
await this.replication?.saveChangeForReplication(this, data, CRUDEvents.UPDATE, db);
await db.commit();
const data = await this.storage.update(this.schema.getStoreName(), input, filter);
await this.replication?.saveChangeForReplication(this, data, CRUDEvents.UPDATE, this.storage);
const event = {
eventType: CRUDEvents.UPDATE,
data
};
this.changeEventStream.publish(event);
return data;
} catch (error) {
await db.rollback();
throw error;
}
}
Expand All @@ -178,19 +169,16 @@ export class Model<T = unknown> {
const primaryKey = this.schema.getPrimaryKey();
invariant((input as any)[primaryKey], "Missing primary key for update");

const db = await this.storage.createTransaction();
try {
const data = await db.updateById(this.schema.getStoreName(), this.schema.getPrimaryKey(), input);
await this.replication?.saveChangeForReplication(this, data, CRUDEvents.UPDATE, db);
await db.commit();
const data = await this.storage.updateById(this.schema.getStoreName(), this.schema.getPrimaryKey(), input);
await this.replication?.saveChangeForReplication(this, data, CRUDEvents.UPDATE, this.storage);
const event = {
eventType: CRUDEvents.UPDATE,
data: [data]
};
this.changeEventStream.publish(event);
return data;
} catch (error) {
await db.rollback();
throw error;
}
}
Expand All @@ -202,20 +190,17 @@ export class Model<T = unknown> {
*/
public async remove(filter: Filter<T>) {
invariant(filter, "filter needs to be provided for deletion");
const db = await this.storage.createTransaction();
try {
const primaryKey = this.schema.getPrimaryKey();
const data = await db.remove(this.schema.getStoreName(), primaryKey, filter);
await this.replication?.saveChangeForReplication(this, data, CRUDEvents.DELETE, db);
await db.commit();
const data = await this.storage.remove(this.schema.getStoreName(), primaryKey, filter);
await this.replication?.saveChangeForReplication(this, data, CRUDEvents.DELETE, this.storage);
const event = {
eventType: CRUDEvents.DELETE,
data
};
this.changeEventStream.publish(event);
return data;
} catch (error) {
await db.rollback();
throw error;
}
}
Expand All @@ -230,11 +215,9 @@ export class Model<T = unknown> {
const primaryKey = this.schema.getPrimaryKey();
invariant((input as any)[primaryKey], "Missing primary key for delete");

const db = await this.storage.createTransaction();
try {
const data = await db.removeById(this.schema.getStoreName(), this.schema.getPrimaryKey(), input);
await this.replication?.saveChangeForReplication(this, data, CRUDEvents.DELETE, db);
await db.commit();
const data = await this.storage.removeById(this.schema.getStoreName(), this.schema.getPrimaryKey(), input);
await this.replication?.saveChangeForReplication(this, data, CRUDEvents.DELETE, this.storage);
const event = {
eventType: CRUDEvents.DELETE,
// TODO Why array here?
Expand All @@ -243,7 +226,6 @@ export class Model<T = unknown> {
this.changeEventStream.publish(event);
return data;
} catch (error) {
await db.rollback();
throw error;
}
}
Expand Down
21 changes: 17 additions & 4 deletions packages/datastore/datastore/src/react/hooks/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,32 @@ import { CRUDEvents, StoreChangeEvent } from "../../storage";
import { Filter } from "../../filters";

const onAdded = (currentData: any[], newData: any[]) => {
if (!currentData) {return newData;}
if (!currentData) { return newData; }
return [...currentData, ...newData];
};

const onChanged = (currentData: any[], newData: any[], primaryKey: string) => {
if (!currentData) {return [];}
if (!currentData) { return []; }
// What happens to data that get's updated and falls outside original query filter?
return currentData.map((d) => {
const index = newData.findIndex((newD) => newD[primaryKey] === d[primaryKey]);
if (index === -1) {return d;}
if (index === -1) { return d; }
return newData[index];
});
};

const onIdSwapped = (currentData: any[], newData: any[], primaryKey: string) => {
if (!currentData) { return []; }

return currentData.map((d) => {
const index = newData.findIndex((newD) => newD.previous[primaryKey] === d[primaryKey]);
if (index === -1) { return d; }
return newData[index].current;
});
};

const onRemoved = (currentData: any[], removedData: any[], primaryKey: string) => {
if (!currentData) {return [];}
if (!currentData) { return []; }
return currentData
.filter(
(d) => removedData.findIndex((newD) => newD[primaryKey] === d[primaryKey])
Expand All @@ -35,6 +45,9 @@ export const updateResult = (state: ResultState, event: StoreChangeEvent, primar
case CRUDEvents.UPDATE:
return onChanged(state.data, event.data, primaryKey);

case CRUDEvents.ID_SWAP:
return onIdSwapped(state.data, event.data, primaryKey);

case CRUDEvents.DELETE:
return onRemoved(state.data, event.data, primaryKey);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@ export interface LiveUpdatesConfig {

/**
* Handle errors repeat request if needed
*
* @returns true if request should be repeated
*/
export type UserErrorHandler = (networkError: any, graphqlError: any) => boolean;

/**
* Handle errors repeat request if needed
*
* @returns true if request should be repeated
*/
export type PullErrorHandler = (networkError: any, graphqlError: any) => boolean;

Expand Down
Loading

0 comments on commit 2e87e49

Please sign in to comment.