node和wechatMp的适配

This commit is contained in:
Xu Chang 2022-05-19 12:21:55 +08:00
parent a059a1d64f
commit 9a7e6ced34
16 changed files with 946 additions and 416 deletions

View File

@ -18,14 +18,28 @@ export declare class Node<ED extends EntityDict, T extends keyof ED, Cxt extends
protected needReGetValue: boolean;
protected refreshing: boolean;
private refreshFn?;
constructor(entity: T, fullPath: string, schema: StorageSchema<ED>, cache: Cache<ED, Cxt, AD>, projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), parent?: Node<ED, keyof ED, Cxt, AD>, action?: ED[T]['Action']);
getSubEntity(path: string): {
entity: keyof ED;
constructor(entity: T, fullPath: string, schema: StorageSchema<ED>, cache: Cache<ED, Cxt, AD>, projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), parent?: Node<ED, keyof ED, Cxt, AD>, action?: ED[T]['Action'], updateData?: DeduceUpdateOperation<ED[T]['OpSchema']>['data']);
getSubEntity(path: string): Promise<{
entity: any;
isList: boolean;
};
id: string | undefined;
ids?: undefined;
} | {
entity: string;
isList: boolean;
id: any;
ids?: undefined;
} | {
entity: string;
isList: boolean;
ids: any;
id?: undefined;
}>;
getEntity(): T;
setUpdateData(attr: string, value: any): void;
setWholeUpdateData(updateData: DeduceUpdateOperation<ED[T]['OpSchema']>['data']): void;
setDirty(): void;
setAction(action: ED[T]['Action']): void;
isDirty(): boolean;
getParent(): Node<ED, keyof ED, Cxt, AD> | undefined;
getProjection(): Promise<ED[T]["Selection"]["data"] | undefined>;
@ -39,13 +53,25 @@ declare class ListNode<ED extends EntityDict, T extends keyof ED, Cxt extends Co
private filters;
private sorters;
private pagination;
constructor(entity: T, fullPath: string, schema: StorageSchema<ED>, cache: Cache<ED, Cxt, AD>, projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), parent?: Node<ED, keyof ED, Cxt, AD>, pagination?: Pagination, filters?: NamedFilterItem<ED, T>[], sorters?: NamedSorterItem<ED, T>[], action?: ED[T]['Action']);
composeOperation(action?: string): Promise<DeduceOperation<ED[T]['Schema']> | DeduceOperation<ED[T]['Schema']>[] | undefined>;
constructor(entity: T, fullPath: string, schema: StorageSchema<ED>, cache: Cache<ED, Cxt, AD>, projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), parent?: Node<ED, keyof ED, Cxt, AD>, pagination?: Pagination, filters?: NamedFilterItem<ED, T>[], sorters?: NamedSorterItem<ED, T>[], ids?: string[], action?: ED[T]['Action'], updateData?: DeduceUpdateOperation<ED[T]['OpSchema']>['data']);
getIds(): string[];
composeOperation(action?: string, realId?: boolean): Promise<DeduceOperation<ED[T]['Schema']> | DeduceOperation<ED[T]['Schema']>[] | undefined>;
getChildren(): SingleNode<ED, T, Cxt, AD>[];
addChild(path: string, node: SingleNode<ED, T, Cxt, AD>): void;
removeChild(path: string): void;
getChild(path: string, create?: boolean): Promise<SingleNode<ED, T, Cxt, AD>>;
getFilters(): NamedFilterItem<ED, T>[];
setFilters(filters: NamedFilterItem<ED, T>[]): void;
getChild(path?: string, create?: boolean): Promise<SingleNode<ED, T, Cxt, AD>>;
getNamedFilters(): NamedFilterItem<ED, T>[];
getNamedFilterByName(name: string): NamedFilterItem<ED, T> | undefined;
setNamedFilters(filters: NamedFilterItem<ED, T>[]): void;
addNamedFilter(filter: NamedFilterItem<ED, T>): void;
removeNamedFilter(filter: NamedFilterItem<ED, T>): void;
removeNamedFilterByName(name: string): void;
getNamedSorters(): NamedSorterItem<ED, T>[];
getNamedSorterByName(name: string): NamedSorterItem<ED, T> | undefined;
setNamedSorters(sorters: NamedSorterItem<ED, T>[]): void;
addNamedSorter(sorter: NamedSorterItem<ED, T>): void;
removeNamedSorter(sorter: NamedSorterItem<ED, T>): void;
removeNamedSorterByName(name: string): void;
refresh(): Promise<void>;
updateChildrenValue(): void;
reGetValue(): Promise<void>;
@ -60,12 +86,15 @@ declare class SingleNode<ED extends EntityDict, T extends keyof ED, Cxt extends
private id?;
private value?;
private children;
constructor(entity: T, fullPath: string, schema: StorageSchema<ED>, cache: Cache<ED, Cxt, AD>, projection?: ED[T]['Selection']['data'], parent?: Node<ED, keyof ED, Cxt, AD>, id?: string, action?: ED[T]['Action']);
constructor(entity: T, fullPath: string, schema: StorageSchema<ED>, cache: Cache<ED, Cxt, AD>, projection?: ED[T]['Selection']['data'], parent?: Node<ED, keyof ED, Cxt, AD>, id?: string, action?: ED[T]['Action'], updateData?: DeduceUpdateOperation<ED[T]['OpSchema']>['data']);
refresh(): Promise<void>;
composeOperation(action2?: string): Promise<DeduceOperation<ED[T]['Schema']> | undefined>;
composeOperation(action2?: string, realId?: boolean): Promise<DeduceOperation<ED[T]['Schema']> | undefined>;
addChild(path: string, node: Node<ED, keyof ED, Cxt, AD>): void;
removeChild(path: string): void;
getChild<Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>>(path: keyof ED[T]['Schema'], create?: boolean, cache?: Cache<ED, Cxt, AD>): Promise<{ [K in keyof ED[T]["Schema"]]?: SingleNode<ED, keyof ED, Cxt, AD> | ListNode<ED, keyof ED, Cxt, AD> | undefined; }[keyof ED[T]["Schema"]]>;
getChildren(): {
[K: string]: SingleNode<ED, keyof ED, Cxt, AD> | ListNode<ED, keyof ED, Cxt, AD>;
};
getChild(path: keyof ED[T]['Schema'], create?: boolean): Promise<SingleNode<ED, keyof ED, Cxt, AD> | ListNode<ED, keyof ED, Cxt, AD>>;
getFilter(): DeduceFilter<ED[T]["Schema"]>;
updateChildrenValues(): void;
reGetValue(): Promise<void>;
@ -73,13 +102,30 @@ declare class SingleNode<ED extends EntityDict, T extends keyof ED, Cxt extends
setValue(value: Partial<ED[T]['Schema']>): void;
resetUpdateData(): void;
onRecordSynchoronized(records: OpRecord<ED>[]): Promise<void>;
createPicker<T2 extends keyof ED>(path: string, projection?: ED[T2]['Selection']['data'] | (() => Promise<ED[T2]['Selection']['data']>), pagination?: Pagination, filters?: NamedFilterItem<ED, T2>[], sorters?: NamedSorterItem<ED, T2>[]): ListNode<ED, T2, Cxt, AD>;
}
declare type CreateNodeOptions<ED extends EntityDict, T extends keyof ED> = {
path?: string;
parent?: string;
entity?: T;
isList?: boolean;
isPicker?: boolean;
projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>);
pagination?: Pagination;
filters?: NamedFilterItem<ED, T>[];
sorters?: NamedSorterItem<ED, T>[];
action?: ED[T]['Action'];
id?: string;
ids?: string[];
updateData?: DeduceUpdateOperation<ED[T]['OpSchema']>['data'];
};
export declare class RunningNode<ED extends EntityDict, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>> extends Feature<ED, Cxt, AD> {
private cache;
private schema?;
private root;
constructor(cache: Cache<ED, Cxt, AD>);
createNode<T extends keyof ED>(path: string, parent?: string, entity?: T, isList?: boolean, isPicker?: boolean, projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), id?: string, pagination?: Pagination, filters?: NamedFilterItem<ED, T>[], sorters?: NamedSorterItem<ED, T>[]): Promise<keyof ED>;
createNode<T extends keyof ED>(options: CreateNodeOptions<ED, T>): Promise<ListNode<ED, T, Cxt, AD> | SingleNode<ED, T, Cxt, AD>>;
addNode<T extends keyof ED>(options: Pick<CreateNodeOptions<ED, T>, 'parent' | 'updateData'>): Promise<ListNode<ED, T, Cxt, AD> | SingleNode<ED, T, Cxt, AD>>;
destroyNode(path: string): Promise<void>;
setStorageSchema(schema: StorageSchema<ED>): void;
private applyOperation;
@ -87,14 +133,28 @@ export declare class RunningNode<ED extends EntityDict, Cxt extends Context<ED>,
isDirty(path: string): Promise<boolean>;
private findNode;
protected setUpdateDataInner(path: string, attr: string, value: any): Promise<void>;
setAction<T extends keyof ED>(path: string, action: ED[T]['Action']): Promise<void>;
setUpdateData(path: string, attr: string, value: any): Promise<void>;
setMultipleData(path: string, data: [string, any][]): Promise<void>;
setForeignKey(path: string, id: string): Promise<void>;
refresh(path: string): Promise<void>;
setFilters<T extends keyof ED>(path: string, filters: NamedFilterItem<ED, T>[], refresh?: boolean): Promise<void>;
testAction(path: string, action: string): Promise<{
getNamedFilters<T extends keyof ED>(path: string): Promise<NamedFilterItem<ED, keyof ED>[]>;
getNamedFilterByName<T extends keyof ED>(path: string, name: string): Promise<NamedFilterItem<ED, keyof ED> | undefined>;
setNamedFilters<T extends keyof ED>(path: string, filters: NamedFilterItem<ED, T>[], refresh?: boolean): Promise<void>;
addNamedFilter<T extends keyof ED>(path: string, filter: NamedFilterItem<ED, T>, refresh?: boolean): Promise<void>;
removeNamedFilter<T extends keyof ED>(path: string, filter: NamedFilterItem<ED, T>, refresh?: boolean): Promise<void>;
removeNamedFilterByName<T extends keyof ED>(path: string, name: string, refresh?: boolean): Promise<void>;
getNamedSorters<T extends keyof ED>(path: string): Promise<NamedSorterItem<ED, keyof ED>[]>;
getNamedSorterByName<T extends keyof ED>(path: string, name: string): Promise<NamedSorterItem<ED, keyof ED> | undefined>;
setNamedSorters<T extends keyof ED>(path: string, sorters: NamedSorterItem<ED, T>[], refresh?: boolean): Promise<void>;
addNamedSorter<T extends keyof ED>(path: string, sorter: NamedSorterItem<ED, T>, refresh?: boolean): Promise<void>;
removeNamedSorter<T extends keyof ED>(path: string, sorter: NamedSorterItem<ED, T>, refresh?: boolean): Promise<void>;
removeNamedSorterByName<T extends keyof ED>(path: string, name: string, refresh?: boolean): Promise<void>;
testAction(path: string, action: string, realId?: boolean): Promise<{
node: SingleNode<ED, keyof ED, Cxt, AD> | ListNode<ED, keyof ED, Cxt, AD>;
operation: DeduceOperation<ED[keyof ED]["Schema"]> | DeduceOperation<ED[keyof ED]["Schema"]>[];
}>;
private beforeExecute;
execute(path: string, action: string): Promise<void>;
}
export {};

View File

@ -16,6 +16,7 @@ const Feature_1 = require("../types/Feature");
const assert_1 = __importDefault(require("assert"));
const lodash_2 = require("lodash");
const relation_1 = require("oak-domain/lib/store/relation");
const mockId_1 = require("../utils/mockId");
class Node {
entity;
fullPath;
@ -29,7 +30,7 @@ class Node {
needReGetValue;
refreshing;
refreshFn;
constructor(entity, fullPath, schema, cache, projection, parent, action) {
constructor(entity, fullPath, schema, cache, projection, parent, action, updateData) {
this.entity = entity;
this.fullPath = fullPath;
this.schema = schema;
@ -40,19 +41,32 @@ class Node {
this.dirty = false;
this.needReGetValue = !!this.projection;
this.refreshing = false;
this.updateData = updateData;
}
getSubEntity(path) {
async getSubEntity(path) {
if (this instanceof ListNode) {
const idx = parseInt(path, 10);
(0, assert_1.default)(typeof idx === 'number');
return {
entity: this.entity,
isList: false,
id: this.getIds()[idx] || undefined,
};
}
(0, assert_1.default)(this instanceof SingleNode);
const relation = (0, relation_1.judgeRelation)(this.schema, this.entity, path);
if (relation === 2) {
return {
entity: path,
isList: false,
id: (await this.getValue())['entityId'],
};
}
else if (typeof relation === 'string') {
return {
entity: relation,
isList: false,
id: (await this.getValue())[`${path}Id`],
};
}
else {
@ -60,6 +74,7 @@ class Node {
return {
entity: relation[0],
isList: true,
ids: (await this.getValue()).map((ele) => ele.id),
};
}
}
@ -73,10 +88,21 @@ class Node {
this.setDirty();
(0, lodash_1.set)(this.updateData, attr, value);
}
setWholeUpdateData(updateData) {
this.updateData = updateData;
this.setDirty();
}
setDirty() {
if (!this.dirty) {
this.dirty = true;
}
if (this.parent) {
this.parent.setDirty();
}
}
setAction(action) {
this.action = action;
this.setDirty();
}
isDirty() {
return this.dirty;
@ -118,9 +144,9 @@ class ListNode extends Node {
filters;
sorters;
pagination;
constructor(entity, fullPath, schema, cache, projection, parent, pagination, filters, sorters, action) {
super(entity, fullPath, schema, cache, projection, parent, action);
this.ids = [];
constructor(entity, fullPath, schema, cache, projection, parent, pagination, filters, sorters, ids, action, updateData) {
super(entity, fullPath, schema, cache, projection, parent, action, updateData);
this.ids = ids || [];
this.value = [];
this.children = [];
this.filters = filters || [];
@ -130,7 +156,10 @@ class ListNode extends Node {
this.registerValueSentry((records) => this.onRecordSynchoronized(records));
}
}
async composeOperation(action) {
getIds() {
return this.ids;
}
async composeOperation(action, realId) {
if (!action && !this.isDirty()) {
return;
}
@ -139,18 +168,21 @@ class ListNode extends Node {
return {
action: action || this.action || 'update',
data: (0, lodash_1.cloneDeep)(this.updateData),
filter: (0, filter_1.combineFilters)(this.filters),
filter: (0, filter_1.combineFilters)(this.filters.map(ele => ele.filter)),
}; // todo 这里以后再增加对选中id的过滤
}
const actions = [];
for (const node of this.children) {
const subAction = await node.composeOperation();
const subAction = await node.composeOperation(undefined, realId);
if (subAction) {
actions.push(subAction);
}
}
return actions;
}
getChildren() {
return this.children;
}
addChild(path, node) {
const { children } = this;
const idx = parseInt(path, 10);
@ -164,21 +196,96 @@ class ListNode extends Node {
(0, lodash_1.unset)(children, idx);
}
async getChild(path, create) {
const idx = parseInt(path, 10);
let node = this.children[idx];
if (create && !node) {
node = new SingleNode(this.entity, `${this.fullPath}.${idx}`, this.schema, this.cache, undefined, this, this.ids[idx]);
node.setValue(this.value[idx]);
this.addChild(path, node);
if (path) {
const idx = parseInt(path, 10);
let node = this.children[idx];
if (create && !node) {
node = new SingleNode(this.entity, `${this.fullPath}.${idx}`, this.schema, this.cache, undefined, this, this.ids[idx]);
node.setValue(this.value[idx]);
this.addChild(path, node);
}
return node;
}
else {
// 不传path说明是在list里增加一个结点找空位就行了
(0, assert_1.default)(create);
let idx = this.ids.length;
while (this.children[idx]) {
idx++;
}
const node = new SingleNode(this.entity, `${this.fullPath}.${idx}`, this.schema, this.cache, undefined, this, undefined);
this.children[idx] = node;
return node;
}
return node;
}
getFilters() {
getNamedFilters() {
return this.filters;
}
setFilters(filters) {
getNamedFilterByName(name) {
const filter = this.filters.find((ele) => ele['#name'] === name);
return filter;
}
setNamedFilters(filters) {
this.filters = filters;
}
addNamedFilter(filter) {
// filter 根据#name查找
const fIndex = this.filters.findIndex(ele => filter['#name'] && ele['#name'] === filter['#name']);
if (fIndex >= 0) {
this.filters.splice(fIndex, 1, filter);
}
else {
this.filters.push(filter);
}
}
removeNamedFilter(filter) {
// filter 根据#name查找
const fIndex = this.filters.findIndex(ele => filter['#name'] && ele['#name'] === filter['#name']);
if (fIndex >= 0) {
this.filters.splice(fIndex, 1);
}
}
removeNamedFilterByName(name) {
// filter 根据#name查找
const fIndex = this.filters.findIndex(ele => ele['#name'] === name);
if (fIndex >= 0) {
this.filters.splice(fIndex, 1);
}
}
getNamedSorters() {
return this.sorters;
}
getNamedSorterByName(name) {
const sorter = this.sorters.find((ele) => ele['#name'] === name);
return sorter;
}
setNamedSorters(sorters) {
this.sorters = sorters;
}
addNamedSorter(sorter) {
// sorter 根据#name查找
const fIndex = this.sorters.findIndex(ele => sorter['#name'] && ele['#name'] === sorter['#name']);
if (fIndex >= 0) {
this.sorters.splice(fIndex, 1, sorter);
}
else {
this.sorters.push(sorter);
}
}
removeNamedSorter(sorter) {
// sorter 根据#name查找
const fIndex = this.sorters.findIndex(ele => sorter['#name'] && ele['#name'] === sorter['#name']);
if (fIndex >= 0) {
this.sorters.splice(fIndex, 1);
}
}
removeNamedSorterByName(name) {
// sorter 根据#name查找
const fIndex = this.sorters.findIndex(ele => ele['#name'] === name);
if (fIndex >= 0) {
this.sorters.splice(fIndex, 1);
}
}
async refresh() {
const { filters, sorters, pagination, entity, fullPath } = this;
const { step } = pagination;
@ -253,7 +360,7 @@ class ListNode extends Node {
const { e, d } = record;
if (e === this.entity) {
const { id } = d;
const filter = (0, filter_1.combineFilters)([{ id }, ...this.filters]);
const filter = (0, filter_1.combineFilters)([{ id }, ...(this.filters).map(ele => ele.filter)]);
const { ids } = await this.cache.operate(e, {
data: {
id: 1,
@ -287,7 +394,7 @@ class ListNode extends Node {
break;
}
else {
const filter = (0, filter_1.combineFilters)([{ id }, ...this.filters]);
const filter = (0, filter_1.combineFilters)([{ id }, ...(this.filters.map(ele => ele.filter))]);
const { ids } = await this.cache.operate(e, {
data: {
id: 1,
@ -336,8 +443,8 @@ class SingleNode extends Node {
id;
value;
children;
constructor(entity, fullPath, schema, cache, projection, parent, id, action) {
super(entity, fullPath, schema, cache, projection, parent, action);
constructor(entity, fullPath, schema, cache, projection, parent, id, action, updateData) {
super(entity, fullPath, schema, cache, projection, parent, action, updateData);
this.id = id;
this.children = {};
if (projection) {
@ -358,14 +465,14 @@ class SingleNode extends Node {
this.refreshing = false;
}
}
async composeOperation(action2) {
async composeOperation(action2, realId) {
if (!action2 && !this.isDirty()) {
return;
}
const action = action2 || this.action || (this.id ? 'update' : 'create');
const operation = action === 'create' ? {
action: 'create',
data: (0, lodash_2.assign)({}, this.updateData, { id: await generateNewId() }),
data: (0, lodash_2.assign)({}, this.updateData, { id: realId ? await generateNewId() : (0, mockId_1.generateMockId)() }),
} : {
action,
data: (0, lodash_1.cloneDeep)(this.updateData) || {},
@ -374,7 +481,7 @@ class SingleNode extends Node {
},
};
for (const attr in this.children) {
const subAction = await this.children[attr].composeOperation();
const subAction = await this.children[attr].composeOperation(undefined, realId);
if (subAction) {
(0, lodash_2.assign)(operation.data, {
[attr]: subAction,
@ -395,10 +502,12 @@ class SingleNode extends Node {
(0, assert_1.default)(children[path]);
(0, lodash_1.unset)(children, path);
}
async getChild(path, create, cache) {
getChildren() {
return this.children;
}
async getChild(path, create) {
let node = this.children[path];
if (create && !node) {
(0, assert_1.default)(cache);
const relation = (0, relation_1.judgeRelation)(this.schema, this.entity, path);
if (relation === 2) {
// 基于entityId的多对一
@ -408,23 +517,7 @@ class SingleNode extends Node {
else {
// 新建对象并关联
(0, assert_1.default)(!this.value || this.value.entity);
const id = await generateNewId();
/* await cache.operate(this.entity, {
action: 'update',
data: {
entity: path as any,
[path]: {
action: 'create',
data: {
id,
},
},
},
filter: {
id: this.id!,
}
} as any); */
node = new SingleNode(path, `${this.fullPath}.${path}`, this.schema, this.cache, undefined, this, id, 'create');
node = new SingleNode(path, `${this.fullPath}.${path}`, this.schema, this.cache, undefined, this, undefined, 'create');
}
}
else if (typeof relation === 'string') {
@ -434,27 +527,12 @@ class SingleNode extends Node {
else {
// 新建对象并关联
(0, assert_1.default)(!this.value || !this.value.entity);
const id = await generateNewId();
/* await cache.operate(this.entity, {
action: 'update',
data: {
[path]: {
action: 'create',
data: {
id,
},
},
},
filter: {
id: this.id!,
}
} as any); */
node = new SingleNode(path, `${this.fullPath}.${path}`, this.schema, this.cache, undefined, this, id, 'create');
node = new SingleNode(path, `${this.fullPath}.${path}`, this.schema, this.cache, undefined, this, undefined, 'create');
}
}
else {
(0, assert_1.default)(relation instanceof Array);
node = new ListNode(relation[0], `${this.fullPath}.${path}`, this.schema, this.cache, undefined, this);
node = new ListNode(relation[0], `${this.fullPath}.${path}`, this.schema, this.cache, undefined, this, undefined, undefined, undefined, this.value && this.value[path].map((ele) => ele.id));
}
node.setValue(this.value && this.value[path]);
this.addChild(path, node);
@ -546,6 +624,20 @@ class SingleNode extends Node {
}
}
}
createPicker(path, projection, pagination, filters, sorters) {
const rel = (0, relation_1.judgeRelation)(this.schema, this.entity, path);
let entity;
if (rel === 2) {
entity = path;
}
else {
(0, assert_1.default)(typeof rel === 'string');
entity = rel;
}
const node = new ListNode(entity, `${this.fullPath}.${path}`, this.schema, this.cache, projection, this, pagination, filters, sorters);
this.addChild(path, node);
return node;
}
}
class RunningNode extends Feature_1.Feature {
cache;
@ -556,26 +648,65 @@ class RunningNode extends Feature_1.Feature {
this.cache = cache;
this.root = {};
}
async createNode(path, parent, entity, isList, isPicker, projection, id, pagination, filters, sorters) {
async createNode(options) {
const { entity, parent, pagination, path, filters, sorters, id, ids, action, updateData, projection, isList, isPicker, } = options;
let node;
const parentNode = parent ? await this.findNode(parent) : undefined;
const fullPath = parent ? `${parent}.${path}` : `${path}`;
const subEntity = parentNode && parentNode.getSubEntity(path);
const entity2 = subEntity ? subEntity.entity : entity;
const isList2 = subEntity ? subEntity.isList : isList;
if (isPicker || isList2) {
node = new ListNode(entity2, fullPath, this.schema, this.cache, projection, parentNode, pagination, filters, sorters);
}
else {
node = new SingleNode(entity2, fullPath, this.schema, this.cache, projection, parentNode, id);
}
const parentNode = parent && await this.findNode(parent);
if (parentNode) {
parentNode.addChild(path, node);
if (isPicker) {
// 如果是picker使用list来选择
(0, assert_1.default)(path);
(0, assert_1.default)(parentNode instanceof SingleNode);
node = parentNode.createPicker(path, projection, pagination, filters, sorters);
}
else {
(0, assert_1.default)(path || parentNode instanceof ListNode);
node = (await parentNode.getChild(path, true));
}
if (action) {
node.setAction(action);
}
if (updateData) {
node.setWholeUpdateData(updateData);
}
}
else {
(0, assert_1.default)(entity && path);
if (isPicker || isList) {
node = new ListNode(entity, path, this.schema, this.cache, projection, undefined, pagination, filters, sorters, ids, action, updateData);
}
else {
node = new SingleNode(entity, path, this.schema, this.cache, projection, undefined, id, action, updateData);
}
this.root[path] = node;
}
return entity2;
return node;
/* const parentNode = parent ? await this.findNode(parent) : undefined;
const fullPath = parent ? `${parent}.${path}` : `${path}`;
const subEntity = parentNode && await parentNode.getSubEntity(path);
const entity2 = subEntity ? subEntity.entity : entity!;
const isList2 = subEntity ? subEntity.isList : isList!;
const id2 = subEntity && subEntity.id || id;
const ids2 = subEntity && subEntity.ids || ids;
if (isPicker || isList2) {
node = new ListNode<ED, T, Cxt, AD>(entity2 as T, fullPath, this.schema!, this.cache, projection, parentNode, pagination, filters, sorters, ids2, action);
}
else {
node = new SingleNode<ED, T, Cxt, AD>(entity2 as T, fullPath, this.schema!, this.cache, projection, parentNode, id2, action);
}
if (parentNode) {
parentNode.addChild(path, node as any);
}
else {
this.root[path] = node as any;
}
return entity2; */
}
// 目前addNode应该只有在list中新加一项这一种情况
addNode(options) {
return this.createNode(options);
}
async destroyNode(path) {
const node = await this.findNode(path);
@ -605,12 +736,14 @@ class RunningNode extends Feature_1.Feature {
switch (action.action) {
case 'create': {
value.push(await this.applyOperation(entity, undefined, action, projection, scene));
break;
}
case 'remove': {
const { filter } = action;
(0, assert_1.default)(filter.id);
const row = value.find(ele => ele.id === filter.id);
(0, lodash_1.pull)(value, row);
break;
}
default: {
const { filter } = action;
@ -671,7 +804,7 @@ class RunningNode extends Feature_1.Feature {
else {
(0, assert_1.default)(relation instanceof Array);
if (projection[attr]) {
(0, lodash_1.set)(row, attr, await this.applyOperation(relation[0], row[attr], actionData[attr], projection[attr], scene));
(0, lodash_1.set)(row, attr, await this.applyOperation(relation[0], row[attr], actionData[attr], projection[attr]['data'], scene));
row[attr].forEach((ele) => {
if (relation[1]) {
(0, lodash_2.assign)(ele, {
@ -727,9 +860,7 @@ class RunningNode extends Feature_1.Feature {
switch (action) {
case 'create': {
(0, assert_1.default)(!value);
const row = {
id: await generateNewId(),
};
const row = {};
await applyUpsert(row, data);
return row;
}
@ -750,7 +881,7 @@ class RunningNode extends Feature_1.Feature {
if (node.isDirty()) {
const operation = await node.composeOperation();
const projection = await node.getProjection();
value = (await this.applyOperation(node.getEntity(), value, operation, projection, path));
value = (await this.applyOperation(node.getEntity(), (0, lodash_1.cloneDeep)(value), operation, projection, path));
}
if (value instanceof Array) {
return value;
@ -759,16 +890,16 @@ class RunningNode extends Feature_1.Feature {
}
async isDirty(path) {
const node = await this.findNode(path);
return node.isDirty();
return node ? node.isDirty() : false;
}
async findNode(path) {
async findNode(path, create) {
const paths = path.split('.');
let node = this.root[paths[0]];
let iter = 1;
while (iter < paths.length) {
while (iter < paths.length && node) {
const childPath = paths[iter];
node = (await node.getChild(childPath));
iter++;
node = (await node.getChild(childPath, create));
}
return node;
}
@ -786,12 +917,16 @@ class RunningNode extends Feature_1.Feature {
return;
}
else {
node.setDirty();
node = (await node.getChild(split, true, this.cache));
// node.setDirty();
node = (await node.getChild(split, true));
idx++;
}
}
}
async setAction(path, action) {
const node = await this.findNode(path, true);
node.setAction(action);
}
async setUpdateData(path, attr, value) {
await this.setUpdateDataInner(path, attr, value);
}
@ -800,22 +935,111 @@ class RunningNode extends Feature_1.Feature {
await this.setUpdateDataInner(path, d[0], d[1]);
}
}
async setForeignKey(path, id) {
const node = await this.findNode(path);
const parent = node.getParent();
const attr = path.slice(path.lastIndexOf('.') + 1);
const rel = (0, relation_1.judgeRelation)(this.schema, parent.getEntity(), attr);
if (rel === 2) {
parent.setUpdateData('entity', node.getEntity());
parent.setUpdateData('entityId', id);
}
else {
(0, assert_1.default)(typeof rel === 'string');
parent.setUpdateData(`${attr}Id`, id);
}
}
async refresh(path) {
const node = await this.findNode(path);
await node.refresh();
}
async setFilters(path, filters, refresh = true) {
async getNamedFilters(path) {
const node = await this.findNode(path);
if (node instanceof ListNode) {
node.setFilters(filters);
if (refresh) {
await node.refresh();
}
(0, assert_1.default)(node instanceof ListNode);
return await node.getNamedFilters();
}
async getNamedFilterByName(path, name) {
const node = await this.findNode(path);
(0, assert_1.default)(node instanceof ListNode);
return await node.getNamedFilterByName(name);
}
async setNamedFilters(path, filters, refresh = true) {
const node = await this.findNode(path);
(0, assert_1.default)(node instanceof ListNode);
node.setNamedFilters(filters);
if (refresh) {
await node.refresh();
}
}
async testAction(path, action) {
async addNamedFilter(path, filter, refresh = false) {
const node = await this.findNode(path);
const operation = await node.composeOperation(action);
(0, assert_1.default)(node instanceof ListNode);
node.addNamedFilter(filter);
if (refresh) {
await node.refresh();
}
}
async removeNamedFilter(path, filter, refresh = false) {
const node = await this.findNode(path);
(0, assert_1.default)(node instanceof ListNode);
node.removeNamedFilter(filter);
if (refresh) {
await node.refresh();
}
}
async removeNamedFilterByName(path, name, refresh = false) {
const node = await this.findNode(path);
(0, assert_1.default)(node instanceof ListNode);
node.removeNamedFilterByName(name);
if (refresh) {
await node.refresh();
}
}
async getNamedSorters(path) {
const node = await this.findNode(path);
(0, assert_1.default)(node instanceof ListNode);
return await node.getNamedSorters();
}
async getNamedSorterByName(path, name) {
const node = await this.findNode(path);
(0, assert_1.default)(node instanceof ListNode);
return await node.getNamedSorterByName(name);
}
async setNamedSorters(path, sorters, refresh = true) {
const node = await this.findNode(path);
(0, assert_1.default)(node instanceof ListNode);
node.setNamedSorters(sorters);
if (refresh) {
await node.refresh();
}
}
async addNamedSorter(path, sorter, refresh = false) {
const node = await this.findNode(path);
(0, assert_1.default)(node instanceof ListNode);
node.addNamedSorter(sorter);
if (refresh) {
await node.refresh();
}
}
async removeNamedSorter(path, sorter, refresh = false) {
const node = await this.findNode(path);
(0, assert_1.default)(node instanceof ListNode);
node.removeNamedSorter(sorter);
if (refresh) {
await node.refresh();
}
}
async removeNamedSorterByName(path, name, refresh = false) {
const node = await this.findNode(path);
(0, assert_1.default)(node instanceof ListNode);
node.removeNamedSorterByName(name);
if (refresh) {
await node.refresh();
}
}
async testAction(path, action, realId) {
const node = await this.findNode(path);
const operation = await node.composeOperation(action, realId);
// 先在cache中尝试能否执行如果权限上否决了在这里就失败
if (operation instanceof Array) {
for (const oper of operation) {
@ -833,8 +1057,13 @@ class RunningNode extends Feature_1.Feature {
operation,
};
}
async beforeExecute(node2) {
async function beNode(node) {
}
await beNode(node2);
}
async execute(path, action) {
const { node, operation } = await this.testAction(path, action);
const { node, operation } = await this.testAction(path, action, true);
await this.getAspectProxy().operate({
entity: node.getEntity(),
operation,
@ -843,18 +1072,45 @@ class RunningNode extends Feature_1.Feature {
node.resetUpdateData();
}
}
__decorate([
Feature_1.Action
], RunningNode.prototype, "addNode", null);
__decorate([
Feature_1.Action
], RunningNode.prototype, "setUpdateData", null);
__decorate([
Feature_1.Action
], RunningNode.prototype, "setMultipleData", null);
__decorate([
Feature_1.Action
], RunningNode.prototype, "setForeignKey", null);
__decorate([
Feature_1.Action
], RunningNode.prototype, "refresh", null);
__decorate([
Feature_1.Action
], RunningNode.prototype, "setFilters", null);
], RunningNode.prototype, "setNamedFilters", null);
__decorate([
Feature_1.Action
], RunningNode.prototype, "addNamedFilter", null);
__decorate([
Feature_1.Action
], RunningNode.prototype, "removeNamedFilter", null);
__decorate([
Feature_1.Action
], RunningNode.prototype, "removeNamedFilterByName", null);
__decorate([
Feature_1.Action
], RunningNode.prototype, "setNamedSorters", null);
__decorate([
Feature_1.Action
], RunningNode.prototype, "addNamedSorter", null);
__decorate([
Feature_1.Action
], RunningNode.prototype, "removeNamedSorter", null);
__decorate([
Feature_1.Action
], RunningNode.prototype, "removeNamedSorterByName", null);
__decorate([
Feature_1.Action
], RunningNode.prototype, "execute", null);

1
lib/index.d.ts vendored
View File

@ -3,3 +3,4 @@ export { InitializeWechatMp, MakeOakComponent, MakeOakPage, };
export * from './types/Feature';
export * from './types/ExceptionRoute';
export { BasicFeatures } from './features';
export * from './utils/WechatMpFileCarrier';

View File

@ -15,3 +15,4 @@ const wechatMp_1 = require("./platforms/wechatMp");
Object.defineProperty(exports, "InitializeWechatMp", { enumerable: true, get: function () { return wechatMp_1.initialize; } });
__exportStar(require("./types/Feature"), exports);
__exportStar(require("./types/ExceptionRoute"), exports);
__exportStar(require("./utils/WechatMpFileCarrier"), exports);

View File

@ -6,9 +6,9 @@ import { Pagination } from "../../types/Pagination";
import { BasicFeatures } from "../../features";
import { ExceptionRouters } from '../../types/ExceptionRoute';
import { NamedFilterItem, NamedSorterItem } from '../../types/NamedCondition';
declare type OakComponentOption<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD>>, Proj extends ED[T]['Selection']['data'], FormedData extends WechatMiniprogram.Component.DataOption> = {
declare type OakComponentOption<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD>>, FormedData extends WechatMiniprogram.Component.DataOption> = {
entity: T;
formData: ($rows: SelectionResult<ED[T]['Schema'], Proj>['result'], features: BasicFeatures<ED, Cxt, AD> & FD) => Promise<FormedData>;
formData: ($rows: SelectionResult<ED[T]['Schema'], Required<ED[T]['Selection']['data']>>['result'], features: BasicFeatures<ED, Cxt, AD> & FD) => Promise<FormedData>;
};
interface OakPageOption<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD>>, Proj extends ED[T]['Selection']['data'], FormedData extends WechatMiniprogram.Component.DataOption> {
entity: T;
@ -60,15 +60,28 @@ declare type OakNavigateToParameters<ED extends EntityDict, T extends keyof ED>
oakActions?: Array<ED[T]['Action']>;
};
declare type OakComponentMethods<ED extends EntityDict, T extends keyof ED> = {
addNode: (path?: string, updateData?: object) => Promise<void>;
setUpdateData: (attr: string, input: any) => void;
callPicker: (attr: string, params: Record<string, any>) => void;
setFilters: (filters: NamedFilterItem<ED, T>[]) => void;
getFilters: () => Promise<ED[T]['Selection']['filter'][]>;
getFilterByName: (name: string) => Promise<ED[T]['Selection']['filter']>;
addNamedFilter: (filter: NamedFilterItem<ED, T>, refresh?: boolean) => void;
removeNamedFilter: (filter: NamedFilterItem<ED, T>, refresh?: boolean) => void;
removeNamedFilterByName: (name: string, refresh?: boolean) => void;
setNamedSorters: (sorters: NamedSorterItem<ED, T>[]) => void;
getSorters: () => Promise<ED[T]['Selection']['sorter']>;
getSorterByName: (name: string) => Promise<DeduceSorterItem<ED[T]['Schema']>>;
addNamedSorter: (filter: NamedSorterItem<ED, T>, refresh?: boolean) => void;
removeNamedSorter: (filter: NamedSorterItem<ED, T>, refresh?: boolean) => void;
removeSorterByName: (name: string, refresh?: boolean) => void;
navigateTo: <T2 extends keyof ED>(options: Parameters<typeof wx.navigateTo>[0] & OakNavigateToParameters<ED, T2>) => ReturnType<typeof wx.navigateTo>;
};
declare type OakPageMethods<ED extends EntityDict, T extends keyof ED> = OakComponentMethods<ED, T> & {
reRender: (extra?: any) => Promise<void>;
refresh: (extra?: any) => Promise<void>;
onPullDownRefresh: () => Promise<void>;
onLoad: () => Promise<void>;
subscribed?: () => void;
subscribe: () => void;
unsubscribe: () => void;
@ -98,13 +111,13 @@ export declare function initialize<ED extends EntityDict, Cxt extends Context<ED
[T in keyof ED]?: Array<ED[T]['OpSchema']>;
}, actionDict?: ActionDictOfEntityDict<ED>): {
OakPage: <T extends keyof ED, D extends WechatMiniprogram.Component.DataOption, P extends WechatMiniprogram.Component.PropertyOption, M extends WechatMiniprogram.Component.MethodOption, Proj extends ED[T]["Selection"]["data"], IS extends WechatMiniprogram.IAnyObject = {}, FormedData extends WechatMiniprogram.Component.DataOption = {}>(options: OakPageOption<ED, T, Cxt, AD, FD, Proj, FormedData>, componentOptions?: WechatMiniprogram.Component.Options<D, P, M, IS & OakPageInstanceProperties<ED, Cxt, AD, FD>, true>) => string;
OakComponent: <T_1 extends string | number, D_1 extends WechatMiniprogram.Component.DataOption, P_1 extends WechatMiniprogram.Component.PropertyOption, M_1 extends WechatMiniprogram.Component.MethodOption, Proj_1 extends ED[T_1]["Selection"]["data"], IS_1 extends WechatMiniprogram.IAnyObject = {}, FormedData_1 extends WechatMiniprogram.Component.DataOption = {}>(options: OakComponentOption<ED, T_1, Cxt, AD, FD, Proj_1, FormedData_1>, componentOptions?: OakWechatMpOptions<D_1, P_1, M_1, OakPageProperties, OakPageMethods<ED, T_1>, OakPageData, OakPageInstanceProperties<ED, Cxt, AD, FD>, IS_1, true>) => string;
OakComponent: <T_1 extends string | number, D_1 extends WechatMiniprogram.Component.DataOption, P_1 extends WechatMiniprogram.Component.PropertyOption, M_1 extends WechatMiniprogram.Component.MethodOption, Proj_1 extends ED[T_1]["Selection"]["data"], IS_1 extends WechatMiniprogram.IAnyObject = {}, FormedData_1 extends WechatMiniprogram.Component.DataOption = {}>(options: OakComponentOption<ED, T_1, Cxt, AD, FD, FormedData_1>, componentOptions?: OakWechatMpOptions<D_1, P_1, M_1, OakPageProperties, OakPageMethods<ED, T_1>, OakPageData, OakPageInstanceProperties<ED, Cxt, AD, FD>, IS_1, true>) => string;
features: BasicFeatures<ED, Cxt, AD> & FD;
};
/**
* WechatMiniprogram.Component.Options写的OakPage和OakComponent中第二个参数的定义
*/
declare type OakWechatMpOptions<TData extends WechatMiniprogram.Component.DataOption, TProperty extends WechatMiniprogram.Component.PropertyOption, TMethod extends WechatMiniprogram.Component.MethodOption, InherentProperties extends WechatMiniprogram.Component.PropertyOption, InherentMethods extends WechatMiniprogram.Component.MethodOption, InherentData extends WechatMiniprogram.Component.DataOption, InherentInstanceProperty extends WechatMiniprogram.IAnyObject, TCustomInstanceProperty extends WechatMiniprogram.IAnyObject = {}, TIsPage extends boolean = false> = Partial<TData> & Partial<WechatMiniprogram.Component.Property<TProperty>> & Partial<WechatMiniprogram.Component.Method<TMethod, TIsPage>> & Partial<WechatMiniprogram.Component.OtherOption> & Partial<WechatMiniprogram.Component.Lifetimes> & ThisType<WechatMiniprogram.Component.Instance<TData & InherentData, TProperty & InherentProperties, TMethod & InherentMethods, TCustomInstanceProperty & InherentInstanceProperty, TIsPage>>;
export declare type MakeOakPage<ED extends EntityDict, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD>>> = <T extends keyof ED, D extends WechatMiniprogram.Component.DataOption, P extends WechatMiniprogram.Component.PropertyOption, M extends WechatMiniprogram.Component.MethodOption, Proj extends ED[T]['Selection']['data'], IS extends WechatMiniprogram.IAnyObject = {}, FormedData extends WechatMiniprogram.Component.DataOption = {}>(options: OakPageOption<ED, T, Cxt, AD, FD, Proj, FormedData>, componentOptions: OakWechatMpOptions<D, P, M, OakPageProperties, OakPageMethods<ED, T>, OakPageData & FormedData, OakPageInstanceProperties<ED, Cxt, AD, FD>, IS, true>) => string;
export declare type MakeOakComponent<ED extends EntityDict, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD>>> = <T extends keyof ED, D extends WechatMiniprogram.Component.DataOption, P extends WechatMiniprogram.Component.PropertyOption, M extends WechatMiniprogram.Component.MethodOption, Proj extends ED[T]['Selection']['data'], IS extends WechatMiniprogram.IAnyObject = {}, FormedData extends WechatMiniprogram.Component.DataOption = {}>(options: OakComponentOption<ED, T, Cxt, AD, FD, Proj, FormedData>, componentOptions: OakWechatMpOptions<D, P, M, OakComponentProperties, OakComponentMethods<ED, T>, OakComponentData & FormedData, OakComponentInstanceProperties<ED, Cxt, AD, FD>, IS, true>) => string;
export declare type MakeOakPage<ED extends EntityDict, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD>>> = <T extends keyof ED, D extends WechatMiniprogram.Component.DataOption, P extends WechatMiniprogram.Component.PropertyOption, M extends WechatMiniprogram.Component.MethodOption, Proj extends ED[T]['Selection']['data'], IS extends WechatMiniprogram.IAnyObject = {}, FormedData extends WechatMiniprogram.Component.DataOption = {}>(options: OakPageOption<ED, T, Cxt, AD, FD, Proj, FormedData> & ThisType<WechatMiniprogram.Component.Instance<D & OakPageData, P & OakPageProperties, M & OakPageMethods<ED, T>, IS & OakPageInstanceProperties<ED, Cxt, AD, FD>, true>>, componentOptions: OakWechatMpOptions<D, P, M, OakPageProperties, OakPageMethods<ED, T>, OakPageData & FormedData, OakPageInstanceProperties<ED, Cxt, AD, FD>, IS, true>) => string;
export declare type MakeOakComponent<ED extends EntityDict, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD>>> = <T extends keyof ED, D extends WechatMiniprogram.Component.DataOption, P extends WechatMiniprogram.Component.PropertyOption, M extends WechatMiniprogram.Component.MethodOption, IS extends WechatMiniprogram.IAnyObject = {}, FormedData extends WechatMiniprogram.Component.DataOption = {}>(options: OakComponentOption<ED, T, Cxt, AD, FD, FormedData> & ThisType<WechatMiniprogram.Component.Instance<D & OakPageData, P & OakPageProperties, M & OakPageMethods<ED, T>, IS & OakPageInstanceProperties<ED, Cxt, AD, FD>, true>>, componentOptions: OakWechatMpOptions<D, P, M, OakComponentProperties, OakComponentMethods<ED, T>, OakComponentData & FormedData, OakComponentInstanceProperties<ED, Cxt, AD, FD>, IS, false>) => string;
export {};

View File

@ -10,9 +10,6 @@ const initialize_1 = require("../../initialize");
const assert_1 = __importDefault(require("assert"));
const lodash_1 = require("lodash");
;
function setFilters(features, fullpath, filters) {
features.runningNode.setFilters(fullpath, filters);
}
async function execute(features, fullpath, action) {
await features.runningNode.execute(fullpath, action);
}
@ -52,35 +49,43 @@ function createPageOptions(options, doSubscribe, features, exceptionRouterDict)
},
methods: {
async reRender() {
const $rows = await features.runningNode.get(this.data.oakFullpath);
const data = await formData($rows, features);
for (const k in data) {
if (data[k] === undefined) {
(0, lodash_1.assign)(data, {
[k]: null,
});
}
}
const dirty = await features.runningNode.isDirty(this.data.oakFullpath);
(0, lodash_1.assign)(data, { oakDirty: dirty });
if (this.data.oakActions) {
const oakLegalActions = [];
for (const action of this.data.oakActions) {
try {
await features.runningNode.testAction(this.data.oakFullpath, action);
oakLegalActions.push(action);
if (this.data.oakFullpath) {
const $rows = await features.runningNode.get(this.data.oakFullpath);
const data = await formData.call(this, $rows, features);
for (const k in data) {
if (data[k] === undefined) {
(0, lodash_1.assign)(data, {
[k]: null,
});
}
catch (e) {
if (e instanceof types_1.OakInputIllegalException) {
}
const dirty = await features.runningNode.isDirty(this.data.oakFullpath);
(0, lodash_1.assign)(data, { oakDirty: dirty });
if (this.data.oakActions) {
const oakLegalActions = [];
for (const action of this.data.oakActions) {
try {
await features.runningNode.testAction(this.data.oakFullpath, action);
oakLegalActions.push(action);
}
catch (e) {
if (e instanceof types_1.OakInputIllegalException) {
oakLegalActions.push(action);
}
}
}
(0, lodash_1.assign)(data, {
oakLegalActions,
});
}
(0, lodash_1.assign)(data, {
oakLegalActions,
});
this.setData(data);
}
this.setData(data);
},
async addNode(path, updateData) {
await features.runningNode.addNode({
parent: path ? `${this.data.oakFullpath}.${path}` : this.data.oakFullpath,
updateData,
});
},
async refresh() {
if (options.projection) {
@ -108,34 +113,25 @@ function createPageOptions(options, doSubscribe, features, exceptionRouterDict)
if (this.data.oakExecuting) {
return;
}
features.runningNode.setUpdateData(this.data.oakFullpath, attr, value);
return features.runningNode.setUpdateData(this.data.oakFullpath, attr, value);
},
callPicker(attr, params) {
if (this.data.oakExecuting) {
return;
}
callPicker(features, attr, params, options.entity, this.data.oakFullpath);
return callPicker(features, attr, params, this.data.oakEntity, this.data.oakFullpath);
},
async setForeignKey(id, goBackDelta = -1) {
if (this.data.oakExecuting) {
return;
}
const { oakParentEntity, oakPath, oakIsPicker, oakFullpath } = this.data;
if (oakIsPicker) {
const relation = features.cache.judgeRelation(oakParentEntity, oakPath);
const parentPath = oakFullpath.slice(0, oakFullpath.lastIndexOf('.'));
if (relation === 2) {
await features.runningNode.setMultipleData(parentPath, [['entity', oakPath], ['entityId', id]]);
}
else {
(0, assert_1.default)(typeof relation === 'string');
await features.runningNode.setUpdateData(parentPath, `${oakPath}Id`, id);
}
if (goBackDelta !== 0) {
wx.navigateBack({
delta: goBackDelta,
});
}
const { oakIsPicker } = this.data;
(0, assert_1.default)(oakIsPicker);
await features.runningNode.setForeignKey(this.data.oakFullpath, id);
if (goBackDelta !== 0) {
wx.navigateBack({
delta: goBackDelta,
});
}
},
onForeignKeyPicked(input) {
@ -143,7 +139,58 @@ function createPageOptions(options, doSubscribe, features, exceptionRouterDict)
this.setForeignKey(id);
},
setFilters(filters) {
setFilters(features, this.data.oakFullpath, filters);
return features.runningNode.setNamedFilters(this.data.oakFullpath, filters);
},
async getFilters() {
const namedFilters = await features.runningNode.getNamedFilters(this.data.oakFullpath);
const filters = await Promise.all(namedFilters.map(({ filter }) => {
if (typeof filter === 'function') {
return filter();
}
return filter;
}));
return filters;
},
getFilterByName(name) {
return features.runningNode.getNamedFilterByName(this.data.oakFullpath, name);
},
addNamedFilter(filter, refresh = false) {
return features.runningNode.addNamedFilter(this.data.oakFullpath, filter, refresh);
},
removeNamedFilter(filter, refresh = false) {
return features.runningNode.removeNamedFilter(this.data.oakFullpath, filter, refresh);
},
removeNamedFilterByName(name, refresh = false) {
return features.runningNode.removeNamedFilterByName(this.data.oakFullpath, name, refresh);
},
setNamedSorters(sorters) {
return features.runningNode.setNamedSorters(this.data.oakFullpath, sorters);
},
async getSorters() {
const namedSorters = await features.runningNode.getNamedSorters(this.data.oakFullpath);
const sorters = await Promise.all(namedSorters.map(({ sorter }) => {
if (typeof sorter === 'function') {
return sorter();
}
return sorter;
}));
return sorters;
},
async getSorterByName(name) {
const { sorter } = (await features.runningNode.getNamedSorterByName(this.data.oakFullpath, name));
if (typeof sorter === 'function') {
return sorter();
}
return sorter;
},
addNamedSorter(sorter, refresh = false) {
return features.runningNode.addNamedSorter(this.data.oakFullpath, sorter, refresh);
},
removeNamedSorter(sorter, refresh = false) {
return features.runningNode.removeNamedSorter(this.data.oakFullpath, sorter, refresh);
},
removeSorterByName(name, refresh = false) {
return features.runningNode.removeNamedSorterByName(this.data.oakFullpath, name, refresh);
},
async execute(action, afterExecuted) {
if (this.data.oakExecuting) {
@ -242,16 +289,8 @@ function createPageOptions(options, doSubscribe, features, exceptionRouterDict)
url: url2
});
return wx.navigateTo(options);
}
},
lifetimes: {
async created() {
this.features = features;
},
async attached() {
this.subscribe();
},
async ready() {
async onLoad() {
const { oakId, oakEntity, oakPath, oakProjection, oakParent, oakSorters, oakFilters, oakIsPicker, oakFrom, oakActions } = this.data;
(0, assert_1.default)(!(isList && oakId));
const filters = [];
@ -299,11 +338,35 @@ function createPageOptions(options, doSubscribe, features, exceptionRouterDict)
};
}));
}
await features.runningNode.createNode(oakPath || options.path, oakParent, (oakEntity || options.entity), isList, oakIsPicker, proj, oakId, pagination, filters, sorters);
const node = await features.runningNode.createNode({
path: oakPath || options.path,
parent: oakParent,
entity: (oakEntity || options.entity),
isList,
isPicker: oakIsPicker,
projection: proj,
pagination,
filters,
sorters,
id: oakId,
});
const oakFullpath = oakParent ? `${oakParent}.${oakPath || options.path}` : oakPath || options.path;
this.data.oakFullpath = oakFullpath;
this.data.oakFrom = oakFrom;
this.data.oakActions = oakActions.length > 0 ? oakActions : options.actions || [];
this.setData({
oakEntity: node.getEntity(),
oakFullpath,
oakFrom,
oakActions: oakActions.length > 0 ? oakActions : options.actions || [],
});
}
},
lifetimes: {
async created() {
this.features = features;
},
async attached() {
this.subscribe();
},
async ready() {
await this.refresh();
},
async detached() {
@ -334,9 +397,50 @@ function createComponentOptions(options, features, exceptionRouterDict) {
oakParent: String,
},
observers: {
"oakValue": async function (value) {
const $rows = value instanceof Array ? value : [value];
const data = await formData($rows, features);
"oakValue": function (value) {
/* const $rows = value instanceof Array ? value : [value];
const fileCarrier = this.data.oakFullpath && await features.runningNode.getFileCarrier(this.data.oakFullpath);
const data = await formData.call(this, $rows, features, fileCarrier as any);
for (const k in data) {
if (data[k] === undefined) {
assign(data, {
[k]: null,
});
}
}
const dirty = await features.runningNode.isDirty(this.data.oakFullpath);
this.setData(assign({}, data, {
oakDirty: dirty,
oakValue: $rows,
})); */
return this.onPropsChanged({
value,
});
},
"oakParent": function (parent) {
return this.onPropsChanged({
parent,
});
}
},
methods: {
async onPropsChanged(options) {
const value2 = options.hasOwnProperty('value') ? options.value : this.data.oakValue;
const parent2 = options.hasOwnProperty('parent') && options.parent;
const $rows = value2 instanceof Array ? value2 : [value2];
const data2 = {};
if (parent2) {
const node = await features.runningNode.createNode({
path: this.data.oakPath,
parent: parent2,
});
(0, lodash_1.assign)(data2, {
oakFullpath: `${parent2}.${this.data.oakPath}`,
oakEntity: node.getEntity(),
});
}
const fullpath = data2.oakFullpath || this.data.oakFullpath;
const data = await formData.call(this, $rows, features);
for (const k in data) {
if (data[k] === undefined) {
(0, lodash_1.assign)(data, {
@ -344,40 +448,83 @@ function createComponentOptions(options, features, exceptionRouterDict) {
});
}
}
const dirty = await features.runningNode.isDirty(this.data.oakFullpath);
this.setData((0, lodash_1.assign)({}, data, {
oakDirty: dirty,
const dirty = fullpath && await features.runningNode.isDirty(fullpath);
this.setData((0, lodash_1.assign)(data2, data, {
oakDirty: !!dirty,
// oakValue: value2,
}));
},
"oakParent": async function (oakParent) {
if (oakParent) {
const oakFullpath = `${oakParent}.${this.data.oakPath}`;
const entity = await features.runningNode.createNode(this.data.oakPath, oakParent);
this.setData({
oakFullpath,
entity,
});
async addNode(path, updateData) {
await features.runningNode.addNode({
parent: path ? `${this.data.oakFullpath}.${path}` : this.data.oakFullpath,
updateData,
});
},
async getFilters() {
const namedFilters = await features.runningNode.getNamedFilters(this.data.oakFullpath);
const filters = await Promise.all(namedFilters.map(({ filter }) => {
if (typeof filter === 'function') {
return filter();
}
return filter;
}));
return filters;
},
getFilterByName(name) {
return features.runningNode.getNamedFilterByName(this.data.oakFullpath, name);
},
addNamedFilter(namedFilter, refresh = false) {
return features.runningNode.addNamedFilter(this.data.oakFullpath, namedFilter, refresh);
},
removeNamedFilter(namedFilter, refresh = false) {
return features.runningNode.removeNamedFilter(this.data.oakFullpath, namedFilter, refresh);
},
removeNamedFilterByName(name, refresh = false) {
return features.runningNode.removeNamedFilterByName(this.data.oakFullpath, name, refresh);
},
setNamedSorters(namedSorters) {
return features.runningNode.setNamedSorters(this.data.oakFullpath, namedSorters);
},
async getSorters() {
const namedSorters = await features.runningNode.getNamedSorters(this.data.oakFullpath);
const sorters = await Promise.all(namedSorters.map(({ sorter }) => {
if (typeof sorter === 'function') {
return sorter();
}
return sorter;
}));
return sorters;
},
async getSorterByName(name) {
const { sorter } = (await features.runningNode.getNamedSorterByName(this.data.oakFullpath, name));
if (typeof sorter === 'function') {
return sorter();
}
}
},
methods: {
return sorter;
},
addNamedSorter(namedSorter, refresh = false) {
return features.runningNode.addNamedSorter(this.data.oakFullpath, namedSorter, refresh);
},
removeNamedSorter(namedSorter, refresh = false) {
return features.runningNode.removeNamedSorter(this.data.oakFullpath, namedSorter, refresh);
},
removeSorterByName(name, refresh = false) {
return features.runningNode.removeNamedSorterByName(this.data.oakFullpath, name, refresh);
},
setUpdateData(attr, value) {
if (this.data.oakExecuting) {
return;
}
features.runningNode.setUpdateData(this.data.oakFullpath, attr, value);
return features.runningNode.setUpdateData(this.data.oakFullpath, attr, value);
},
callPicker(attr, params) {
if (this.data.oakExecuting) {
return;
}
callPicker(features, attr, params, this.data.entity, this.data.oakFullpath);
return callPicker(features, attr, params, this.data.oakEntity, this.data.oakFullpath);
},
setFilters(filters) {
if (this.data.oakExecuting) {
return;
}
setFilters(features, this.data.oakFullpath, filters);
return features.runningNode.setNamedFilters(this.data.oakFullpath, filters);
},
/* async execute(action, afterExecuted) {
if (this.data.oakExecuting) {
@ -474,7 +621,7 @@ function createComponentOptions(options, features, exceptionRouterDict) {
async ready() {
const { oakPath, oakParent, oakValue } = this.data;
const $rows = oakValue instanceof Array ? oakValue : [oakValue];
const data = await formData($rows, features);
const data = await formData.call(this, $rows, features);
for (const k in data) {
if (data[k] === undefined) {
(0, lodash_1.assign)(data, {
@ -485,10 +632,13 @@ function createComponentOptions(options, features, exceptionRouterDict) {
if (oakParent) {
// 小程序component ready的时候父组件还未构造完成
const oakFullpath = `${oakParent}.${oakPath}`;
const entity = await features.runningNode.createNode(oakPath, oakParent);
const node = await features.runningNode.createNode({
path: oakPath,
parent: oakParent,
});
this.setData((0, lodash_1.assign)(data, {
oakFullpath,
entity,
oakEntity: node.getEntity,
}));
}
else {
@ -574,6 +724,24 @@ function mergePageLifetimes(lifetimes) {
},
};
}
function mergeMethods(methods) {
const merged = {};
const names = (0, lodash_1.union)(...(methods.map(ele => Object.keys(ele))));
for (const name of names) {
Object.assign(merged, {
[name]: function () {
let result;
for (const m of methods) {
if (m[name]) {
result = m[name].apply(this, arguments);
}
}
return result;
}
});
}
return merged;
}
function initialize(storageSchema, createFeatures, createContext, exceptionRouters = [], triggers, checkers, aspectDict, initialData, actionDict) {
const { subscribe, features } = (0, initialize_1.initialize)(storageSchema, createFeatures, createContext, triggers, checkers, aspectDict, initialData, actionDict);
const exceptionRouterDict = {};
@ -599,13 +767,7 @@ function initialize(storageSchema, createFeatures, createContext, exceptionRoute
data: (0, lodash_1.assign)({}, d2, data),
properties: (0, lodash_1.assign)({}, p2, properties),
observers: (0, lodash_1.assign)({}, o2, observers),
methods: {
onLoad() {
// console.log('onLoad', this.data.oakId);
},
...m2,
...methods,
},
methods: (m2 ? mergeMethods([methods, m2]) : methods),
pageLifetimes: mergePageLifetimes(pls),
lifetimes: mergeLifetimes(ls),
...restOptions,
@ -621,7 +783,7 @@ function initialize(storageSchema, createFeatures, createContext, exceptionRoute
data: (0, lodash_1.assign)({}, d2, data),
properties: (0, lodash_1.assign)({}, p2, properties),
observers: (0, lodash_1.assign)({}, o2, observers),
methods: (0, lodash_1.assign)({}, m2, methods),
methods: (m2 ? mergeMethods([methods, m2]) : methods),
pageLifetimes: mergePageLifetimes(pls),
lifetimes: mergeLifetimes(ls),
...restOptions,

2
lib/utils/mockId.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
export declare function generateMockId(): string;
export declare function isMockId(id: string): boolean;

11
lib/utils/mockId.js Normal file
View File

@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isMockId = exports.generateMockId = void 0;
function generateMockId() {
return `__mock-${Math.ceil(Math.random() * 100000000000)}`;
}
exports.generateMockId = generateMockId;
function isMockId(id) {
return id.startsWith('__mock-');
}
exports.isMockId = isMockId;

View File

View File

@ -1 +0,0 @@
"use strict";

View File

@ -10,7 +10,6 @@ import { judgeRelation } from 'oak-domain/lib/store/relation';
import { StorageSchema } from 'oak-domain/lib/types/Storage';
import { Pagination } from '../types/Pagination';
import { NamedFilterItem, NamedSorterItem } from '../types/NamedCondition';
import { FileCarrier } from '../types/FileCarrier';
import { generateMockId } from '../utils/mockId';
export class Node<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>> {
@ -248,20 +247,20 @@ class ListNode<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED
}
}
getFilters() {
getNamedFilters() {
return this.filters;
}
getFilterByName(name: string) {
getNamedFilterByName(name: string) {
const filter = this.filters.find((ele) => ele['#name'] === name);
return filter;
}
setFilters(filters: NamedFilterItem<ED, T>[]) {
setNamedFilters(filters: NamedFilterItem<ED, T>[]) {
this.filters = filters;
}
addFilter(filter: NamedFilterItem<ED, T>) {
addNamedFilter(filter: NamedFilterItem<ED, T>) {
// filter 根据#name查找
const fIndex = this.filters.findIndex(ele => filter['#name'] && ele['#name'] === filter['#name']);
if (fIndex >= 0) {
@ -271,7 +270,7 @@ class ListNode<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED
}
}
removeFilter(filter: NamedFilterItem<ED, T>) {
removeNamedFilter(filter: NamedFilterItem<ED, T>) {
// filter 根据#name查找
const fIndex = this.filters.findIndex(ele => filter['#name'] && ele['#name'] === filter['#name']);
if (fIndex >= 0) {
@ -279,7 +278,7 @@ class ListNode<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED
}
}
removeFilterByName(name: string) {
removeNamedFilterByName(name: string) {
// filter 根据#name查找
const fIndex = this.filters.findIndex(ele => ele['#name'] === name);
if (fIndex >= 0) {
@ -287,20 +286,20 @@ class ListNode<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED
}
}
getSorters() {
getNamedSorters() {
return this.sorters;
}
getSorterByName(name: string) {
getNamedSorterByName(name: string) {
const sorter = this.sorters.find((ele) => ele['#name'] === name);
return sorter;
}
setSorters(sorters: NamedSorterItem<ED, T>[]) {
setNamedSorters(sorters: NamedSorterItem<ED, T>[]) {
this.sorters = sorters;
}
addSorter(sorter: NamedSorterItem<ED, T>) {
addNamedSorter(sorter: NamedSorterItem<ED, T>) {
// sorter 根据#name查找
const fIndex = this.sorters.findIndex(ele => sorter['#name'] && ele['#name'] === sorter['#name']);
if (fIndex >= 0) {
@ -310,7 +309,7 @@ class ListNode<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED
}
}
removeSorter(sorter: NamedSorterItem<ED, T>) {
removeNamedSorter(sorter: NamedSorterItem<ED, T>) {
// sorter 根据#name查找
const fIndex = this.sorters.findIndex(ele => sorter['#name'] && ele['#name'] === sorter['#name']);
if (fIndex >= 0) {
@ -318,7 +317,7 @@ class ListNode<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED
}
}
removeSorterByName(name: string) {
removeNamedSorterByName(name: string) {
// sorter 根据#name查找
const fIndex = this.sorters.findIndex(ele => ele['#name'] === name);
if (fIndex >= 0) {
@ -1117,127 +1116,111 @@ export class RunningNode<ED extends EntityDict, Cxt extends Context<ED>, AD exte
await node.refresh();
}
async getFilters<T extends keyof ED>(path: string) {
async getNamedFilters<T extends keyof ED>(path: string) {
const node = await this.findNode(path);
if (node instanceof ListNode) {
return await node.getFilters();
}
assert (node instanceof ListNode);
return await node.getNamedFilters();
}
async getFilterByName<T extends keyof ED>(path: string, name: string) {
async getNamedFilterByName<T extends keyof ED>(path: string, name: string) {
const node = await this.findNode(path);
if (node instanceof ListNode) {
return await node.getFilterByName(name);
assert (node instanceof ListNode);
return await node.getNamedFilterByName(name);
}
@Action
async setNamedFilters<T extends keyof ED>(path: string, filters: NamedFilterItem<ED, T>[], refresh: boolean = true) {
const node = await this.findNode(path);
assert (node instanceof ListNode);
node.setNamedFilters(filters);
if (refresh) {
await node.refresh();
}
}
@Action
async setFilters<T extends keyof ED>(path: string, filters: NamedFilterItem<ED, T>[], refresh: boolean = true) {
async addNamedFilter<T extends keyof ED>(path: string, filter: NamedFilterItem<ED, T>, refresh: boolean = false) {
const node = await this.findNode(path);
if (node instanceof ListNode) {
node.setFilters(filters);
if (refresh) {
await node.refresh();
}
assert (node instanceof ListNode);
node.addNamedFilter(filter);
if (refresh) {
await node.refresh();
}
}
@Action
async addFilter<T extends keyof ED>(path: string, filter: NamedFilterItem<ED, T>, refresh: boolean = false) {
async removeNamedFilter<T extends keyof ED>(path: string, filter: NamedFilterItem<ED, T>, refresh: boolean = false) {
const node = await this.findNode(path);
if (node instanceof ListNode) {
node.addFilter(filter);
if (refresh) {
await node.refresh();
}
assert (node instanceof ListNode);
node.removeNamedFilter(filter);
if (refresh) {
await node.refresh();
}
}
@Action
async removeFilter<T extends keyof ED>(path: string, filter: NamedFilterItem<ED, T>, refresh: boolean = false) {
async removeNamedFilterByName<T extends keyof ED>(path: string, name: string, refresh: boolean = false) {
const node = await this.findNode(path);
if (node instanceof ListNode) {
node.removeFilter(filter);
if (refresh) {
await node.refresh();
}
assert (node instanceof ListNode);
node.removeNamedFilterByName(name);
if (refresh) {
await node.refresh();
}
}
async getNamedSorters<T extends keyof ED>(path: string) {
const node = await this.findNode(path);
assert (node instanceof ListNode);
return await node.getNamedSorters();
}
async getNamedSorterByName<T extends keyof ED>(path: string, name: string) {
const node = await this.findNode(path);
assert (node instanceof ListNode);
return await node.getNamedSorterByName(name);
}
@Action
async setNamedSorters<T extends keyof ED>(path: string, sorters: NamedSorterItem<ED, T>[], refresh: boolean = true) {
const node = await this.findNode(path);
assert (node instanceof ListNode);
node.setNamedSorters(sorters);
if (refresh) {
await node.refresh();
}
}
@Action
async removeFilterByName<T extends keyof ED>(path: string, name: string, refresh: boolean = false) {
async addNamedSorter<T extends keyof ED>(path: string, sorter: NamedSorterItem<ED, T>, refresh: boolean = false) {
const node = await this.findNode(path);
if (node instanceof ListNode) {
node.removeFilterByName(name);
if (refresh) {
await node.refresh();
}
assert (node instanceof ListNode);
node.addNamedSorter(sorter);
if (refresh) {
await node.refresh();
}
}
@Action
async removeNamedSorter<T extends keyof ED>(path: string, sorter: NamedSorterItem<ED, T>, refresh: boolean = false) {
const node = await this.findNode(path);
assert (node instanceof ListNode);
node.removeNamedSorter(sorter);
if (refresh) {
await node.refresh();
}
}
@Action
async removeNamedSorterByName<T extends keyof ED>(path: string, name: string, refresh: boolean = false) {
const node = await this.findNode(path);
assert (node instanceof ListNode);
node.removeNamedSorterByName(name);
if (refresh) {
await node.refresh();
}
}
<<<<<<< HEAD
async testAction(path: string, action: string, realId?: boolean) {
=======
async getSorters<T extends keyof ED>(path: string) {
const node = await this.findNode(path);
if (node instanceof ListNode) {
return await node.getSorters();
}
}
async getSorterByName<T extends keyof ED>(path: string, name: string) {
const node = await this.findNode(path);
if (node instanceof ListNode) {
return await node.getSorterByName(name);
}
}
@Action
async setSorters<T extends keyof ED>(path: string, sorters: NamedSorterItem<ED, T>[], refresh: boolean = true) {
const node = await this.findNode(path);
if (node instanceof ListNode) {
node.setSorters(sorters);
if (refresh) {
await node.refresh();
}
}
}
@Action
async addSorter<T extends keyof ED>(path: string, sorter: NamedSorterItem<ED, T>, refresh: boolean = false) {
const node = await this.findNode(path);
if (node instanceof ListNode) {
node.addSorter(sorter);
if (refresh) {
await node.refresh();
}
}
}
@Action
async removeSorter<T extends keyof ED>(path: string, sorter: NamedSorterItem<ED, T>, refresh: boolean = false) {
const node = await this.findNode(path);
if (node instanceof ListNode) {
node.removeSorter(sorter);
if (refresh) {
await node.refresh();
}
}
}
@Action
async removeSorterByName<T extends keyof ED>(path: string, name: string, refresh: boolean = false) {
const node = await this.findNode(path);
if (node instanceof ListNode) {
node.removeSorterByName(name);
if (refresh) {
await node.refresh();
}
}
}
async testAction(path: string, action: string) {
>>>>>>> 902cba0c2cd4e94ca0aeaeb59ec449623dab3c42
const node = await this.findNode(path);
const operation = await node.composeOperation(action, realId);
// 先在cache中尝试能否执行如果权限上否决了在这里就失败
@ -1267,7 +1250,7 @@ export class RunningNode<ED extends EntityDict, Cxt extends Context<ED>, AD exte
@Action
async execute(path: string, action: string) {
const { node, operation } = await this.testAction(path, action);
const { node, operation } = await this.testAction(path, action, true);
await this.getAspectProxy().operate({
entity: node.getEntity() as string,

View File

@ -86,20 +86,20 @@ type OakNavigateToParameters<ED extends EntityDict, T extends keyof ED> = {
};
type OakComponentMethods<ED extends EntityDict, T extends keyof ED> = {
addNode: (path?: string, updateData?: object) =>Promise<void>;
addNode: (path?: string, updateData?: object) => Promise<void>;
setUpdateData: (attr: string, input: any) => void;
callPicker: (attr: string, params: Record<string, any>) => void;
setFilters: (filters: NamedFilterItem<ED, T>[]) => void;
getFilters: () => void;
getFilterByName: (name: string) => void;
addFilter: (filter: NamedFilterItem<ED, T>, refresh?: boolean) => void;
removeFilter: (filter: NamedFilterItem<ED, T>, refresh?: boolean) => void;
removeFilterByName: (name: string, refresh?: boolean) => void;
setSorters: (sorters: NamedSorterItem<ED, T>[]) => void;
getSorters: () => void;
getSorterByName: (name: string) => void;
addSorter: (filter: NamedSorterItem<ED, T>, refresh?: boolean) => void;
removeSorter: (filter: NamedSorterItem<ED, T>, refresh?: boolean) => void;
getFilters: () => Promise<ED[T]['Selection']['filter'][]>;
getFilterByName: (name: string) => Promise<ED[T]['Selection']['filter']>;
addNamedFilter: (filter: NamedFilterItem<ED, T>, refresh?: boolean) => void;
removeNamedFilter: (filter: NamedFilterItem<ED, T>, refresh?: boolean) => void;
removeNamedFilterByName: (name: string, refresh?: boolean) => void;
setNamedSorters: (sorters: NamedSorterItem<ED, T>[]) => void;
getSorters: () => Promise<ED[T]['Selection']['sorter']>;
getSorterByName: (name: string) => Promise<DeduceSorterItem<ED[T]['Schema']>>;
addNamedSorter: (filter: NamedSorterItem<ED, T>, refresh?: boolean) => void;
removeNamedSorter: (filter: NamedSorterItem<ED, T>, refresh?: boolean) => void;
removeSorterByName: (name: string, refresh?: boolean) => void;
navigateTo: <T2 extends keyof ED>(options: Parameters<typeof wx.navigateTo>[0] & OakNavigateToParameters<ED, T2>) => ReturnType<typeof wx.navigateTo>;
};
@ -109,7 +109,7 @@ type ComponentOnPropsChangeOption = {
parent?: string;
}
type OakComponentOnlyMethods = {
type OakComponentOnlyMethods = {
onPropsChanged: (options: ComponentOnPropsChangeOption) => Promise<void>;
};
@ -233,7 +233,7 @@ function createPageOptions<ED extends EntityDict,
}
const dirty = await features.runningNode.isDirty(this.data.oakFullpath);
assign(data, { oakDirty: dirty });
if (this.data.oakActions) {
const oakLegalActions = [];
for (const action of this.data.oakActions) {
@ -251,7 +251,7 @@ function createPageOptions<ED extends EntityDict,
oakLegalActions,
});
}
this.setData(data);
}
},
@ -326,51 +326,77 @@ function createPageOptions<ED extends EntityDict,
},
setFilters(filters) {
return features.runningNode.setFilters(this.data.oakFullpath, filters);
return features.runningNode.setNamedFilters(this.data.oakFullpath, filters);
},
getFilters() {
return features.runningNode.getFilters(this.data.oakFullpath);
async getFilters() {
const namedFilters = await features.runningNode.getNamedFilters(this.data.oakFullpath);
const filters = await Promise.all(
namedFilters.map(
({ filter }) => {
if (typeof filter === 'function') {
return filter();
}
return filter;
}
)
);
return filters;
},
getFilterByName(name) {
return features.runningNode.getFilterByName(this.data.oakFullpath, name)
return features.runningNode.getNamedFilterByName(this.data.oakFullpath, name)
},
addFilter(filter, refresh = false) {
return features.runningNode.addFilter(this.data.oakFullpath, filter, refresh);
addNamedFilter(filter, refresh = false) {
return features.runningNode.addNamedFilter(this.data.oakFullpath, filter, refresh);
},
removeFilter(filter, refresh = false) {
return features.runningNode.removeFilter(this.data.oakFullpath, filter, refresh);
removeNamedFilter(filter, refresh = false) {
return features.runningNode.removeNamedFilter(this.data.oakFullpath, filter, refresh);
},
removeFilterByName(name, refresh = false) {
return features.runningNode.removeFilterByName(this.data.oakFullpath, name, refresh);
removeNamedFilterByName(name, refresh = false) {
return features.runningNode.removeNamedFilterByName(this.data.oakFullpath, name, refresh);
},
setSorters(sorters) {
return features.runningNode.setSorters(this.data.oakFullpath, sorters);
setNamedSorters(sorters) {
return features.runningNode.setNamedSorters(this.data.oakFullpath, sorters);
},
getSorters() {
return features.runningNode.getSorters(this.data.oakFullpath);
async getSorters() {
const namedSorters = await features.runningNode.getNamedSorters(this.data.oakFullpath);
const sorters = await Promise.all(
namedSorters.map(
({ sorter }) => {
if (typeof sorter === 'function') {
return sorter();
}
return sorter;
}
)
);
return sorters;
},
getSorterByName(name) {
return features.runningNode.getSorterByName(this.data.oakFullpath, name)
async getSorterByName(name) {
const { sorter } = (await features.runningNode.getNamedSorterByName(this.data.oakFullpath, name))!;
if (typeof sorter === 'function') {
return sorter();
}
return sorter;
},
addSorter(sorter, refresh = false) {
return features.runningNode.addSorter(this.data.oakFullpath, sorter, refresh);
addNamedSorter(sorter, refresh = false) {
return features.runningNode.addNamedSorter(this.data.oakFullpath, sorter, refresh);
},
removeSorter(sorter, refresh = false) {
return features.runningNode.removeSorter(this.data.oakFullpath, sorter, refresh);
removeNamedSorter(sorter, refresh = false) {
return features.runningNode.removeNamedSorter(this.data.oakFullpath, sorter, refresh);
},
removeSorterByName(name, refresh = false) {
return features.runningNode.removeSorterByName(this.data.oakFullpath, name, refresh);
return features.runningNode.removeNamedSorterByName(this.data.oakFullpath, name, refresh);
},
async execute(action, afterExecuted) {
@ -632,7 +658,7 @@ function createComponentOptions<ED extends EntityDict,
"oakParent": function (parent) {
return this.onPropsChanged({
parent,
})
})
}
},
methods: {
@ -666,7 +692,7 @@ function createComponentOptions<ED extends EntityDict,
// oakValue: value2,
}));
},
async addNode(path, updateData) {
await features.runningNode.addNode({
parent: path ? `${this.data.oakFullpath}.${path}` : this.data.oakFullpath,
@ -674,48 +700,74 @@ function createComponentOptions<ED extends EntityDict,
});
},
getFilters() {
return features.runningNode.getFilters(this.data.oakFullpath);
async getFilters() {
const namedFilters = await features.runningNode.getNamedFilters(this.data.oakFullpath);
const filters = await Promise.all(
namedFilters.map(
({ filter }) => {
if (typeof filter === 'function') {
return filter();
}
return filter;
}
)
);
return filters;
},
getFilterByName(name) {
return features.runningNode.getFilterByName(this.data.oakFullpath, name)
return features.runningNode.getNamedFilterByName(this.data.oakFullpath, name)
},
addFilter(filter, refresh = false) {
return features.runningNode.addFilter(this.data.oakFullpath, filter, refresh);
addNamedFilter(namedFilter, refresh = false) {
return features.runningNode.addNamedFilter(this.data.oakFullpath, namedFilter, refresh);
},
removeFilter(filter, refresh = false) {
return features.runningNode.removeFilter(this.data.oakFullpath, filter, refresh);
removeNamedFilter(namedFilter, refresh = false) {
return features.runningNode.removeNamedFilter(this.data.oakFullpath, namedFilter, refresh);
},
removeFilterByName(name, refresh = false) {
return features.runningNode.removeFilterByName(this.data.oakFullpath, name, refresh);
removeNamedFilterByName(name, refresh = false) {
return features.runningNode.removeNamedFilterByName(this.data.oakFullpath, name, refresh);
},
setSorters(sorters) {
return features.runningNode.setSorters(this.data.oakFullpath, sorters);
setNamedSorters(namedSorters) {
return features.runningNode.setNamedSorters(this.data.oakFullpath, namedSorters);
},
getSorters() {
return features.runningNode.getSorters(this.data.oakFullpath);
async getSorters() {
const namedSorters = await features.runningNode.getNamedSorters(this.data.oakFullpath);
const sorters = await Promise.all(
namedSorters.map(
({ sorter }) => {
if (typeof sorter === 'function') {
return sorter();
}
return sorter;
}
)
);
return sorters;
},
getSorterByName(name) {
return features.runningNode.getSorterByName(this.data.oakFullpath, name)
async getSorterByName(name) {
const { sorter } = (await features.runningNode.getNamedSorterByName(this.data.oakFullpath, name))!;
if (typeof sorter === 'function') {
return sorter();
}
return sorter;
},
addSorter(sorter, refresh = false) {
return features.runningNode.addSorter(this.data.oakFullpath, sorter, refresh);
addNamedSorter(namedSorter, refresh = false) {
return features.runningNode.addNamedSorter(this.data.oakFullpath, namedSorter, refresh);
},
removeSorter(sorter, refresh = false) {
return features.runningNode.removeSorter(this.data.oakFullpath, sorter, refresh);
removeNamedSorter(namedSorter, refresh = false) {
return features.runningNode.removeNamedSorter(this.data.oakFullpath, namedSorter, refresh);
},
removeSorterByName(name, refresh = false) {
return features.runningNode.removeSorterByName(this.data.oakFullpath, name, refresh);
return features.runningNode.removeNamedSorterByName(this.data.oakFullpath, name, refresh);
},
setUpdateData(attr, value) {
@ -733,7 +785,7 @@ function createComponentOptions<ED extends EntityDict,
},
setFilters(filters) {
return features.runningNode.setFilters(this.data.oakFullpath, filters);
return features.runningNode.setNamedFilters(this.data.oakFullpath, filters);
},
/* async execute(action, afterExecuted) {
@ -1111,7 +1163,16 @@ export type MakeOakPage<
IS extends WechatMiniprogram.IAnyObject = {},
FormedData extends WechatMiniprogram.Component.DataOption = {}
> (
options: OakPageOption<ED, T, Cxt, AD, FD, Proj, FormedData>,
options: OakPageOption<ED, T, Cxt, AD, FD, Proj, FormedData> &
ThisType<
WechatMiniprogram.Component.Instance<
D & OakPageData,
P & OakPageProperties,
M & OakPageMethods<ED, T>,
IS & OakPageInstanceProperties<ED, Cxt, AD, FD>,
true
>
>,
componentOptions: OakWechatMpOptions<
D,
P,
@ -1138,7 +1199,16 @@ export type MakeOakComponent<
IS extends WechatMiniprogram.IAnyObject = {},
FormedData extends WechatMiniprogram.Component.DataOption = {}
>(
options: OakComponentOption<ED, T, Cxt, AD, FD, FormedData>,
options: OakComponentOption<ED, T, Cxt, AD, FD, FormedData> &
ThisType<
WechatMiniprogram.Component.Instance<
D & OakPageData,
P & OakPageProperties,
M & OakPageMethods<ED, T>,
IS & OakPageInstanceProperties<ED, Cxt, AD, FD>,
true
>
>,
componentOptions: OakWechatMpOptions<
D,
P,

View File

@ -1,7 +0,0 @@
import { EntityDict, EntityShape } from "oak-domain/lib/types";
export abstract class FileCarrier<ED extends EntityDict, T extends keyof ED> {
abstract getBytes(): Promise<Uint8Array>;
abstract upload(entity: T, data: ED[T]['OpSchema']): Promise<void>;
}

View File

@ -1,23 +0,0 @@
import { EntityDict } from "oak-domain/lib/types";
import { FileCarrier } from "../types/FileCarrier";
export class WechatMpFileCarrier<ED extends EntityDict, T extends keyof ED> extends FileCarrier<ED, T> {
private file: WechatMiniprogram.MediaFile;
constructor(_file: WechatMiniprogram.MediaFile) {
super();
this.file = _file;
}
getFile() {
return this.file;
}
getBytes(): Promise<Uint8Array> {
throw new Error("Method not implemented.");
}
upload(entity: T, data: ED[T]["OpSchema"]): Promise<void> {
throw new Error("Method not implemented.");
}
}

View File

@ -1,5 +1,5 @@
export function generateMockId() {
return `__mock-${Math.random()}`;
return `__mock-${Math.ceil(Math.random() * 100000000000)}`;
}
export function isMockId(id: string) {

View File

@ -1,12 +1,14 @@
type IsOptional<T, K extends keyof T> = { [K1 in Exclude<keyof T, K>]: T[K1] } & { K?: T[K] } extends T ? K : never
type OptionalKeys<T> = { [K in keyof T]: IsOptional<T, K> }[keyof T]
type A = {
a: number
b?: {
x: string
}
c?:string
d?:1
area: object;
areaId: never,
} | {
areaId: string;
area?: number;
}
type RR = OptionalKeys<A> // type RR = "b" | "c"
const a: A = {
areaId: 'ddd',
area: {
bb: 1,
},
}