Skip to content

Commit

Permalink
V7 Backports (#845)
Browse files Browse the repository at this point in the history
* Handle ignored children in decorate (#840)

* Allow finding and modifying wrapped widgets in functional children (#780)

* Add function to create "typed" version of middleware (#819)

* Add factory function to middleware for adding types

* change to withType

* Fix mock middleware types (#822)

* Wrap children result in an array if not already in one (#844)

* wrap children result in an array if not already in one

* add test for wrapped children

* update assert render unit test (#820)

Co-authored-by: Bradley Maier <[email protected]>
Co-authored-by: Anthony Gubler <[email protected]>
  • Loading branch information
3 people authored Sep 23, 2020
1 parent b1bbd38 commit 3fc3011
Show file tree
Hide file tree
Showing 11 changed files with 401 additions and 239 deletions.
6 changes: 6 additions & 0 deletions src/core/interfaces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,12 @@ export interface DefaultMiddlewareResult extends MiddlewareResult<any, any, any,

export interface MiddlewareResultFactory<Props, Children, Middleware, ReturnValue> {
(): MiddlewareResult<Props, Children, Middleware, ReturnValue>;
withType: <Api extends ReturnValue, CustomProps = Props>() => MiddlewareResultFactory<
CustomProps,
Children,
Middleware,
Api
>;
}

export interface DefaultChildrenWNodeFactory<W extends WNodeFactoryTypes> {
Expand Down
137 changes: 68 additions & 69 deletions src/core/middleware/icache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,80 +52,79 @@ export interface ICacheResult<S = void> {
clear(invalidate?: boolean): void;
}

export function createICacheMiddleware<S = void>() {
const icache = factory(
({ middleware: { invalidator, destroy } }): ICacheResult<S> => {
const cacheMap = new Map<string, CacheWrapper>();
destroy(() => {
cacheMap.clear();
});

const api: any = {
get: (key: any): any => {
const cachedValue = cacheMap.get(key);
if (!cachedValue || cachedValue.status === 'pending') {
return undefined;
}
return cachedValue.value;
}
};
const icacheFactory = factory(
({ middleware: { invalidator, destroy } }): ICacheResult<any> => {
const cacheMap = new Map<string, CacheWrapper>();
destroy(() => {
cacheMap.clear();
});

api.set = (key: any, value: any, invalidate: boolean = true): any => {
const current = api.get(key);
if (typeof value === 'function') {
value = value(current);
if (value && typeof value.then === 'function') {
cacheMap.set(key, {
status: 'pending',
value
});
value.then((result: any) => {
const cachedValue = cacheMap.get(key);
if (cachedValue && cachedValue.value === value) {
cacheMap.set(key, {
status: 'resolved',
value: result
});
invalidate && invalidator();
}
});
return undefined;
}
}
cacheMap.set(key, {
status: 'resolved',
value
});
invalidate && invalidator();
return value;
};
api.has = (key: any) => {
return cacheMap.has(key);
};
api.delete = (key: any, invalidate: boolean = true) => {
cacheMap.delete(key);
invalidate && invalidator();
};
api.clear = (invalidate: boolean = true): void => {
cacheMap.clear();
invalidate && invalidator();
};
api.getOrSet = (key: any, value: any, invalidate: boolean = true): any | undefined => {
let cachedValue = cacheMap.get(key);
if (!cachedValue) {
api.set(key, value, invalidate);
}
cachedValue = cacheMap.get(key);
const api: any = {
get: (key: any): any => {
const cachedValue = cacheMap.get(key);
if (!cachedValue || cachedValue.status === 'pending') {
return undefined;
}
return cachedValue.value;
};
return api;
}
);
return icache;
}
}
};

api.set = (key: any, value: any, invalidate: boolean = true): any => {
const current = api.get(key);
if (typeof value === 'function') {
value = value(current);
if (value && typeof value.then === 'function') {
cacheMap.set(key, {
status: 'pending',
value
});
value.then((result: any) => {
const cachedValue = cacheMap.get(key);
if (cachedValue && cachedValue.value === value) {
cacheMap.set(key, {
status: 'resolved',
value: result
});
invalidate && invalidator();
}
});
return undefined;
}
}
cacheMap.set(key, {
status: 'resolved',
value
});
invalidate && invalidator();
return value;
};
api.has = (key: any) => {
return cacheMap.has(key);
};
api.delete = (key: any, invalidate: boolean = true) => {
cacheMap.delete(key);
invalidate && invalidator();
};
api.clear = (invalidate: boolean = true): void => {
cacheMap.clear();
invalidate && invalidator();
};
api.getOrSet = (key: any, value: any, invalidate: boolean = true): any | undefined => {
let cachedValue = cacheMap.get(key);
if (!cachedValue) {
api.set(key, value, invalidate);
}
cachedValue = cacheMap.get(key);
if (!cachedValue || cachedValue.status === 'pending') {
return undefined;
}
return cachedValue.value;
};
return api;
}
);

export const createICacheMiddleware = <S = void>() => icacheFactory.withType<ICacheResult<S>>();

export const icache = createICacheMiddleware();

Expand Down
Loading

0 comments on commit 3fc3011

Please sign in to comment.