@proteinjs/service 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/src/Service.d.ts +8 -2
- package/dist/src/Service.d.ts.map +1 -1
- package/dist/src/Service.js +28 -5
- package/dist/src/Service.js.map +1 -1
- package/package.json +2 -2
- package/src/Service.ts +38 -7
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [1.2.0](https://github.com/proteinjs/service/compare/@proteinjs/service@1.1.1...@proteinjs/service@1.2.0) (2025-02-06)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* fix typing for the debounce config ([62bb2d6](https://github.com/proteinjs/service/commit/62bb2d646e2c71f2bf5300364cd92bbd95911f21))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* method specific debouncers. allows one service to use multiple debouncers for each method in the service. ([00fa7b2](https://github.com/proteinjs/service/commit/00fa7b23c4960ad9a006d4791e9f5a12f9ab6c89))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
## [1.1.1](https://github.com/proteinjs/service/compare/@proteinjs/service@1.1.0...@proteinjs/service@1.1.1) (2024-09-10)
|
|
7
23
|
|
|
8
24
|
|
package/dist/src/Service.d.ts
CHANGED
|
@@ -10,6 +10,12 @@ type KeysWithoutService<T extends Service> = Diff<KeysWithoutIndexSignature<T>,
|
|
|
10
10
|
type RetryConfig<T extends Service> = {
|
|
11
11
|
[K in KeysWithoutService<T>]?: number;
|
|
12
12
|
};
|
|
13
|
+
interface DebounceConfig {
|
|
14
|
+
waitTime: number;
|
|
15
|
+
}
|
|
16
|
+
type MethodDebounceConfig<T extends Service> = {
|
|
17
|
+
[K in KeysWithoutService<T>]?: DebounceConfig;
|
|
18
|
+
};
|
|
13
19
|
export interface Service extends Loadable {
|
|
14
20
|
serviceMetadata?: {
|
|
15
21
|
auth?: {
|
|
@@ -36,9 +42,9 @@ export interface Service extends Loadable {
|
|
|
36
42
|
* Create a factory that creates an instance of the Service. The Service instance is a
|
|
37
43
|
* ServiceClient wrapped in the interface's api.
|
|
38
44
|
* @param serviceInterfaceQualifiedName the package-qualified name of the service interface (ie. service-package-name/MyService)
|
|
39
|
-
* @param debouncer
|
|
45
|
+
* @param debouncer pass in either a single debouncer instance or method-specific debounce configurations
|
|
40
46
|
* @returns a function that creates a Service
|
|
41
47
|
*/
|
|
42
|
-
export declare const serviceFactory: <T extends Service>(serviceInterfaceQualifiedName: string, debouncer?: Debouncer, retryConfig?: RetryConfig<T> | undefined) => () => T;
|
|
48
|
+
export declare const serviceFactory: <T extends Service>(serviceInterfaceQualifiedName: string, debouncer?: Debouncer | MethodDebounceConfig<T> | undefined, retryConfig?: RetryConfig<T> | undefined) => () => T;
|
|
43
49
|
export {};
|
|
44
50
|
//# sourceMappingURL=Service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Service.d.ts","sourceRoot":"","sources":["../../src/Service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAoB,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"Service.d.ts","sourceRoot":"","sources":["../../src/Service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAoB,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAgB,MAAM,iBAAiB,CAAC;AAE1D,KAAK,WAAW,CAAC,CAAC,IAAI;KACnB,CAAC,IAAI,MAAM,CAAC,IAAI,MAAM,SAAS,CAAC,GAAG,KAAK,GAAG,MAAM,SAAS,CAAC,GAAG,KAAK,GAAG,MAAM,SAAS,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC3G,CAAC;AACF,KAAK,yBAAyB,CAAC,CAAC,IAAI,MAAM,WAAW,CAAC,CAAC,CAAC,CAAC;AAGzD,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;AAG1C,KAAK,kBAAkB,CAAC,CAAC,SAAS,OAAO,IAAI,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,yBAAyB,CAAC,OAAO,CAAC,CAAC,CAAC;AAEpH,KAAK,WAAW,CAAC,CAAC,SAAS,OAAO,IAAI;KACnC,CAAC,IAAI,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM;CACtC,CAAC;AAEF,UAAU,cAAc;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,KAAK,oBAAoB,CAAC,CAAC,SAAS,OAAO,IAAI;KAC5C,CAAC,IAAI,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc;CAC9C,CAAC;AAEF,MAAM,WAAW,OAAQ,SAAQ,QAAQ;IACvC,eAAe,CAAC,EAAE;QAChB,IAAI,CAAC,EAAE;YACL,2HAA2H;YAC3H,MAAM,CAAC,EAAE,OAAO,CAAC;YACjB,kIAAkI;YAClI,QAAQ,CAAC,EAAE,OAAO,CAAC;YACnB,8HAA8H;YAC9H,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;YACjB;;;;;eAKG;YACH,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC;SAC1D,CAAC;QACF,uFAAuF;QACvF,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;CACzD;AAaD;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,qDACM,MAAM,mHAkCtC,CAAC"}
|
package/dist/src/Service.js
CHANGED
|
@@ -3,11 +3,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.serviceFactory = void 0;
|
|
4
4
|
var reflection_1 = require("@proteinjs/reflection");
|
|
5
5
|
var ServiceClient_1 = require("./ServiceClient");
|
|
6
|
+
var util_1 = require("@proteinjs/util");
|
|
7
|
+
var debouncerMap = {};
|
|
8
|
+
/** Retrieve an existing debouncer from the map or make a new one.
|
|
9
|
+
* This allows the debouncer instance per method to remain the same across multiple service calls.
|
|
10
|
+
*/
|
|
11
|
+
function getOrCreateDebouncer(methodName, waitTime) {
|
|
12
|
+
if (!debouncerMap[methodName]) {
|
|
13
|
+
debouncerMap[methodName] = new util_1.Debouncer(waitTime);
|
|
14
|
+
}
|
|
15
|
+
return debouncerMap[methodName];
|
|
16
|
+
}
|
|
6
17
|
/**
|
|
7
18
|
* Create a factory that creates an instance of the Service. The Service instance is a
|
|
8
19
|
* ServiceClient wrapped in the interface's api.
|
|
9
20
|
* @param serviceInterfaceQualifiedName the package-qualified name of the service interface (ie. service-package-name/MyService)
|
|
10
|
-
* @param debouncer
|
|
21
|
+
* @param debouncer pass in either a single debouncer instance or method-specific debounce configurations
|
|
11
22
|
* @returns a function that creates a Service
|
|
12
23
|
*/
|
|
13
24
|
var serviceFactory = function (serviceInterfaceQualifiedName, debouncer, retryConfig) {
|
|
@@ -17,13 +28,25 @@ var serviceFactory = function (serviceInterfaceQualifiedName, debouncer, retryCo
|
|
|
17
28
|
for (var _i = 0, _a = serviceInterface.methods; _i < _a.length; _i++) {
|
|
18
29
|
var method = _a[_i];
|
|
19
30
|
var servicePath = "/service/".concat(serviceInterface.qualifiedName, "/").concat(method.name);
|
|
31
|
+
var methodName = method.name;
|
|
20
32
|
var retryCount = 0;
|
|
21
|
-
if (retryConfig &&
|
|
22
|
-
var methodName = method.name;
|
|
33
|
+
if (retryConfig && methodName in retryConfig) {
|
|
23
34
|
retryCount = retryConfig[methodName];
|
|
24
35
|
}
|
|
25
|
-
var
|
|
26
|
-
|
|
36
|
+
var methodDebouncer = void 0;
|
|
37
|
+
if (debouncer) {
|
|
38
|
+
if ((0, util_1.isInstanceOf)(debouncer, util_1.Debouncer)) {
|
|
39
|
+
methodDebouncer = debouncer;
|
|
40
|
+
}
|
|
41
|
+
else if (methodName in debouncer) {
|
|
42
|
+
var methodConfig = debouncer[methodName];
|
|
43
|
+
if (methodConfig) {
|
|
44
|
+
methodDebouncer = getOrCreateDebouncer(methodName, methodConfig.waitTime);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
var serviceClient = new ServiceClient_1.ServiceClient(servicePath, method, methodDebouncer, retryCount);
|
|
49
|
+
service[methodName] = serviceClient.send.bind(serviceClient);
|
|
27
50
|
}
|
|
28
51
|
return service;
|
|
29
52
|
};
|
package/dist/src/Service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Service.js","sourceRoot":"","sources":["../../src/Service.ts"],"names":[],"mappings":";;;AACA,oDAAmE;AACnE,iDAAgD;
|
|
1
|
+
{"version":3,"file":"Service.js","sourceRoot":"","sources":["../../src/Service.ts"],"names":[],"mappings":";;;AACA,oDAAmE;AACnE,iDAAgD;AAChD,wCAA0D;AAgD1D,IAAM,YAAY,GAAiC,EAAE,CAAC;AACtD;;GAEG;AACH,SAAS,oBAAoB,CAAC,UAAkB,EAAE,QAAgB;IAChE,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE;QAC7B,YAAY,CAAC,UAAU,CAAC,GAAG,IAAI,gBAAS,CAAC,QAAQ,CAAC,CAAC;KACpD;IACD,OAAO,YAAY,CAAC,UAAU,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;GAMG;AACI,IAAM,cAAc,GAAG,UAC5B,6BAAqC,EACrC,SAA+C,EAC/C,WAA4B;IAE5B,OAAO;QACL,IAAM,OAAO,GAAQ,EAAE,CAAC;QACxB,IAAM,gBAAgB,GAAG,6BAAgB,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;QACzF,KAAqB,UAAwB,EAAxB,KAAA,gBAAgB,CAAC,OAAO,EAAxB,cAAwB,EAAxB,IAAwB,EAAE;YAA1C,IAAM,MAAM,SAAA;YACf,IAAM,WAAW,GAAG,mBAAY,gBAAgB,CAAC,aAAa,cAAI,MAAM,CAAC,IAAI,CAAE,CAAC;YAChF,IAAM,UAAU,GAAG,MAAM,CAAC,IAA6B,CAAC;YAExD,IAAI,UAAU,GAAG,CAAC,CAAC;YACnB,IAAI,WAAW,IAAI,UAAU,IAAI,WAAW,EAAE;gBAC5C,UAAU,GAAG,WAAW,CAAC,UAAU,CAAE,CAAC;aACvC;YAED,IAAI,eAAe,SAAuB,CAAC;YAC3C,IAAI,SAAS,EAAE;gBACb,IAAI,IAAA,mBAAY,EAAC,SAAS,EAAE,gBAAS,CAAC,EAAE;oBACtC,eAAe,GAAG,SAAsB,CAAC;iBAC1C;qBAAM,IAAI,UAAU,IAAI,SAAS,EAAE;oBAClC,IAAM,YAAY,GAAI,SAAqC,CAAC,UAAU,CAAC,CAAC;oBACxE,IAAI,YAAY,EAAE;wBAChB,eAAe,GAAG,oBAAoB,CAAC,UAAoB,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;qBACrF;iBACF;aACF;YAED,IAAM,aAAa,GAAG,IAAI,6BAAa,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;YAC1F,OAAO,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;SAC9D;QAED,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;AACJ,CAAC,CAAC;AAnCW,QAAA,cAAc,kBAmCzB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteinjs/service",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Service api",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
},
|
|
44
44
|
"main": "./dist/generated/index.js",
|
|
45
45
|
"types": "./dist/generated/index.d.ts",
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "3de027b69d80594ca40d10c2069b6ec1ef119f89"
|
|
47
47
|
}
|
package/src/Service.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SerializableFunction, NotFunction } from '@proteinjs/serializer';
|
|
2
2
|
import { Loadable, SourceRepository } from '@proteinjs/reflection';
|
|
3
3
|
import { ServiceClient } from './ServiceClient';
|
|
4
|
-
import { Debouncer } from '@proteinjs/util';
|
|
4
|
+
import { Debouncer, isInstanceOf } from '@proteinjs/util';
|
|
5
5
|
|
|
6
6
|
type RemoveIndex<T> = {
|
|
7
7
|
[K in keyof T as string extends K ? never : number extends K ? never : symbol extends K ? never : K]: T[K];
|
|
@@ -18,6 +18,14 @@ type RetryConfig<T extends Service> = {
|
|
|
18
18
|
[K in KeysWithoutService<T>]?: number;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
interface DebounceConfig {
|
|
22
|
+
waitTime: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type MethodDebounceConfig<T extends Service> = {
|
|
26
|
+
[K in KeysWithoutService<T>]?: DebounceConfig;
|
|
27
|
+
};
|
|
28
|
+
|
|
21
29
|
export interface Service extends Loadable {
|
|
22
30
|
serviceMetadata?: {
|
|
23
31
|
auth?: {
|
|
@@ -41,16 +49,27 @@ export interface Service extends Loadable {
|
|
|
41
49
|
[prop: string]: SerializableFunction | NotFunction<any>;
|
|
42
50
|
}
|
|
43
51
|
|
|
52
|
+
const debouncerMap: { [key: string]: Debouncer } = {};
|
|
53
|
+
/** Retrieve an existing debouncer from the map or make a new one.
|
|
54
|
+
* This allows the debouncer instance per method to remain the same across multiple service calls.
|
|
55
|
+
*/
|
|
56
|
+
function getOrCreateDebouncer(methodName: string, waitTime: number): Debouncer {
|
|
57
|
+
if (!debouncerMap[methodName]) {
|
|
58
|
+
debouncerMap[methodName] = new Debouncer(waitTime);
|
|
59
|
+
}
|
|
60
|
+
return debouncerMap[methodName];
|
|
61
|
+
}
|
|
62
|
+
|
|
44
63
|
/**
|
|
45
64
|
* Create a factory that creates an instance of the Service. The Service instance is a
|
|
46
65
|
* ServiceClient wrapped in the interface's api.
|
|
47
66
|
* @param serviceInterfaceQualifiedName the package-qualified name of the service interface (ie. service-package-name/MyService)
|
|
48
|
-
* @param debouncer
|
|
67
|
+
* @param debouncer pass in either a single debouncer instance or method-specific debounce configurations
|
|
49
68
|
* @returns a function that creates a Service
|
|
50
69
|
*/
|
|
51
70
|
export const serviceFactory = <T extends Service>(
|
|
52
71
|
serviceInterfaceQualifiedName: string,
|
|
53
|
-
debouncer?: Debouncer,
|
|
72
|
+
debouncer?: MethodDebounceConfig<T> | Debouncer,
|
|
54
73
|
retryConfig?: RetryConfig<T>
|
|
55
74
|
): (() => T) => {
|
|
56
75
|
return () => {
|
|
@@ -58,15 +77,27 @@ export const serviceFactory = <T extends Service>(
|
|
|
58
77
|
const serviceInterface = SourceRepository.get().interface(serviceInterfaceQualifiedName);
|
|
59
78
|
for (const method of serviceInterface.methods) {
|
|
60
79
|
const servicePath = `/service/${serviceInterface.qualifiedName}/${method.name}`;
|
|
80
|
+
const methodName = method.name as KeysWithoutService<T>;
|
|
61
81
|
|
|
62
82
|
let retryCount = 0;
|
|
63
|
-
if (retryConfig &&
|
|
64
|
-
const methodName = method.name as KeysWithoutService<T>;
|
|
83
|
+
if (retryConfig && methodName in retryConfig) {
|
|
65
84
|
retryCount = retryConfig[methodName]!;
|
|
66
85
|
}
|
|
67
86
|
|
|
68
|
-
|
|
69
|
-
|
|
87
|
+
let methodDebouncer: Debouncer | undefined;
|
|
88
|
+
if (debouncer) {
|
|
89
|
+
if (isInstanceOf(debouncer, Debouncer)) {
|
|
90
|
+
methodDebouncer = debouncer as Debouncer;
|
|
91
|
+
} else if (methodName in debouncer) {
|
|
92
|
+
const methodConfig = (debouncer as MethodDebounceConfig<T>)[methodName];
|
|
93
|
+
if (methodConfig) {
|
|
94
|
+
methodDebouncer = getOrCreateDebouncer(methodName as string, methodConfig.waitTime);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const serviceClient = new ServiceClient(servicePath, method, methodDebouncer, retryCount);
|
|
100
|
+
service[methodName] = serviceClient.send.bind(serviceClient);
|
|
70
101
|
}
|
|
71
102
|
|
|
72
103
|
return service;
|