generated from gxc-solutions/gxc-template-repo
This commit is contained in:
parent
41a325f5e1
commit
0f8546bc69
10 changed files with 149 additions and 1 deletions
15
lib/src/decorators/ignore.ts
Normal file
15
lib/src/decorators/ignore.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { ModelConstructor } from "../interfaces";
|
||||
|
||||
export const IGNORABLE_FIELDS = new WeakMap<ModelConstructor, Set<string>>();
|
||||
|
||||
export function ignore(value: unknown, context: ClassFieldDecoratorContext) {
|
||||
context.addInitializer(function () {
|
||||
const ctor = this.constructor as ModelConstructor;
|
||||
let set = IGNORABLE_FIELDS.get(ctor);
|
||||
if (!set) {
|
||||
set = new Set<string>();
|
||||
IGNORABLE_FIELDS.set(ctor, set);
|
||||
}
|
||||
set.add(context.name as string);
|
||||
});
|
||||
}
|
||||
15
lib/src/decorators/immutable.ts
Normal file
15
lib/src/decorators/immutable.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { ModelConstructor } from "../interfaces";
|
||||
|
||||
export const IMMUTABLE_FIELDS = new WeakMap<ModelConstructor, Set<string>>();
|
||||
|
||||
export function immutable(value: unknown, context: ClassFieldDecoratorContext) {
|
||||
context.addInitializer(function () {
|
||||
const ctor = this.constructor as ModelConstructor;
|
||||
let set = IMMUTABLE_FIELDS.get(ctor);
|
||||
if (!set) {
|
||||
set = new Set<string>();
|
||||
IMMUTABLE_FIELDS.set(ctor, set);
|
||||
}
|
||||
set.add(context.name as string);
|
||||
});
|
||||
}
|
||||
3
lib/src/decorators/index.ts
Normal file
3
lib/src/decorators/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from "./ignore";
|
||||
export * from "./immutable";
|
||||
export * from "./utils";
|
||||
11
lib/src/decorators/property.ts
Normal file
11
lib/src/decorators/property.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
export class PropertyMetadata {
|
||||
get(object: any, property: string) {
|
||||
console.warn(object, property);
|
||||
}
|
||||
}
|
||||
|
||||
export function property() {
|
||||
return function (target: object, property: string) {
|
||||
console.warn(target, property);
|
||||
};
|
||||
}
|
||||
17
lib/src/decorators/utils.ts
Normal file
17
lib/src/decorators/utils.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { IMMUTABLE_FIELDS } from "./immutable";
|
||||
import { IGNORABLE_FIELDS } from "./ignore";
|
||||
|
||||
export const getImmutableKeys = (obj: any): string[] => {
|
||||
const ctor = obj.constructor;
|
||||
return IMMUTABLE_FIELDS.has(ctor) ? Array.from(IMMUTABLE_FIELDS.get(ctor) as Set<string>) : [];
|
||||
};
|
||||
|
||||
export const isImmutableKey = (object: any, key: string) => getImmutableKeys(object).includes(key);
|
||||
|
||||
export const getIgnorableKeys = (obj: any): string[] => {
|
||||
const ctor = obj.constructor;
|
||||
|
||||
return IGNORABLE_FIELDS.has(ctor) ? Array.from(IGNORABLE_FIELDS.get(ctor) as Set<string>) : [];
|
||||
};
|
||||
|
||||
export const isIgnorableKey = (object: any, key: string) => getIgnorableKeys(object).includes(key);
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
export * from "./models";
|
||||
export * from "./decorators";
|
||||
export * from "./interfaces";
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
export type ModelConstructor = new (...args: any[]) => IModel;
|
||||
|
||||
export type TypeOfModel = "collection";
|
||||
|
||||
export interface IModel {
|
||||
readonly id: string;
|
||||
readonly type: TypeOfModel;
|
||||
}
|
||||
75
lib/src/models/collection.ts
Normal file
75
lib/src/models/collection.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { ignore } from "../decorators/ignore";
|
||||
|
||||
export class Collection<T> {
|
||||
@ignore readonly id = crypto.randomUUID();
|
||||
private _store: Record<number, T> = {};
|
||||
|
||||
get length() {
|
||||
return Object.keys(this._store).length;
|
||||
}
|
||||
|
||||
constructor(args: T[] = []) {
|
||||
args.forEach((item, index) => (this._store[index] = item));
|
||||
}
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
const array = this.toArray();
|
||||
for (const item of array) {
|
||||
yield item;
|
||||
}
|
||||
}
|
||||
|
||||
push(...args: T[]) {
|
||||
const diff: Record<number, T> = {};
|
||||
args.forEach((item) => {
|
||||
const index = this.length;
|
||||
this._store[index] = item;
|
||||
diff[index] = item;
|
||||
});
|
||||
return { ...diff, length: this.length };
|
||||
}
|
||||
|
||||
remove(item: T) {
|
||||
const backup: Record<number, T> = { ...this._store };
|
||||
|
||||
Object.keys(this._store).forEach((key) => {
|
||||
const index = Number(key);
|
||||
const itemOfIndex = this.get(index);
|
||||
if (item !== itemOfIndex) return;
|
||||
|
||||
Reflect.deleteProperty(this._store, Number(key));
|
||||
});
|
||||
|
||||
const diff: Record<number, T> = {};
|
||||
const values = Object.values(this._store);
|
||||
const newStore: Record<number, T> = {};
|
||||
|
||||
for (let index = 0; index < values.length; index++) {
|
||||
newStore[index] = values[index];
|
||||
|
||||
if (backup[index] !== newStore[index]) {
|
||||
diff[index] = newStore[index];
|
||||
}
|
||||
}
|
||||
this._store = newStore;
|
||||
|
||||
return { ...diff, length: this.length };
|
||||
}
|
||||
|
||||
indexOf(item: T) {
|
||||
return this.toArray().indexOf(item);
|
||||
}
|
||||
|
||||
get(index: number): T {
|
||||
return this._store[index];
|
||||
}
|
||||
|
||||
set(index: number, value: T) {
|
||||
this._store[index] = value;
|
||||
return { [index]: value, length: this.length };
|
||||
}
|
||||
|
||||
toArray(): T[] {
|
||||
return Object.keys(this._store).map((index) => this._store[index]);
|
||||
}
|
||||
}
|
||||
1
lib/src/models/index.ts
Normal file
1
lib/src/models/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "./collection";
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@gxc-solutions/lib",
|
||||
"name": "@gxc-solutions/model-base",
|
||||
"version": "0.0.1",
|
||||
"main": "index.js",
|
||||
"author": "GXC Solutions",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue