Adding Rsx and decorator
This commit is contained in:
parent
d18601132e
commit
9b6788b47b
@ -432,7 +432,7 @@ const sharedMethods = injectedClasses[0].getMethods()
|
|||||||
const parsedMethods = sharedMethods.map(methodObject => getMethodInfo(methodObject.declaration as MethodDeclaration));
|
const parsedMethods = sharedMethods.map(methodObject => getMethodInfo(methodObject.declaration as MethodDeclaration));
|
||||||
|
|
||||||
// Get the Properties
|
// Get the Properties
|
||||||
const sharedObservables = getMatchingProperties(injectedClasses[0], 'IObservable', false)
|
const sharedObservables = getMatchingProperties(injectedClasses[0], 'NopeObersvable', false)
|
||||||
.filter(property =>
|
.filter(property =>
|
||||||
property.isPublic &&
|
property.isPublic &&
|
||||||
getDecorators(property.declaration, 'inject', importMapping.aliasToOriginal, false, false)
|
getDecorators(property.declaration, 'inject', importMapping.aliasToOriginal, false, false)
|
||||||
|
88
lib/decorators.ts
Normal file
88
lib/decorators.ts
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
// Symbols for the Property Registery:
|
||||||
|
const _registedMethods_ = Symbol('_registedMethods_');
|
||||||
|
const _registedParams_ = Symbol('_registedParams_');
|
||||||
|
|
||||||
|
// Interfaces for the Class
|
||||||
|
export interface IExportApiParameters {
|
||||||
|
url: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IExportMethodParameters {
|
||||||
|
url?: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IExportPropertyParameters {
|
||||||
|
url?: string,
|
||||||
|
readonly?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export const unicorn = {
|
||||||
|
test: []
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorator used to export a Class API over openAPI
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
export function eportApi(options: IExportApiParameters) {
|
||||||
|
return function <T extends { new(...args: any[]): {} }>(Base: T) {
|
||||||
|
return class extends Base {
|
||||||
|
constructor(...args: any[]) {
|
||||||
|
super(...args);
|
||||||
|
|
||||||
|
// Adding the Path Option.
|
||||||
|
(this as any).__path = options.url;
|
||||||
|
|
||||||
|
// extract the Registered Methods of the Class.
|
||||||
|
const registedMethods = Base.prototype[_registedMethods_] as Map<string, IExportMethodParameters>;
|
||||||
|
const registedParams = Base.prototype[_registedParams_] as Map<string, IExportPropertyParameters>;
|
||||||
|
|
||||||
|
// Online if they are present, iterate over them
|
||||||
|
if (registedMethods) {
|
||||||
|
registedMethods.forEach((options, methodName) => {
|
||||||
|
|
||||||
|
// Provide the code that should be exectuted for every
|
||||||
|
// Registered Function
|
||||||
|
unicorn.test.push([methodName, options]);
|
||||||
|
console.log(unicorn.test)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Online if they are present, iterate over them
|
||||||
|
if (registedParams) {
|
||||||
|
registedParams.forEach((options, parameterName) => {
|
||||||
|
|
||||||
|
// Provide the code that should be exectuted for every
|
||||||
|
// Registered Function
|
||||||
|
unicorn.test.push([parameterName, options]);
|
||||||
|
console.log(unicorn.test)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorator, used to export the Method.
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
export function exportMethod(options: IExportMethodParameters = {}) {
|
||||||
|
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
||||||
|
target[_registedMethods_] = target[_registedMethods_] || new Map<string, IExportMethodParameters>();
|
||||||
|
// Here we just add some information that class decorator will use
|
||||||
|
target[_registedMethods_].set(propertyKey, options);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorator, will create a POST and GET api for the Parameter.
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
export function exportProperty(options: IExportPropertyParameters = {}) {
|
||||||
|
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
||||||
|
target[_registedParams_] = target[_registedParams_] || new Map<string, IExportPropertyParameters>();
|
||||||
|
// Here we just add some information that class decorator will use
|
||||||
|
target[_registedParams_].set(propertyKey, options);
|
||||||
|
};
|
||||||
|
}
|
122
lib/observables/nopeObservable.ts
Normal file
122
lib/observables/nopeObservable.ts
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import { BehaviorSubject, CompletionObserver, ErrorObserver, NextObserver, Subscription } from 'rxjs';
|
||||||
|
|
||||||
|
export interface nopeObserver {
|
||||||
|
active: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare type NopePartialObserver<T> = NextObserver<T> & nopeObserver | ErrorObserver<T> & nopeObserver | CompletionObserver<T> & nopeObserver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RsJX based Observable.
|
||||||
|
*
|
||||||
|
* Contains additional Functionalities like:
|
||||||
|
* - property with the current value
|
||||||
|
* - function to publish values. (wrapper for next)
|
||||||
|
* - enables performing a subscription with synced call or a immediate call.
|
||||||
|
*/
|
||||||
|
export class nopeObservable<T> extends BehaviorSubject<T> {
|
||||||
|
|
||||||
|
protected _currentValue: T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for the Current Value.
|
||||||
|
*/
|
||||||
|
public get currentValue(): T {
|
||||||
|
return this._currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setter for the Current value.
|
||||||
|
*/
|
||||||
|
public set currentValue(value: T) {
|
||||||
|
this.next(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a custom Observable.
|
||||||
|
* @param initialValue
|
||||||
|
*/
|
||||||
|
constructor(initialValue: T) {
|
||||||
|
super(initialValue);
|
||||||
|
|
||||||
|
const _this = this;
|
||||||
|
this.subscribe((data) => {
|
||||||
|
_this._currentValue = data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to Publish a Value to the stream.
|
||||||
|
* @param value The Value.
|
||||||
|
*/
|
||||||
|
publish(value: T) {
|
||||||
|
this.next(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribe(observer?: NopePartialObserver<T>, cbMode?: 'sync' | 'immediate'): Subscription;
|
||||||
|
/** @deprecated Use an observer instead of a complete callback */
|
||||||
|
subscribe(next: null | undefined, error: null | undefined, complete: () => void, cbMode?: 'sync' | 'immediate'): Subscription;
|
||||||
|
/** @deprecated Use an observer instead of an error callback */
|
||||||
|
subscribe(next: null | undefined, error: (error: any) => void, complete?: () => void, cbMode?: 'sync' | 'immediate'): Subscription;
|
||||||
|
/** @deprecated Use an observer instead of a complete callback */
|
||||||
|
subscribe(next: (value: T) => void, error: null | undefined, complete: () => void, cbMode?: 'sync' | 'immediate'): Subscription;
|
||||||
|
subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void, cbMode?: 'sync' | 'immediate'): Subscription;
|
||||||
|
|
||||||
|
// Underlying implementation
|
||||||
|
subscribe(observerOrNext?, errorOrcbMode?, complete?: () => void, cbMode?: 'sync' | 'immediate'): Subscription {
|
||||||
|
// The first argument could be an Observer or Callback (Depricated) and the callbacks for complete and error
|
||||||
|
let _cbMode = cbMode;
|
||||||
|
let _error = errorOrcbMode;
|
||||||
|
let _complete = complete;
|
||||||
|
let _observerOrNext = observerOrNext;
|
||||||
|
|
||||||
|
// If the first argument is an Observer => the second argument must be the cbMode
|
||||||
|
if (typeof observerOrNext === 'object') {
|
||||||
|
// Adapt the Callback
|
||||||
|
_cbMode = errorOrcbMode || 'sync';
|
||||||
|
// The error function must be undefined
|
||||||
|
_error = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test the cbMode
|
||||||
|
if (_cbMode === 'immediate') {
|
||||||
|
switch (typeof observerOrNext) {
|
||||||
|
case 'object':
|
||||||
|
if ((observerOrNext as NopePartialObserver<T>).next) {
|
||||||
|
const orgFunc = observerOrNext.next;
|
||||||
|
observerOrNext.next = (v: T) => setImmediate(() => {
|
||||||
|
if ((observerOrNext as NopePartialObserver<T>).active) {
|
||||||
|
orgFunc.call(observerOrNext, v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if ((observerOrNext as NopePartialObserver<T>).error) {
|
||||||
|
const orgFunc = observerOrNext.next;
|
||||||
|
observerOrNext.next = (v: T) => setImmediate(() => {
|
||||||
|
if ((observerOrNext as NopePartialObserver<T>).active) {
|
||||||
|
orgFunc.call(observerOrNext, v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} if ((observerOrNext as NopePartialObserver<T>).complete) {
|
||||||
|
const orgFunc = observerOrNext.next;
|
||||||
|
observerOrNext.next = (v: T) => setImmediate(() => {
|
||||||
|
if ((observerOrNext as NopePartialObserver<T>).active) {
|
||||||
|
orgFunc.call(observerOrNext, v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'function':
|
||||||
|
_observerOrNext = typeof observerOrNext === 'function' ? (_value: T) => setImmediate(observerOrNext, _value) : observerOrNext;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_error = typeof errorOrcbMode === 'function' ? (_errorValue: any) => setImmediate(errorOrcbMode, _errorValue) : undefined;
|
||||||
|
_complete = typeof complete === 'function' ? () => setImmediate(complete) : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.subscribe(_observerOrNext, _error, _complete);
|
||||||
|
}
|
||||||
|
}
|
0
lib/pubSub/nopePubSubSystem.ts
Normal file
0
lib/pubSub/nopePubSubSystem.ts
Normal file
8
package-lock.json
generated
8
package-lock.json
generated
@ -5781,6 +5781,14 @@
|
|||||||
"aproba": "^1.1.1"
|
"aproba": "^1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"rxjs": {
|
||||||
|
"version": "6.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz",
|
||||||
|
"integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^1.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-bootstrap": "^1.3.0",
|
"react-bootstrap": "^1.3.0",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
|
"rxjs": "^6.6.2",
|
||||||
"ts-morph": "^7.3.0"
|
"ts-morph": "^7.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
28
test/testDecorators.ts
Normal file
28
test/testDecorators.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { eportApi, exportMethod, exportProperty } from "../lib/decorators";
|
||||||
|
|
||||||
|
@eportApi({
|
||||||
|
url: 'icemaker'
|
||||||
|
})
|
||||||
|
export class Icemaker {
|
||||||
|
|
||||||
|
toppings = [];
|
||||||
|
sugar = 0;
|
||||||
|
|
||||||
|
@exportMethod()
|
||||||
|
addTopping(topping) {
|
||||||
|
this.toppings.push(topping);
|
||||||
|
}
|
||||||
|
|
||||||
|
@exportMethod()
|
||||||
|
addSugar() {
|
||||||
|
this.sugar++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@exportProperty()
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const instance = new Icemaker();
|
||||||
|
instance.addTopping('caramel')
|
||||||
|
console.log(instance)
|
21
test/testNopeObservable.ts
Normal file
21
test/testNopeObservable.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { filter } from 'rxjs/operators';
|
||||||
|
import { nopeObservable } from "../lib/observables/nopeObservable";
|
||||||
|
|
||||||
|
const observable = new nopeObservable(0);
|
||||||
|
const subscriptionSmaller = observable.pipe(
|
||||||
|
filter((v, idx) => v < 10)
|
||||||
|
).subscribe((v) => {
|
||||||
|
console.log('smaller 10:', v)
|
||||||
|
});
|
||||||
|
|
||||||
|
const subscriptionGreater = observable.pipe(
|
||||||
|
filter((v, idx) => v > 10)
|
||||||
|
).subscribe((v) => {
|
||||||
|
console.log('greater 10: ', v)
|
||||||
|
});
|
||||||
|
|
||||||
|
let i = 1;
|
||||||
|
while (i < 20) {
|
||||||
|
observable.currentValue = i++;
|
||||||
|
console.log('current', observable.currentValue);
|
||||||
|
}
|
@ -25,7 +25,8 @@
|
|||||||
"**/*.ts",
|
"**/*.ts",
|
||||||
"helpers",
|
"helpers",
|
||||||
"api",
|
"api",
|
||||||
"src"
|
"src",
|
||||||
|
"test"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
|
Loading…
Reference in New Issue
Block a user