From da8ecc0669865dff8dd19a889246965ddf7b5282 Mon Sep 17 00:00:00 2001 From: Akash Kava <39438041+ackava@users.noreply.github.com> Date: Thu, 5 Dec 2024 19:00:04 +0530 Subject: [PATCH] entity changed --- package-lock.json | 32 +++--- package.json | 2 +- src/services/BaseEntityService.ts | 173 +++++++++++++++++++++--------- src/services/HttpSession.ts | 18 ++-- tsconfig.json | 3 +- 5 files changed, 154 insertions(+), 74 deletions(-) diff --git a/package-lock.json b/package-lock.json index da13748..82c257d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "2.4.64", "license": "ISC", "dependencies": { - "@web-atoms/core": "^v2.2.3", + "@web-atoms/core": "^v2.4.29", "@web-atoms/date-time": "^1.1.0", "@web-atoms/module-loader": "^2.1.2", "@web-atoms/web-controls": "^2.2.1", @@ -29,12 +29,13 @@ } }, "node_modules/@web-atoms/core": { - "version": "2.2.19", - "resolved": "https://registry.npmjs.org/@web-atoms/core/-/core-2.2.19.tgz", - "integrity": "sha512-uSkADlihAjCN/vf3sMpMw+2usKIrvTVNTDWEudY9M1UPblYs6qubBopK4J4vg5sICZdQk/FB6qIKNI8NAh/aOg==", + "version": "2.4.29", + "resolved": "https://registry.npmjs.org/@web-atoms/core/-/core-2.4.29.tgz", + "integrity": "sha512-0yyus8JLw6mxt3lFbZMclr68rmKl8c7enRv9dzAPYn+QVVSEq2LpR1eDdx78RUOw38EPfFOSbYhPOGBA+Yy2EA==", + "license": "MIT", "dependencies": { "@web-atoms/date-time": "^1.1.1", - "reflect-metadata": "^0.1.13" + "reflect-metadata": "^0.1.14" } }, "node_modules/@web-atoms/date-time": { @@ -536,9 +537,10 @@ } }, "node_modules/reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", + "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==", + "license": "Apache-2.0" }, "node_modules/safer-buffer": { "version": "2.1.2", @@ -731,12 +733,12 @@ "dev": true }, "@web-atoms/core": { - "version": "2.2.19", - "resolved": "https://registry.npmjs.org/@web-atoms/core/-/core-2.2.19.tgz", - "integrity": "sha512-uSkADlihAjCN/vf3sMpMw+2usKIrvTVNTDWEudY9M1UPblYs6qubBopK4J4vg5sICZdQk/FB6qIKNI8NAh/aOg==", + "version": "2.4.29", + "resolved": "https://registry.npmjs.org/@web-atoms/core/-/core-2.4.29.tgz", + "integrity": "sha512-0yyus8JLw6mxt3lFbZMclr68rmKl8c7enRv9dzAPYn+QVVSEq2LpR1eDdx78RUOw38EPfFOSbYhPOGBA+Yy2EA==", "requires": { "@web-atoms/date-time": "^1.1.1", - "reflect-metadata": "^0.1.13" + "reflect-metadata": "^0.1.14" } }, "@web-atoms/date-time": { @@ -1131,9 +1133,9 @@ "dev": true }, "reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", + "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==" }, "safer-buffer": { "version": "2.1.2", diff --git a/package.json b/package.json index 0b16b4f..88e9089 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "author": "", "license": "ISC", "dependencies": { - "@web-atoms/core": "^v2.2.3", + "@web-atoms/core": "^v2.4.29", "@web-atoms/date-time": "^1.1.0", "@web-atoms/module-loader": "^2.1.2", "@web-atoms/web-controls": "^2.2.1", diff --git a/src/services/BaseEntityService.ts b/src/services/BaseEntityService.ts index ee728c3..e57fea0 100644 --- a/src/services/BaseEntityService.ts +++ b/src/services/BaseEntityService.ts @@ -1,14 +1,17 @@ -import { CancelToken, IDisposable } from "@web-atoms/core/dist/core/types"; +import { CancelToken } from "@web-atoms/core/dist/core/types"; import DateTime from "@web-atoms/date-time/dist/DateTime"; import { Cloner } from "../models/Cloner"; -import IClrEntity, { IClrEntityLike, IClrExtendedEntity } from "../models/IClrEntity"; +import IClrEntity, { IClrEntityLike } from "../models/IClrEntity"; import IEntityModel, { EntityContext } from "../models/IEntityModel"; -import HttpSession, { IHttpRequest } from "./HttpSession"; import mergeProperties from "./mergeProperties"; import Query, { IDateRange, IEntityWithDateRange, stepTypes } from "./Query"; import resolve from "./resolve"; import { QueryProcessor } from "./QueryProcessor"; +import TaskManager from "../models/TaskManager"; +import FetchBuilder from "@web-atoms/core/dist/services/FetchBuilder"; +(Symbol as any).asyncDispose ??= Symbol("asyncDispose"); +(Symbol as any).dispose ??= Symbol("dispose"); export interface IGeometry { latitude: number; longitude: number; @@ -373,7 +376,7 @@ export class Model implements IModel { } } -export default abstract class BaseEntityService extends HttpSession { +export default abstract class BaseEntityService extends TaskManager { public url: string = "/api/entity/"; @@ -391,7 +394,9 @@ export default abstract class BaseEntityService extends HttpSession { if (this.entityModel) { return this.entityModel; } - const c = await this.getJson({ url: `${this.url}model` }); + using busy = this.createBusyIndicator(false); + const c = await FetchBuilder.get(`${this.url}model`) + .asJson(); this.entityModel = new EntityContext(c); return this.entityModel; } @@ -403,7 +408,7 @@ export default abstract class BaseEntityService extends HttpSession { ]); } - public query(m: IModel, + query(m: IModel, queryFunction?: keyof TR, ... args: any[]): Query { return new Query({ @@ -415,17 +420,23 @@ export default abstract class BaseEntityService extends HttpSession { }); } - public delete(body: T): Promise { + async delete(body: T): Promise { + using busy = this.createBusyIndicator(false); const url = this.url; - return this.deleteJson({url, body}); + // return this.deleteJson({url, body}); + return await FetchBuilder.delete(url).jsonBody(body).asJson(); } - public insert(body: IClrEntity): Promise { + async insert(body: IClrEntity): Promise { + using busy = this.createBusyIndicator(false); const url = this.url; - return this.putJson({url, body}); + // return this.putJson({url, body}); + const result = await FetchBuilder.put(url).jsonBody(body).asJson(); + return this.resultConverter(result); } - public invoke(m: IModel, method: keyof TA, argEntity: IClrEntity, ... args: any[]) { + async invoke(m: IModel, method: keyof TA, argEntity: IClrEntity, ... args: any[]) { + using busy = this.createBusyIndicator(false); // will send keys only... const entity = { $type: m.name @@ -433,25 +444,29 @@ export default abstract class BaseEntityService extends HttpSession { for(const key of m.schema.keys) { entity[key.name] = argEntity[key.name]; } - return this.postJson({ - url: `${this.url}invoke/${entity.$type}/${method as any}`, - method: "POST", - body: { - entity, - args - } - }) as Promise; + + const result = await FetchBuilder.post(`${this.url}invoke/${entity.$type}/${method as any}`) + .jsonBody({ entity, args }) + .asJson(); + + return this.resultConverter(result); + + // return this.postJson({ + // url: `${this.url}invoke/${entity.$type}/${method as any}`, + // method: "POST", + // body: { + // entity, + // args + // } + // }) as Promise; } - - public run(m: IModel, method: keyof TA, argEntity: IClrEntity, { + buildRunUrl(m: IModel, method: keyof TA, argEntity: IClrEntity, { args = void 0 as any[], cacheSeconds = 0, - cacheVersion = void 0 as any, - cancelToken = void 0 as CancelToken + cacheVersion = void 0 as any } = { }) { - // will send keys only... const { $type, $key } = argEntity; if (!$key) { throw new Error(`Run requires encrypted $key`); @@ -467,18 +482,61 @@ export default abstract class BaseEntityService extends HttpSession { if (cacheVersion) { usp.append("cv", cacheVersion); } - return this.getJson({ - url: `${this.url}run/${$type}/${method as any}?${usp.toString()}`, - cancelToken, - }) as Promise; + return `${this.url}run/${$type}/${method as any}?${usp.toString()}`; + } + + async runAsText(m: IModel, method: keyof TA, argEntity: IClrEntity, { + args = void 0 as any[], + cacheSeconds = 0, + cacheVersion = void 0 as any, + cancelToken = void 0 as CancelToken + } = { + }) { + using busy = this.createBusyIndicator(false); + const url = this.buildRunUrl(m, method, argEntity, { args, cacheSeconds, cacheVersion}); + return await FetchBuilder.get(url) + .cancelToken(cancelToken) + .asText(); } + async runAsBlob(m: IModel, method: keyof TA, argEntity: IClrEntity, { + args = void 0 as any[], + cacheSeconds = 0, + cacheVersion = void 0 as any, + cancelToken = void 0 as CancelToken + } = { + }) { + using busy = this.createBusyIndicator(false); + const url = this.buildRunUrl(m, method, argEntity, { args, cacheSeconds, cacheVersion}); + return await FetchBuilder.get(url) + .cancelToken(cancelToken) + .asBlob(); + } + + async run(m: IModel, method: keyof TA, argEntity: IClrEntity, { + args = void 0 as any[], + cacheSeconds = 0, + cacheVersion = void 0 as any, + cancelToken = void 0 as CancelToken + } = { + }) { + using busy = this.createBusyIndicator(false); + const url = this.buildRunUrl(m, method, argEntity, { args, cacheSeconds, cacheVersion}); + let result = await FetchBuilder.get(url) + .cancelToken(cancelToken) + .asJson(); + result = this.resultConverter(result); + return result as any; + } + + public save(body: T, cloner?: (c: Cloner) => Cloner, trace?: boolean): Promise; public save(body: T[], cloner?: (c: Cloner) => Cloner, trace?: boolean): Promise; public async save(body: any, cloner?: (c: Cloner) => Cloner, trace?: boolean): Promise { if (Array.isArray(body) && body.length === 0) { return body; } + using busy = this.createBusyIndicator(false); let url = this.url; if (body instanceof Cloner) { body = body.copy; @@ -499,9 +557,13 @@ export default abstract class BaseEntityService extends HttpSession { body = c.copy; } } - const result = await this.postJson({ - url, body - }); + // const result = await this.postJson({ + // url, body + // }); + let result = await FetchBuilder.post(url) + .jsonBody(body) + .asJson(); + result = this.resultConverter(result); mergeProperties(result, body); return body; } @@ -522,6 +584,7 @@ export default abstract class BaseEntityService extends HttpSession { update: IModifications, throwWhenNotFound: boolean = false): Promise { const model = await this.model(); + using busy = this.createBusyIndicator(false); const keys = []; for (const iterator of entities) { const entityType = model.for(iterator.$type); @@ -533,13 +596,18 @@ export default abstract class BaseEntityService extends HttpSession { } const body = { keys, update, throwWhenNotFound }; const url = `${this.url}bulk`; - await this.putJson({url, body}); + let results = await FetchBuilder.post(url) + .jsonBody(body) + .asJson(); + results = this.resultConverter(results); + return results; } public async bulkDelete( entities: T[], throwWhenNotFound: boolean = false): Promise { const model = await this.model(); + using busy = this.createBusyIndicator(false); const keys = []; for (const iterator of entities) { const entityType = model.for(iterator.$type); @@ -551,26 +619,31 @@ export default abstract class BaseEntityService extends HttpSession { } const url = `${this.url}bulk`; const body = { keys, throwWhenNotFound }; - await this.deleteJson({ - url, - body - }); - } - - protected async fetchJson(options: IHttpRequest): Promise { - if (!this.createBusyIndicator || options?.hideActivityIndicator) { - return await super.fetchJson(options); - } - const disposable = this.createBusyIndicator(options); - try { - return await super.fetchJson(options); - } finally { - disposable?.dispose(); - } + // await this.deleteJson({ + // url, + // body + // }); + let results = await FetchBuilder.delete(url) + .jsonBody(body) + .asJson(); + results = this.resultConverter(results); + return results; } - protected createBusyIndicator(options: IHttpRequest) { - return { dispose() {}}; + // protected async fetchResponse(options: IHttpRequest): Promise { + // if (!this.createBusyIndicator || options?.hideActivityIndicator) { + // return await super.fetchResponse(options); + // } + // const disposable = this.createBusyIndicator(options); + // try { + // return await super.fetchResponse(options); + // } finally { + // disposable?.dispose(); + // } + // } + + protected createBusyIndicator(hideActivityIndicator = false) { + return { [Symbol.dispose]() {}}; } } diff --git a/src/services/HttpSession.ts b/src/services/HttpSession.ts index fd656f8..621ee5b 100644 --- a/src/services/HttpSession.ts +++ b/src/services/HttpSession.ts @@ -43,6 +43,7 @@ export interface IHttpRequest extends RequestInit { body?: any; cancelToken?: CancelToken; hideActivityIndicator?: boolean; + asJson?: boolean; } export default class HttpSession extends TaskManager { @@ -55,7 +56,7 @@ export default class HttpSession extends TaskManager { protected resultConverter = (e) => e; - protected fetchJson(options: IHttpRequest): Promise { + protected fetchResponse(options: IHttpRequest): Promise { return this.queueRun(() => this.uncheckedFetchJson(options)); } @@ -93,7 +94,10 @@ export default class HttpSession extends TaskManager { // throw new Error(`Unable to convert to json\r\n${contentType}\r\n${await response.text()}`); throw new Error(`Unable to convert to json\r\n${contentType}}`); } - return this.resultConverter(await response.json()); + const asJson = options.asJson ?? true; + if(asJson) { + return this.resultConverter(await response.json()); + } } protected interceptFetch(input: RequestInfo | URL, init?: RequestInit): Promise { @@ -102,7 +106,7 @@ export default class HttpSession extends TaskManager { protected getJson(options: IHttpRequest) { options.method = "GET"; - return this.fetchJson(options); + return this.fetchResponse(options); } protected postFormModel(options: IHttpRequest) { @@ -112,7 +116,7 @@ export default class HttpSession extends TaskManager { } options.headers ??= {}; options.headers["content-type"] = "application/x-www-form-urlencoded"; - return this.fetchJson(options); + return this.fetchResponse(options); } protected postJson(options: IHttpRequest) { @@ -122,7 +126,7 @@ export default class HttpSession extends TaskManager { } options.headers ??= {}; options.headers["content-type"] = "application/json"; - return this.fetchJson(options); + return this.fetchResponse(options); } protected deleteJson(options: IHttpRequest) { @@ -132,7 +136,7 @@ export default class HttpSession extends TaskManager { } options.headers ??= {}; options.headers["content-type"] = "application/json"; - return this.fetchJson(options); + return this.fetchResponse(options); } protected putJson(options: IHttpRequest) { @@ -142,7 +146,7 @@ export default class HttpSession extends TaskManager { } options.headers ??= {}; options.headers["content-type"] = "application/json"; - return this.fetchJson(options); + return this.fetchResponse(options); } } diff --git a/tsconfig.json b/tsconfig.json index 0cf2f8b..12b17d6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,7 +14,8 @@ "jsxFactory": "XNode.create", "lib": [ "es6", - "dom" + "dom", + "ESNext.Disposable" ] }, "include": [