Skip to content

Commit

Permalink
Merge pull request #195 from nanyuantingfeng/release/v2
Browse files Browse the repository at this point in the history
Fix set model id by `0`, model actual id is `-1`
  • Loading branch information
DarkoKukovec committed Jul 27, 2020
2 parents b5c82ac + a001cbf commit cff34b2
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 37 deletions.
7 changes: 4 additions & 3 deletions packages/datx/src/PureCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,9 +424,10 @@ export class PureCollection {

const existingModel = this.findOne(modelType, modelId);

if (existingModel && existingModel !== model) {
updateModel(existingModel, model);

if (existingModel) {
if (existingModel !== model) {
updateModel(existingModel, model);
}
return;
}

Expand Down
79 changes: 46 additions & 33 deletions packages/datx/src/helpers/model/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
isModelReference,
modelMapParse,
commitModel,
peekNonNullish,
} from './utils';
import { getBucketConstructor } from '../../buckets';
import { getRef, updateRef, getBackRef, updateBackRef } from './fields';
Expand All @@ -40,6 +41,41 @@ export function getModelRefType(
return model;
}

// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
function getRefValue<T extends PureModel>(
value: TRefValue<any>,
collection: PureCollection,
fieldDef: any,
model: T,
key: string,
): TRefValue<T> {
return mapItems(value, (item) => {
if (typeof item === 'object' && !isModelReference(item)) {
return (
collection?.add(
item,
getModelRefType(fieldDef.referenceDef.model, item, model, key, collection),
) || null
);
}

if (typeof item === 'object' && isModelReference(item)) {
return collection?.findOne(item as IModelRef) || (item as IModelRef);
}

return (
collection?.findOne(
getModelRefType(fieldDef.referenceDef.model, item, model, key, collection),
item,
) ||
({
id: item,
type: getModelRefType(fieldDef.referenceDef.model, item, model, key, collection),
} as IModelRef)
);
});
}

export function initModelRef<T extends PureModel>(
model: T,
key: string,
Expand Down Expand Up @@ -71,35 +107,10 @@ export function initModelRef<T extends PureModel>(
);
} else {
const Bucket = getBucketConstructor(fieldDef.referenceDef.type);
let value: IType | Array<IType> | IModelRef | Array<IModelRef> | null =
fieldDef.referenceDef.type === ReferenceType.TO_MANY ? [] : null;

if (initialVal) {
value = mapItems(initialVal, (item) => {
if (typeof item === 'object' && !isModelReference(item)) {
return (
collection?.add(
item,
getModelRefType(fieldDef.referenceDef.model, item, model, key, collection),
) || null
);
}

if (typeof item === 'object' && isModelReference(item)) {
return collection?.findOne(item as IModelRef) || (item as IModelRef);
}

return (
collection?.findOne(
getModelRefType(fieldDef.referenceDef.model, item, model, key, collection),
item,
) ||
({
id: item,
type: getModelRefType(fieldDef.referenceDef.model, item, model, key, collection),
} as IModelRef)
);
});
let value: TRefValue = fieldDef.referenceDef.type === ReferenceType.TO_MANY ? [] : null;

if (initialVal !== null && initialVal !== undefined) {
value = getRefValue(initialVal, collection!, fieldDef, model, key);
}

const bucket = new Bucket(value, collection, false, model, key, true);
Expand All @@ -113,7 +124,7 @@ export function initModelRef<T extends PureModel>(
() => getRef(model, key),
(newValue: TRefValue) => {
updateSingleAction(model, key, newValue);
updateRef(model, key, newValue);
updateRef(model, key, getRefValue(newValue, collection!, fieldDef, model, key));
},
);
}
Expand Down Expand Up @@ -200,15 +211,15 @@ export function initModel(
setMeta(
instance,
MetaModelField.TypeField,
rawData[typeField] || modelMeta?.type || modelClass.type,
peekNonNullish(rawData[typeField], modelMeta?.type, modelClass.type),
);

const idField = getMeta(instance.constructor, MetaClassField.IdField, DEFAULT_ID_FIELD, true);

setMeta(
instance,
MetaModelField.IdField,
rawData[idField] || modelMeta?.id || modelClass.getAutoId(),
peekNonNullish(rawData[idField], modelMeta?.id, () => modelClass.getAutoId()),
);

setMeta(instance, MetaModelField.OriginalId, modelMeta?.originalId);
Expand All @@ -220,7 +231,9 @@ export function initModel(
const value = rawData[field];
const isRef =
value instanceof PureModel ||
(isArrayLike(value) && (value[0] instanceof PureModel || isModelReference(value[0]))) ||
(isArrayLike(value) &&
value.length &&
(value[0] instanceof PureModel || isModelReference(value[0]))) ||
isModelReference(value);

fields[field] = {
Expand Down
17 changes: 17 additions & 0 deletions packages/datx/src/helpers/model/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,23 @@ export function isIdentifier(value: any): boolean {
return typeof value === 'string' || typeof value === 'number';
}

export function peekNonNullish(...args: any[]): any {
if (args.length === 0) return null;

let i = -1;
while (++i < args.length) {
let arg = args[i];

if (typeof arg === 'function') {
arg = arg();
}
if (arg !== null && arg !== undefined) {
return arg;
}
}
return null;
}

/**
* Get the type of the given model
*
Expand Down
21 changes: 21 additions & 0 deletions packages/datx/test/__snapshots__/patches.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,27 @@ Array [
},
"patchType": 1,
},
Object {
"model": Object {
"id": 3,
"type": "bar",
},
"newValue": Object {
"__META__": Object {
"collection": undefined,
"fields": Object {
"id": Object {
"defaultValue": undefined,
"referenceDef": false,
},
},
"id": 3,
"type": "bar",
},
"id": 3,
},
"patchType": 0,
},
Object {
"model": Object {
"id": 1,
Expand Down
72 changes: 71 additions & 1 deletion packages/datx/test/collection.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { autorun, configure } from 'mobx';

import { Collection, PureModel, Attribute, updateModelId, Model, getRefId } from '../src';
import {
Collection,
PureModel,
Attribute,
updateModelId,
Model,
getRefId,
modelToJSON,
} from '../src';
import { isCollection, isModel } from '../src/helpers/mixin';
import { getModelCollection, getModelId } from '../src/helpers/model/utils';

Expand Down Expand Up @@ -478,5 +486,67 @@ describe('Collection', () => {
expect(refId).toBeInstanceOf(Array);
expect((refId as any[]).map((d) => d.id)).toEqual(['2', '3', '5']);
});

it('should initialize data with id is `0`', () => {
class Foo extends Model {
static type = 'foo';

@Attribute({ isIdentifier: true }) public id!: number;
@Attribute() public name!: string;
}

class Store extends Collection {
static types = [Foo];
}

const store = new Store();
const foo = store.add({ id: 0, name: '99999' }, Foo);
expect(foo.id).toBe(0);
const fooData = modelToJSON(foo);
expect(fooData.id).toBe(0);
// @ts-ignore
expect(fooData.__META__.id).toBe(0);
});

it('should be set nested data as ref', () => {
class Bar extends Model {
static type = 'bar';

@Attribute({ isIdentifier: true }) public id!: number;
@Attribute() public name!: string;
}

class Foo extends Model {
static type = 'foo';
@Attribute({ isIdentifier: true }) public id!: number;
@Attribute() public name!: string;
@Attribute({ toOne: Bar }) public bar!: Bar;
}

class Store extends Collection {
static types = [Foo, Bar];
}

const store = new Store();
store.add(
{
id: 1,
name: 'foo0',
bar: { id: 1, name: 'bar0' },
},
Foo,
);
store.add(
{
id: 1,
name: 'foo0',
bar: { id: 1, name: 'bar1' },
},
Foo,
);

expect(store.findAll(Foo).length).toBe(1);
expect(store.findAll(Bar).length).toBe(1);
});
});
});

0 comments on commit cff34b2

Please sign in to comment.