@xylabs/creatable 5.0.14 → 5.0.16
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/dist/neutral/AbstractCreatable.d.ts +11 -5
- package/dist/neutral/AbstractCreatable.d.ts.map +1 -1
- package/dist/neutral/Creatable.d.ts +2 -2
- package/dist/neutral/Creatable.d.ts.map +1 -1
- package/dist/neutral/index.mjs +62 -17
- package/dist/neutral/index.mjs.map +1 -1
- package/dist/neutral/model/CreatableParams.d.ts +5 -3
- package/dist/neutral/model/CreatableParams.d.ts.map +1 -1
- package/dist/neutral/model/CreatableStatusReporter.d.ts +6 -4
- package/dist/neutral/model/CreatableStatusReporter.d.ts.map +1 -1
- package/dist/neutral/spec/TestCreatable.spec.d.ts +2 -2
- package/dist/neutral/spec/TestCreatable.spec.d.ts.map +1 -1
- package/package.json +8 -7
- package/src/AbstractCreatable.ts +79 -24
- package/src/Creatable.ts +2 -1
- package/src/model/CreatableParams.ts +5 -3
- package/src/model/CreatableStatusReporter.ts +7 -4
- package/src/spec/TestCreatable.spec.ts +4 -2
- package/src/spec/TestCreatable2.spec.ts +2 -2
|
@@ -3,22 +3,28 @@ import { BaseEmitter } from '@xylabs/events';
|
|
|
3
3
|
import { type Logger } from '@xylabs/logger';
|
|
4
4
|
import type { Promisable } from '@xylabs/promise';
|
|
5
5
|
import { type Creatable, CreatableFactory } from './Creatable.ts';
|
|
6
|
-
import type { CreatableInstance, CreatableName, CreatableParams, Labels } from './model/index.ts';
|
|
7
|
-
export declare class AbstractCreatable<TParams extends CreatableParams = CreatableParams, TEventData extends EventData = EventData> extends BaseEmitter<Partial<TParams>, TEventData> {
|
|
6
|
+
import type { CreatableInstance, CreatableName, CreatableParams, CreatableStatus, Labels, RequiredCreatableParams } from './model/index.ts';
|
|
7
|
+
export declare class AbstractCreatable<TParams extends CreatableParams = CreatableParams, TEventData extends EventData = EventData> extends BaseEmitter<Partial<TParams & RequiredCreatableParams>, TEventData> {
|
|
8
8
|
defaultLogger?: Logger;
|
|
9
|
+
private _status;
|
|
10
|
+
private _statusMutex;
|
|
9
11
|
private _validatedParams?;
|
|
10
|
-
constructor(key: unknown, params: Partial<TParams>);
|
|
12
|
+
constructor(key: unknown, params: Partial<TParams & RequiredCreatableParams>);
|
|
11
13
|
get name(): CreatableName;
|
|
12
|
-
get params(): TParams;
|
|
14
|
+
get params(): TParams & RequiredCreatableParams;
|
|
15
|
+
get startable(): boolean;
|
|
16
|
+
get status(): CreatableStatus | null;
|
|
13
17
|
get statusReporter(): import("./model/CreatableStatusReporter.ts").CreatableStatusReporter<void> | undefined;
|
|
14
18
|
static create<T extends CreatableInstance>(this: Creatable<T>, inParams?: Partial<T['params']>): Promise<T>;
|
|
15
19
|
static createHandler<T extends CreatableInstance>(this: Creatable<T>, instance: T): Promisable<T>;
|
|
16
20
|
static paramsHandler<T extends CreatableInstance>(this: Creatable<T>, params?: Partial<T['params']>): Promisable<T['params']>;
|
|
17
21
|
createHandler(): Promisable<void>;
|
|
18
|
-
paramsValidator(params: Partial<TParams>): TParams;
|
|
22
|
+
paramsValidator(params: Partial<TParams & RequiredCreatableParams>): TParams & RequiredCreatableParams;
|
|
19
23
|
start(): Promise<boolean>;
|
|
20
24
|
stop(): Promise<boolean>;
|
|
21
25
|
protected _noOverride(functionName?: string): void;
|
|
26
|
+
protected setStatus(value: Exclude<CreatableStatus, 'error'>, progress?: number): void;
|
|
27
|
+
protected setStatus(value: Extract<CreatableStatus, 'error'>, error?: Error): void;
|
|
22
28
|
protected startHandler(): Promisable<void>;
|
|
23
29
|
protected stopHandler(): Promisable<void>;
|
|
24
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AbstractCreatable.d.ts","sourceRoot":"","sources":["../../src/AbstractCreatable.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"AbstractCreatable.d.ts","sourceRoot":"","sources":["../../src/AbstractCreatable.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Logger } from '@xylabs/logger';
|
|
2
2
|
import type { Promisable } from '@xylabs/promise';
|
|
3
3
|
import type { AbstractCreatable } from './AbstractCreatable.ts';
|
|
4
|
-
import type { CreatableInstance, CreatableParams, Labels } from './model/index.ts';
|
|
4
|
+
import type { CreatableInstance, CreatableParams, Labels, RequiredCreatableParams } from './model/index.ts';
|
|
5
5
|
export interface CreatableFactory<T extends CreatableInstance = CreatableInstance> extends Omit<Creatable<T>, 'create' | 'createHandler' | 'paramsHandler' | 'defaultLogger' | 'factory'> {
|
|
6
6
|
create(this: CreatableFactory<T>, params?: Partial<T['params']>): Promise<T>;
|
|
7
7
|
}
|
|
@@ -10,7 +10,7 @@ export interface Creatable<T extends CreatableInstance = CreatableInstance> {
|
|
|
10
10
|
new (key: unknown, params: Partial<CreatableParams>): T & AbstractCreatable<T['params']>;
|
|
11
11
|
create<T extends CreatableInstance>(this: Creatable<T>, params?: Partial<T['params']>): Promise<T>;
|
|
12
12
|
createHandler<T extends CreatableInstance>(this: Creatable<T>, instance: T): Promisable<T>;
|
|
13
|
-
paramsHandler<T extends CreatableInstance>(this: Creatable<T>, params?: Partial<T['params']>): Promisable<T['params']>;
|
|
13
|
+
paramsHandler<T extends CreatableInstance>(this: Creatable<T>, params?: Partial<T['params']>): Promisable<T['params'] & RequiredCreatableParams>;
|
|
14
14
|
}
|
|
15
15
|
export interface CreatableWithFactory<T extends CreatableInstance = CreatableInstance> extends Creatable<T> {
|
|
16
16
|
factory<T extends CreatableInstance>(this: Creatable<T>, params?: Partial<T['params']>, labels?: Labels): CreatableFactory<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Creatable.d.ts","sourceRoot":"","sources":["../../src/Creatable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,EACV,iBAAiB,EAAE,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"Creatable.d.ts","sourceRoot":"","sources":["../../src/Creatable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,EACV,iBAAiB,EAAE,eAAe,EAAE,MAAM,EAC1C,uBAAuB,EACxB,MAAM,kBAAkB,CAAA;AAEzB,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,iBAAiB,GAAG,iBAAiB,CAC/E,SAAQ,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,GAAG,eAAe,GAAG,eAAe,GAAG,eAAe,GAAG,SAAS,CAAC;IAEtG,MAAM,CACJ,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,EACzB,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CAC7C;AAED,MAAM,WAAW,SAAS,CAAC,CAAC,SAAS,iBAAiB,GAAG,iBAAiB;IAExE,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB,KAAI,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEvF,MAAM,CAAC,CAAC,SAAS,iBAAiB,EAChC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAClB,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IAE5C,aAAa,CAAC,CAAC,SAAS,iBAAiB,EACvC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAClB,QAAQ,EAAE,CAAC,GACV,UAAU,CAAC,CAAC,CAAC,CAAA;IAEhB,aAAa,CAAC,CAAC,SAAS,iBAAiB,EACvC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,uBAAuB,CAAC,CAAA;CACxG;AAED,MAAM,WAAW,oBAAoB,CAAC,CAAC,SAAS,iBAAiB,GAAG,iBAAiB,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IACzG,OAAO,CAAC,CAAC,SAAS,iBAAiB,EACjC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAClB,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAA;CACxC;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,iBAAiB,MAC3C,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,UAI/C;AAED;;;;;GAKG;AAEH,wBAAgB,gBAAgB,KACtB,CAAC,SAAS,gBAAgB,EAAE,aAAa,CAAC,UAInD"}
|
package/dist/neutral/index.mjs
CHANGED
|
@@ -12,7 +12,8 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
12
12
|
// src/AbstractCreatable.ts
|
|
13
13
|
import { assertEx } from "@xylabs/assert";
|
|
14
14
|
import { BaseEmitter } from "@xylabs/events";
|
|
15
|
-
import { isError } from "@xylabs/typeof";
|
|
15
|
+
import { isError, isNumber as isNumber2 } from "@xylabs/typeof";
|
|
16
|
+
import { Mutex } from "async-mutex";
|
|
16
17
|
|
|
17
18
|
// src/Creatable.ts
|
|
18
19
|
function creatable() {
|
|
@@ -78,6 +79,8 @@ function getRootFunction(obj, funcName) {
|
|
|
78
79
|
var AbstractCreatableConstructorKey = Symbol.for("AbstractCreatableConstructor");
|
|
79
80
|
var AbstractCreatable = class extends BaseEmitter {
|
|
80
81
|
defaultLogger;
|
|
82
|
+
_status = null;
|
|
83
|
+
_statusMutex = new Mutex();
|
|
81
84
|
_validatedParams;
|
|
82
85
|
constructor(key, params) {
|
|
83
86
|
assertEx(key === AbstractCreatableConstructorKey, () => "AbstractCreatable should not be instantiated directly, use the static create method instead");
|
|
@@ -90,18 +93,24 @@ var AbstractCreatable = class extends BaseEmitter {
|
|
|
90
93
|
this._validatedParams = this._validatedParams ?? this.paramsValidator(super.params);
|
|
91
94
|
return this._validatedParams;
|
|
92
95
|
}
|
|
96
|
+
get startable() {
|
|
97
|
+
return this.status === "created" || this.status === "stopped";
|
|
98
|
+
}
|
|
99
|
+
get status() {
|
|
100
|
+
return this._status;
|
|
101
|
+
}
|
|
93
102
|
get statusReporter() {
|
|
94
103
|
return this.params.statusReporter;
|
|
95
104
|
}
|
|
96
105
|
static async create(inParams = {}) {
|
|
97
106
|
const params = await this.paramsHandler(inParams);
|
|
98
107
|
const name = params.name ?? this.name;
|
|
99
|
-
params.statusReporter?.report(name, "creating");
|
|
100
108
|
try {
|
|
101
109
|
const instance = new this(AbstractCreatableConstructorKey, params);
|
|
110
|
+
instance.setStatus("creating");
|
|
102
111
|
const initializedInstance = await this.createHandler(instance);
|
|
103
112
|
await instance.createHandler();
|
|
104
|
-
|
|
113
|
+
instance.setStatus("created");
|
|
105
114
|
return initializedInstance;
|
|
106
115
|
} catch (ex) {
|
|
107
116
|
params.statusReporter?.report(name, "error", isError(ex) ? ex : new Error(`Error creating: ${name}`));
|
|
@@ -115,39 +124,75 @@ var AbstractCreatable = class extends BaseEmitter {
|
|
|
115
124
|
return { ...params };
|
|
116
125
|
}
|
|
117
126
|
createHandler() {
|
|
127
|
+
assertEx(this._status === "creating", () => `createHandler can not be called [status = ${this.status}]`);
|
|
118
128
|
}
|
|
119
129
|
paramsValidator(params) {
|
|
120
130
|
return { ...params, name: params.name ?? this.constructor.name };
|
|
121
131
|
}
|
|
122
132
|
async start() {
|
|
123
133
|
this._noOverride("start");
|
|
124
|
-
|
|
125
|
-
this.statusReporter?.report(this.name, "starting");
|
|
126
|
-
await this.startHandler();
|
|
127
|
-
this.statusReporter?.report(this.name, "started");
|
|
134
|
+
if (this.status === "started") {
|
|
128
135
|
return true;
|
|
129
|
-
} catch (ex) {
|
|
130
|
-
this.statusReporter?.report(this.name, "error", isError(ex) ? ex : new Error(`Error stopping: ${ex}`));
|
|
131
|
-
return false;
|
|
132
136
|
}
|
|
137
|
+
return await this._statusMutex.runExclusive(async () => {
|
|
138
|
+
try {
|
|
139
|
+
if (this.status === "started") {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
assertEx(this.startable, () => `Creatable [${this.name}] is not startable in status [${this.status}]`);
|
|
143
|
+
this.setStatus("starting");
|
|
144
|
+
await this.startHandler();
|
|
145
|
+
this.setStatus("started");
|
|
146
|
+
return true;
|
|
147
|
+
} catch (ex) {
|
|
148
|
+
this.setStatus("error", isError(ex) ? ex : new Error(`Error starting: ${ex}`));
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
});
|
|
133
152
|
}
|
|
134
153
|
async stop() {
|
|
135
154
|
this._noOverride("stop");
|
|
136
|
-
|
|
137
|
-
this.statusReporter?.report(this.name, "stopping");
|
|
138
|
-
await this.stopHandler();
|
|
139
|
-
this.statusReporter?.report(this.name, "stopped");
|
|
155
|
+
if (this.status === "stopped") {
|
|
140
156
|
return true;
|
|
141
|
-
} catch (ex) {
|
|
142
|
-
this.statusReporter?.report(this.name, "error", isError(ex) ? ex : new Error(`Error stopping: ${ex}`));
|
|
143
|
-
return false;
|
|
144
157
|
}
|
|
158
|
+
return await this._statusMutex.runExclusive(async () => {
|
|
159
|
+
try {
|
|
160
|
+
if (this.status === "stopped") {
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
assertEx(this.status === "started", () => `Creatable [${this.name}] is not stoppable in status [${this.status}]`);
|
|
164
|
+
this.setStatus("stopping");
|
|
165
|
+
await this.stopHandler();
|
|
166
|
+
this.setStatus("stopped");
|
|
167
|
+
return true;
|
|
168
|
+
} catch (ex) {
|
|
169
|
+
this.setStatus("error", isError(ex) ? ex : new Error(`Error stopping: ${ex}`));
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
});
|
|
145
173
|
}
|
|
146
174
|
_noOverride(functionName = getFunctionName(3)) {
|
|
147
175
|
const thisFunc = this[functionName];
|
|
148
176
|
const rootFunc = getRootFunction(this, functionName);
|
|
149
177
|
assertEx(thisFunc === rootFunc, () => `Override not allowed for [${functionName}] - override ${functionName}Handler instead`);
|
|
150
178
|
}
|
|
179
|
+
setStatus(value, progressOrError) {
|
|
180
|
+
this._status = value;
|
|
181
|
+
if (value !== null) {
|
|
182
|
+
if (value === "error") {
|
|
183
|
+
if (isError(progressOrError)) {
|
|
184
|
+
this.statusReporter?.report(this.name, value, progressOrError);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
} else {
|
|
188
|
+
if (isNumber2(progressOrError)) {
|
|
189
|
+
this.statusReporter?.report(this.name, value, progressOrError);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
this.statusReporter?.report(this.name, value);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
151
196
|
startHandler() {
|
|
152
197
|
}
|
|
153
198
|
stopHandler() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/AbstractCreatable.ts","../../src/Creatable.ts","../../src/Factory.ts","../../src/lib/getFunctionName.ts","../../src/lib/getRootFunction.ts","../../src/model/Labels.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport type { EventData } from '@xylabs/events'\nimport { BaseEmitter } from '@xylabs/events'\nimport { type Logger } from '@xylabs/logger'\nimport type { Promisable } from '@xylabs/promise'\nimport { isError } from '@xylabs/typeof'\n\nimport {\n type Creatable, creatable, CreatableFactory,\n} from './Creatable.ts'\nimport { Factory } from './Factory.ts'\nimport { getFunctionName, getRootFunction } from './lib/index.ts'\nimport type {\n CreatableInstance, CreatableName, CreatableParams,\n Labels,\n} from './model/index.ts'\n\nconst AbstractCreatableConstructorKey = Symbol.for('AbstractCreatableConstructor')\n\n@creatable()\nexport class AbstractCreatable<TParams extends CreatableParams = CreatableParams,\n TEventData extends EventData = EventData> extends BaseEmitter<Partial<TParams>, TEventData> {\n defaultLogger?: Logger\n\n private _validatedParams?: TParams\n\n constructor(key: unknown, params: Partial<TParams>) {\n assertEx(key === AbstractCreatableConstructorKey, () => 'AbstractCreatable should not be instantiated directly, use the static create method instead')\n super(params)\n }\n\n get name(): CreatableName {\n return this.params.name ?? this.constructor.name as CreatableName\n }\n\n override get params(): TParams {\n this._validatedParams = this._validatedParams ?? this.paramsValidator(super.params)\n return this._validatedParams\n }\n\n get statusReporter() {\n return this.params.statusReporter\n }\n\n static async create<T extends CreatableInstance>(\n this: Creatable<T>,\n inParams: Partial<T['params']> = {},\n ): Promise<T> {\n const params = await this.paramsHandler(inParams)\n const name: CreatableName = params.name ?? this.name as CreatableName\n params.statusReporter?.report(name, 'creating')\n try {\n const instance = new this(AbstractCreatableConstructorKey, params)\n const initializedInstance = await this.createHandler(instance)\n await instance.createHandler()\n params.statusReporter?.report(name, 'created')\n return initializedInstance\n } catch (ex) {\n params.statusReporter?.report(name, 'error', isError(ex) ? ex : new Error(`Error creating: ${name}`))\n throw isError(ex) ? ex : new Error(`Error creating: ${name}`)\n }\n }\n\n static createHandler<T extends CreatableInstance>(\n this: Creatable<T>,\n instance: T,\n ): Promisable<T> {\n return instance\n }\n\n static paramsHandler<T extends CreatableInstance>(\n this: Creatable<T>,\n params: Partial<T['params']> = {},\n ): Promisable<T['params']> {\n return { ...params }\n }\n\n createHandler(): Promisable<void> {}\n\n paramsValidator(params: Partial<TParams>): TParams {\n return { ...params, name: params.name ?? this.constructor.name } as TParams\n }\n\n async start(): Promise<boolean> {\n this._noOverride('start')\n try {\n this.statusReporter?.report(this.name, 'starting')\n await this.startHandler()\n this.statusReporter?.report(this.name, 'started')\n return true\n } catch (ex) {\n this.statusReporter?.report(this.name, 'error', isError(ex) ? ex : new Error(`Error stopping: ${ex}`))\n return false\n }\n }\n\n async stop(): Promise<boolean> {\n this._noOverride('stop')\n try {\n this.statusReporter?.report(this.name, 'stopping')\n await this.stopHandler()\n this.statusReporter?.report(this.name, 'stopped')\n return true\n } catch (ex) {\n this.statusReporter?.report(this.name, 'error', isError(ex) ? ex : new Error(`Error stopping: ${ex}`))\n return false\n }\n }\n\n protected _noOverride(functionName = getFunctionName(3)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const thisFunc = (this as any)[functionName]\n\n const rootFunc = getRootFunction(this, functionName)\n assertEx(thisFunc === rootFunc, () => `Override not allowed for [${functionName}] - override ${functionName}Handler instead`)\n }\n\n protected startHandler(): Promisable<void> {\n // when overriding this, throw an error on failure\n }\n\n protected stopHandler(): Promisable<void> {\n // when overriding this, throw an error on failure\n }\n}\n\n@creatable()\nexport class AbstractCreatableWithFactory<TParams extends CreatableParams = CreatableParams,\n TEventData extends EventData = EventData> extends AbstractCreatable<TParams, TEventData> {\n static factory<T extends CreatableInstance>(\n this: Creatable<T>,\n params?: Partial<T['params']>,\n labels?: Labels,\n ): CreatableFactory<T> {\n return Factory.withParams<T>(this, params, labels)\n }\n}\n","import type { Logger } from '@xylabs/logger'\nimport type { Promisable } from '@xylabs/promise'\n\nimport type { AbstractCreatable } from './AbstractCreatable.ts'\nimport type {\n CreatableInstance, CreatableParams, Labels,\n} from './model/index.ts'\n\nexport interface CreatableFactory<T extends CreatableInstance = CreatableInstance>\n extends Omit<Creatable<T>, 'create' | 'createHandler' | 'paramsHandler' | 'defaultLogger' | 'factory'> {\n\n create(\n this: CreatableFactory<T>,\n params?: Partial<T['params']>): Promise<T>\n}\n\nexport interface Creatable<T extends CreatableInstance = CreatableInstance> {\n\n defaultLogger?: Logger\n\n new(key: unknown, params: Partial<CreatableParams>): T & AbstractCreatable<T['params']>\n\n create<T extends CreatableInstance>(\n this: Creatable<T>,\n params?: Partial<T['params']>): Promise<T>\n\n createHandler<T extends CreatableInstance>(\n this: Creatable<T>,\n instance: T\n ): Promisable<T>\n\n paramsHandler<T extends CreatableInstance>(\n this: Creatable<T>, params?: Partial<T['params']>): Promisable<T['params']>\n}\n\nexport interface CreatableWithFactory<T extends CreatableInstance = CreatableInstance> extends Creatable<T> {\n factory<T extends CreatableInstance>(\n this: Creatable<T>,\n params?: Partial<T['params']>,\n labels?: Labels): CreatableFactory<T>\n}\n\n/**\n * Class annotation to be used to decorate Modules which support\n * an asynchronous creation pattern\n * @returns The decorated Module requiring it implement the members\n * of the CreatableModule as statics properties/methods\n */\nexport function creatable<T extends CreatableInstance>() {\n return <U extends Creatable<T>>(constructor: U) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n constructor\n }\n}\n\n/**\n * Class annotation to be used to decorate Modules which support\n * an asynchronous creation factory pattern\n * @returns The decorated Module requiring it implement the members\n * of the CreatableModule as statics properties/methods\n */\n\nexport function creatableFactory() {\n return <U extends CreatableFactory>(constructor: U) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n constructor\n }\n}\n","import { type Creatable, type CreatableFactory } from './Creatable.ts'\nimport type {\n CreatableInstance, Labels, WithOptionalLabels,\n} from './model/index.ts'\n\nexport class Factory<T extends CreatableInstance = CreatableInstance> implements CreatableFactory<T> {\n creatable: Creatable<T>\n\n defaultParams?: Partial<T['params']>\n\n labels?: Labels\n\n constructor(\n creatable: Creatable<T>,\n params?: Partial<T['params']>,\n labels: Labels = {},\n ) {\n this.creatable = creatable\n this.defaultParams = params\n this.labels = Object.assign({}, (creatable as WithOptionalLabels).labels ?? {}, labels ?? {})\n }\n\n static withParams<T extends CreatableInstance>(\n creatableModule: Creatable<T>,\n params?: Partial<T['params']>,\n labels: Labels = {},\n ) {\n return new Factory<T>(creatableModule, params, labels)\n }\n\n create(params?: Partial<T['params']>): Promise<T> {\n const mergedParams: T['params'] = {\n ...this.defaultParams,\n ...params,\n } as T['params']\n return this.creatable.create<T>(mergedParams)\n }\n}\n","import { isNumber } from '@xylabs/typeof'\n\nexport function getFunctionName(depth = 2) {\n const error = new Error('Stack')\n let newIndex: number | undefined\n const stackParts = error.stack?.split('\\n')[depth]?.split(' ')\n const funcName\n = stackParts?.find((item, index) => {\n if (item.length > 0 && item !== 'at') {\n // check if constructor\n if (item === 'new') {\n newIndex = index\n }\n return true\n }\n }) ?? '<unknown>'\n return isNumber(newIndex) ? `${funcName} ${stackParts?.[newIndex + 1]}` : funcName\n}\n","export function getRootFunction(obj: unknown, funcName: string) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let anyObj = obj as any\n while (anyObj.__proto__?.[funcName]) {\n anyObj = anyObj.__proto__\n }\n return anyObj[funcName]\n}\n","/**\n * Object used to represent labels identifying a resource.\n */\nexport interface Labels {\n [key: string]: string | undefined\n}\n\n/**\n * Interface for objects that have labels.\n */\nexport interface WithLabels<T extends Labels = Labels> {\n labels: T\n}\n\n/**\n * Interface for objects that have labels.\n */\nexport interface WithOptionalLabels<T extends Labels = Labels> {\n labels?: T\n}\n\n/**\n * Returns true if the source object has all the labels from the required set\n * @param source Source object to check against\n * @param required Set of labels to check for in source\n * @returns True of the source object has all the labels from the required set\n */\nexport const hasAllLabels = (source?: Labels, required?: Labels): boolean => {\n if (!required) return true\n return Object.entries(required).every(([key, value]) => {\n return source?.hasOwnProperty(key as keyof typeof source) && source?.[key as keyof typeof source] === value\n })\n}\n"],"mappings":"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","names":["creatable"]}
|
|
1
|
+
{"version":3,"sources":["../../src/AbstractCreatable.ts","../../src/Creatable.ts","../../src/Factory.ts","../../src/lib/getFunctionName.ts","../../src/lib/getRootFunction.ts","../../src/model/Labels.ts"],"sourcesContent":["import { assertEx } from '@xylabs/assert'\nimport type { EventData } from '@xylabs/events'\nimport { BaseEmitter } from '@xylabs/events'\nimport { type Logger } from '@xylabs/logger'\nimport type { Promisable } from '@xylabs/promise'\nimport { isError, isNumber } from '@xylabs/typeof'\nimport { Mutex } from 'async-mutex'\n\nimport {\n type Creatable, creatable, CreatableFactory,\n} from './Creatable.ts'\nimport { Factory } from './Factory.ts'\nimport { getFunctionName, getRootFunction } from './lib/index.ts'\nimport type {\n CreatableInstance, CreatableName, CreatableParams,\n CreatableStatus,\n Labels,\n RequiredCreatableParams,\n} from './model/index.ts'\n\nconst AbstractCreatableConstructorKey = Symbol.for('AbstractCreatableConstructor')\n\n@creatable()\nexport class AbstractCreatable<TParams extends CreatableParams = CreatableParams,\n TEventData extends EventData = EventData> extends BaseEmitter<Partial<TParams & RequiredCreatableParams>, TEventData> {\n defaultLogger?: Logger\n\n private _status: CreatableStatus | null = null\n private _statusMutex = new Mutex()\n private _validatedParams?: TParams & RequiredCreatableParams\n\n constructor(key: unknown, params: Partial<TParams & RequiredCreatableParams>) {\n assertEx(key === AbstractCreatableConstructorKey, () => 'AbstractCreatable should not be instantiated directly, use the static create method instead')\n super(params)\n }\n\n get name(): CreatableName {\n return this.params.name ?? this.constructor.name as CreatableName\n }\n\n override get params(): TParams & RequiredCreatableParams {\n this._validatedParams = this._validatedParams ?? this.paramsValidator(super.params)\n return this._validatedParams\n }\n\n get startable() {\n return this.status === 'created' || this.status === 'stopped'\n }\n\n get status(): CreatableStatus | null {\n return this._status\n }\n\n get statusReporter() {\n return this.params.statusReporter\n }\n\n static async create<T extends CreatableInstance>(\n this: Creatable<T>,\n inParams: Partial<T['params']> = {},\n ): Promise<T> {\n const params = await this.paramsHandler(inParams)\n const name: CreatableName = params.name ?? this.name as CreatableName\n try {\n const instance = new this(AbstractCreatableConstructorKey, params)\n instance.setStatus('creating')\n const initializedInstance = await this.createHandler(instance)\n await instance.createHandler()\n instance.setStatus('created')\n return initializedInstance\n } catch (ex) {\n params.statusReporter?.report(name, 'error', isError(ex) ? ex : new Error(`Error creating: ${name}`))\n throw isError(ex) ? ex : new Error(`Error creating: ${name}`)\n }\n }\n\n static createHandler<T extends CreatableInstance>(\n this: Creatable<T>,\n instance: T,\n ): Promisable<T> {\n return instance\n }\n\n static paramsHandler<T extends CreatableInstance>(\n this: Creatable<T>,\n params: Partial<T['params']> = {},\n ): Promisable<T['params']> {\n return { ...params }\n }\n\n createHandler(): Promisable<void> {\n assertEx(this._status === 'creating', () => `createHandler can not be called [status = ${this.status}]`)\n }\n\n paramsValidator(params: Partial<TParams & RequiredCreatableParams>): TParams & RequiredCreatableParams {\n return { ...params, name: params.name ?? this.constructor.name } as TParams & RequiredCreatableParams\n }\n\n async start(): Promise<boolean> {\n this._noOverride('start')\n if (this.status === 'started') {\n return true\n }\n return await this._statusMutex.runExclusive(async () => {\n try {\n // check again in case it changed\n if (this.status === 'started') {\n return true\n }\n assertEx(this.startable, () => `Creatable [${this.name}] is not startable in status [${this.status}]`)\n this.setStatus('starting')\n await this.startHandler()\n this.setStatus('started')\n return true\n } catch (ex) {\n this.setStatus('error', isError(ex) ? ex : new Error(`Error starting: ${ex}`))\n return false\n }\n })\n }\n\n async stop(): Promise<boolean> {\n this._noOverride('stop')\n if (this.status === 'stopped') {\n return true\n }\n return await this._statusMutex.runExclusive(async () => {\n try {\n // check again in case it changed\n if (this.status === 'stopped') {\n return true\n }\n assertEx(this.status === 'started', () => `Creatable [${this.name}] is not stoppable in status [${this.status}]`)\n this.setStatus('stopping')\n await this.stopHandler()\n this.setStatus('stopped')\n return true\n } catch (ex) {\n this.setStatus('error', isError(ex) ? ex : new Error(`Error stopping: ${ex}`))\n return false\n }\n })\n }\n\n protected _noOverride(functionName = getFunctionName(3)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const thisFunc = (this as any)[functionName]\n\n const rootFunc = getRootFunction(this, functionName)\n assertEx(thisFunc === rootFunc, () => `Override not allowed for [${functionName}] - override ${functionName}Handler instead`)\n }\n\n protected setStatus(value: Exclude<CreatableStatus, 'error'>, progress?: number): void\n protected setStatus(value: Extract<CreatableStatus, 'error'>, error?: Error): void\n protected setStatus(value: CreatableStatus, progressOrError?: number | Error): void {\n this._status = value\n if (value !== null) {\n if (value === 'error') {\n if (isError(progressOrError)) {\n this.statusReporter?.report(this.name, value, progressOrError)\n return\n }\n } else {\n if (isNumber(progressOrError)) {\n this.statusReporter?.report(this.name, value, progressOrError)\n return\n }\n }\n this.statusReporter?.report(this.name, value)\n }\n }\n\n protected startHandler(): Promisable<void> {\n // when overriding this, throw an error on failure\n }\n\n protected stopHandler(): Promisable<void> {\n // when overriding this, throw an error on failure\n }\n}\n\n@creatable()\nexport class AbstractCreatableWithFactory<TParams extends CreatableParams = CreatableParams,\n TEventData extends EventData = EventData> extends AbstractCreatable<TParams, TEventData> {\n static factory<T extends CreatableInstance>(\n this: Creatable<T>,\n params?: Partial<T['params']>,\n labels?: Labels,\n ): CreatableFactory<T> {\n return Factory.withParams<T>(this, params, labels)\n }\n}\n","import type { Logger } from '@xylabs/logger'\nimport type { Promisable } from '@xylabs/promise'\n\nimport type { AbstractCreatable } from './AbstractCreatable.ts'\nimport type {\n CreatableInstance, CreatableParams, Labels,\n RequiredCreatableParams,\n} from './model/index.ts'\n\nexport interface CreatableFactory<T extends CreatableInstance = CreatableInstance>\n extends Omit<Creatable<T>, 'create' | 'createHandler' | 'paramsHandler' | 'defaultLogger' | 'factory'> {\n\n create(\n this: CreatableFactory<T>,\n params?: Partial<T['params']>): Promise<T>\n}\n\nexport interface Creatable<T extends CreatableInstance = CreatableInstance> {\n\n defaultLogger?: Logger\n\n new(key: unknown, params: Partial<CreatableParams>): T & AbstractCreatable<T['params']>\n\n create<T extends CreatableInstance>(\n this: Creatable<T>,\n params?: Partial<T['params']>): Promise<T>\n\n createHandler<T extends CreatableInstance>(\n this: Creatable<T>,\n instance: T\n ): Promisable<T>\n\n paramsHandler<T extends CreatableInstance>(\n this: Creatable<T>, params?: Partial<T['params']>): Promisable<T['params'] & RequiredCreatableParams>\n}\n\nexport interface CreatableWithFactory<T extends CreatableInstance = CreatableInstance> extends Creatable<T> {\n factory<T extends CreatableInstance>(\n this: Creatable<T>,\n params?: Partial<T['params']>,\n labels?: Labels): CreatableFactory<T>\n}\n\n/**\n * Class annotation to be used to decorate Modules which support\n * an asynchronous creation pattern\n * @returns The decorated Module requiring it implement the members\n * of the CreatableModule as statics properties/methods\n */\nexport function creatable<T extends CreatableInstance>() {\n return <U extends Creatable<T>>(constructor: U) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n constructor\n }\n}\n\n/**\n * Class annotation to be used to decorate Modules which support\n * an asynchronous creation factory pattern\n * @returns The decorated Module requiring it implement the members\n * of the CreatableModule as statics properties/methods\n */\n\nexport function creatableFactory() {\n return <U extends CreatableFactory>(constructor: U) => {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n constructor\n }\n}\n","import { type Creatable, type CreatableFactory } from './Creatable.ts'\nimport type {\n CreatableInstance, Labels, WithOptionalLabels,\n} from './model/index.ts'\n\nexport class Factory<T extends CreatableInstance = CreatableInstance> implements CreatableFactory<T> {\n creatable: Creatable<T>\n\n defaultParams?: Partial<T['params']>\n\n labels?: Labels\n\n constructor(\n creatable: Creatable<T>,\n params?: Partial<T['params']>,\n labels: Labels = {},\n ) {\n this.creatable = creatable\n this.defaultParams = params\n this.labels = Object.assign({}, (creatable as WithOptionalLabels).labels ?? {}, labels ?? {})\n }\n\n static withParams<T extends CreatableInstance>(\n creatableModule: Creatable<T>,\n params?: Partial<T['params']>,\n labels: Labels = {},\n ) {\n return new Factory<T>(creatableModule, params, labels)\n }\n\n create(params?: Partial<T['params']>): Promise<T> {\n const mergedParams: T['params'] = {\n ...this.defaultParams,\n ...params,\n } as T['params']\n return this.creatable.create<T>(mergedParams)\n }\n}\n","import { isNumber } from '@xylabs/typeof'\n\nexport function getFunctionName(depth = 2) {\n const error = new Error('Stack')\n let newIndex: number | undefined\n const stackParts = error.stack?.split('\\n')[depth]?.split(' ')\n const funcName\n = stackParts?.find((item, index) => {\n if (item.length > 0 && item !== 'at') {\n // check if constructor\n if (item === 'new') {\n newIndex = index\n }\n return true\n }\n }) ?? '<unknown>'\n return isNumber(newIndex) ? `${funcName} ${stackParts?.[newIndex + 1]}` : funcName\n}\n","export function getRootFunction(obj: unknown, funcName: string) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let anyObj = obj as any\n while (anyObj.__proto__?.[funcName]) {\n anyObj = anyObj.__proto__\n }\n return anyObj[funcName]\n}\n","/**\n * Object used to represent labels identifying a resource.\n */\nexport interface Labels {\n [key: string]: string | undefined\n}\n\n/**\n * Interface for objects that have labels.\n */\nexport interface WithLabels<T extends Labels = Labels> {\n labels: T\n}\n\n/**\n * Interface for objects that have labels.\n */\nexport interface WithOptionalLabels<T extends Labels = Labels> {\n labels?: T\n}\n\n/**\n * Returns true if the source object has all the labels from the required set\n * @param source Source object to check against\n * @param required Set of labels to check for in source\n * @returns True of the source object has all the labels from the required set\n */\nexport const hasAllLabels = (source?: Labels, required?: Labels): boolean => {\n if (!required) return true\n return Object.entries(required).every(([key, value]) => {\n return source?.hasOwnProperty(key as keyof typeof source) && source?.[key as keyof typeof source] === value\n })\n}\n"],"mappings":"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","names":["isNumber","creatable","isNumber"]}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { BaseClassName } from '@xylabs/base';
|
|
2
2
|
import type { BaseEmitterParams } from '@xylabs/events';
|
|
3
|
-
import type { CreatableStatusReporter } from './CreatableStatusReporter.ts';
|
|
3
|
+
import type { CreatableStatus, CreatableStatusReporter } from './CreatableStatusReporter.ts';
|
|
4
4
|
export type CreatableName = Exclude<string, 'creatable-name-reserved-32546239486'> & BaseClassName;
|
|
5
|
-
export interface
|
|
5
|
+
export interface RequiredCreatableParams<TAdditionalStatus extends CreatableStatus | void = void> extends BaseEmitterParams {
|
|
6
6
|
name?: CreatableName;
|
|
7
|
-
statusReporter?: CreatableStatusReporter
|
|
7
|
+
statusReporter?: CreatableStatusReporter<TAdditionalStatus>;
|
|
8
|
+
}
|
|
9
|
+
export interface CreatableParams extends RequiredCreatableParams, BaseEmitterParams {
|
|
8
10
|
}
|
|
9
11
|
//# sourceMappingURL=CreatableParams.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreatableParams.d.ts","sourceRoot":"","sources":["../../../src/model/CreatableParams.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAEvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;
|
|
1
|
+
{"version":3,"file":"CreatableParams.d.ts","sourceRoot":"","sources":["../../../src/model/CreatableParams.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAEvD,OAAO,KAAK,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AAE5F,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,qCAAqC,CAAC,GAAG,aAAa,CAAA;AAElG,MAAM,WAAW,uBAAuB,CAAC,iBAAiB,SAAS,eAAe,GAAG,IAAI,GAAG,IAAI,CAAE,SAAQ,iBAAiB;IACzH,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,cAAc,CAAC,EAAE,uBAAuB,CAAC,iBAAiB,CAAC,CAAA;CAC5D;AAED,MAAM,WAAW,eAAgB,SAAQ,uBAAuB,EAAE,iBAAiB;CAAG"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { BaseClassName } from '@xylabs/base';
|
|
2
|
-
export type
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
report(name: BaseClassName, status:
|
|
2
|
+
export type StandardCreatableStatus = 'creating' | 'created' | 'starting' | 'started' | 'stopping' | 'stopped' | 'error';
|
|
3
|
+
export type CreatableStatus<TAdditionalStatus extends void | string = void> = StandardCreatableStatus | (TAdditionalStatus extends void ? StandardCreatableStatus : TAdditionalStatus);
|
|
4
|
+
export interface CreatableStatusReporter<TAdditionalStatus extends void | string = void> {
|
|
5
|
+
report(name: BaseClassName, status: Exclude<CreatableStatus<TAdditionalStatus>, 'error'>, progress: number): void;
|
|
6
|
+
report(name: BaseClassName, status: Extract<CreatableStatus<TAdditionalStatus>, 'error'>, error: Error): void;
|
|
7
|
+
report(name: BaseClassName, status: CreatableStatus<TAdditionalStatus>): void;
|
|
6
8
|
}
|
|
7
9
|
//# sourceMappingURL=CreatableStatusReporter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreatableStatusReporter.d.ts","sourceRoot":"","sources":["../../../src/model/CreatableStatusReporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAEjD,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"CreatableStatusReporter.d.ts","sourceRoot":"","sources":["../../../src/model/CreatableStatusReporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAEjD,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAA;AACxH,MAAM,MAAM,eAAe,CAAC,iBAAiB,SAAS,IAAI,GAAG,MAAM,GAAG,IAAI,IACtE,uBAAuB,GAAG,CAAC,iBAAiB,SAAS,IAAI,GAAG,uBAAuB,GAAG,iBAAiB,CAAC,CAAA;AAE5G,MAAM,WAAW,uBAAuB,CAAC,iBAAiB,SAAS,IAAI,GAAG,MAAM,GAAG,IAAI;IACrF,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACjH,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IAC7G,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAA;CAC9E"}
|
|
@@ -2,12 +2,12 @@ import type { EventData } from '@xylabs/events';
|
|
|
2
2
|
import { Promisable } from '@xylabs/promise';
|
|
3
3
|
import { AbstractCreatable } from '../AbstractCreatable.ts';
|
|
4
4
|
import { Creatable } from '../Creatable.ts';
|
|
5
|
-
import { CreatableInstance, CreatableParams } from '../model/index.ts';
|
|
5
|
+
import { CreatableInstance, CreatableParams, RequiredCreatableParams } from '../model/index.ts';
|
|
6
6
|
export interface TestCreatableParams extends CreatableParams {
|
|
7
7
|
testParam: string;
|
|
8
8
|
}
|
|
9
9
|
export declare class TestCreatable<TParams extends TestCreatableParams = TestCreatableParams, TEventData extends EventData = EventData> extends AbstractCreatable<TParams, TEventData> {
|
|
10
10
|
static createHandler<T extends CreatableInstance>(this: Creatable<T>, instance: T): Promisable<T>;
|
|
11
|
-
paramsValidator(params?: Partial<TParams>): TParams;
|
|
11
|
+
paramsValidator(params?: Partial<TParams & RequiredCreatableParams>): TParams;
|
|
12
12
|
}
|
|
13
13
|
//# sourceMappingURL=TestCreatable.spec.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestCreatable.spec.d.ts","sourceRoot":"","sources":["../../../src/spec/TestCreatable.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAK5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAa,MAAM,iBAAiB,CAAA;AACtD,OAAO,
|
|
1
|
+
{"version":3,"file":"TestCreatable.spec.d.ts","sourceRoot":"","sources":["../../../src/spec/TestCreatable.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAK5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAa,MAAM,iBAAiB,CAAA;AACtD,OAAO,EACL,iBAAiB,EAAE,eAAe,EAAE,uBAAuB,EAC5D,MAAM,mBAAmB,CAAA;AAE1B,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,qBACa,aAAa,CAAC,OAAO,SAAS,mBAAmB,GAAG,mBAAmB,EAAE,UAAU,SAAS,SAAS,GAAG,SAAS,CAC5H,SAAQ,iBAAiB,CAAC,OAAO,EAAE,UAAU,CAAC;WAC9B,aAAa,CAAC,CAAC,SAAS,iBAAiB,EACvD,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAClB,QAAQ,EAAE,CAAC,GACV,UAAU,CAAC,CAAC,CAAC;IAIP,eAAe,CAAC,MAAM,GAAE,OAAO,CAAC,OAAO,GAAG,uBAAuB,CAAM,GAAG,OAAO;CAM3F"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xylabs/creatable",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.16",
|
|
4
4
|
"description": "Base functionality used throughout XY Labs TypeScript/JavaScript libraries",
|
|
5
5
|
"homepage": "https://xyo.network",
|
|
6
6
|
"bugs": {
|
|
@@ -35,12 +35,13 @@
|
|
|
35
35
|
"src"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@xylabs/assert": "~5.0.
|
|
39
|
-
"@xylabs/base": "~5.0.
|
|
40
|
-
"@xylabs/events": "~5.0.
|
|
41
|
-
"@xylabs/logger": "~5.0.
|
|
42
|
-
"@xylabs/promise": "~5.0.
|
|
43
|
-
"@xylabs/typeof": "~5.0.
|
|
38
|
+
"@xylabs/assert": "~5.0.16",
|
|
39
|
+
"@xylabs/base": "~5.0.16",
|
|
40
|
+
"@xylabs/events": "~5.0.16",
|
|
41
|
+
"@xylabs/logger": "~5.0.16",
|
|
42
|
+
"@xylabs/promise": "~5.0.16",
|
|
43
|
+
"@xylabs/typeof": "~5.0.16",
|
|
44
|
+
"async-mutex": "~0.5.0"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
47
|
"@xylabs/ts-scripts-yarn3": "~7.1.8",
|
package/src/AbstractCreatable.ts
CHANGED
|
@@ -3,7 +3,8 @@ import type { EventData } from '@xylabs/events'
|
|
|
3
3
|
import { BaseEmitter } from '@xylabs/events'
|
|
4
4
|
import { type Logger } from '@xylabs/logger'
|
|
5
5
|
import type { Promisable } from '@xylabs/promise'
|
|
6
|
-
import { isError } from '@xylabs/typeof'
|
|
6
|
+
import { isError, isNumber } from '@xylabs/typeof'
|
|
7
|
+
import { Mutex } from 'async-mutex'
|
|
7
8
|
|
|
8
9
|
import {
|
|
9
10
|
type Creatable, creatable, CreatableFactory,
|
|
@@ -12,19 +13,23 @@ import { Factory } from './Factory.ts'
|
|
|
12
13
|
import { getFunctionName, getRootFunction } from './lib/index.ts'
|
|
13
14
|
import type {
|
|
14
15
|
CreatableInstance, CreatableName, CreatableParams,
|
|
16
|
+
CreatableStatus,
|
|
15
17
|
Labels,
|
|
18
|
+
RequiredCreatableParams,
|
|
16
19
|
} from './model/index.ts'
|
|
17
20
|
|
|
18
21
|
const AbstractCreatableConstructorKey = Symbol.for('AbstractCreatableConstructor')
|
|
19
22
|
|
|
20
23
|
@creatable()
|
|
21
24
|
export class AbstractCreatable<TParams extends CreatableParams = CreatableParams,
|
|
22
|
-
TEventData extends EventData = EventData> extends BaseEmitter<Partial<TParams>, TEventData> {
|
|
25
|
+
TEventData extends EventData = EventData> extends BaseEmitter<Partial<TParams & RequiredCreatableParams>, TEventData> {
|
|
23
26
|
defaultLogger?: Logger
|
|
24
27
|
|
|
25
|
-
private
|
|
28
|
+
private _status: CreatableStatus | null = null
|
|
29
|
+
private _statusMutex = new Mutex()
|
|
30
|
+
private _validatedParams?: TParams & RequiredCreatableParams
|
|
26
31
|
|
|
27
|
-
constructor(key: unknown, params: Partial<TParams>) {
|
|
32
|
+
constructor(key: unknown, params: Partial<TParams & RequiredCreatableParams>) {
|
|
28
33
|
assertEx(key === AbstractCreatableConstructorKey, () => 'AbstractCreatable should not be instantiated directly, use the static create method instead')
|
|
29
34
|
super(params)
|
|
30
35
|
}
|
|
@@ -33,11 +38,19 @@ export class AbstractCreatable<TParams extends CreatableParams = CreatableParams
|
|
|
33
38
|
return this.params.name ?? this.constructor.name as CreatableName
|
|
34
39
|
}
|
|
35
40
|
|
|
36
|
-
override get params(): TParams {
|
|
41
|
+
override get params(): TParams & RequiredCreatableParams {
|
|
37
42
|
this._validatedParams = this._validatedParams ?? this.paramsValidator(super.params)
|
|
38
43
|
return this._validatedParams
|
|
39
44
|
}
|
|
40
45
|
|
|
46
|
+
get startable() {
|
|
47
|
+
return this.status === 'created' || this.status === 'stopped'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get status(): CreatableStatus | null {
|
|
51
|
+
return this._status
|
|
52
|
+
}
|
|
53
|
+
|
|
41
54
|
get statusReporter() {
|
|
42
55
|
return this.params.statusReporter
|
|
43
56
|
}
|
|
@@ -48,12 +61,12 @@ export class AbstractCreatable<TParams extends CreatableParams = CreatableParams
|
|
|
48
61
|
): Promise<T> {
|
|
49
62
|
const params = await this.paramsHandler(inParams)
|
|
50
63
|
const name: CreatableName = params.name ?? this.name as CreatableName
|
|
51
|
-
params.statusReporter?.report(name, 'creating')
|
|
52
64
|
try {
|
|
53
65
|
const instance = new this(AbstractCreatableConstructorKey, params)
|
|
66
|
+
instance.setStatus('creating')
|
|
54
67
|
const initializedInstance = await this.createHandler(instance)
|
|
55
68
|
await instance.createHandler()
|
|
56
|
-
|
|
69
|
+
instance.setStatus('created')
|
|
57
70
|
return initializedInstance
|
|
58
71
|
} catch (ex) {
|
|
59
72
|
params.statusReporter?.report(name, 'error', isError(ex) ? ex : new Error(`Error creating: ${name}`))
|
|
@@ -75,36 +88,58 @@ export class AbstractCreatable<TParams extends CreatableParams = CreatableParams
|
|
|
75
88
|
return { ...params }
|
|
76
89
|
}
|
|
77
90
|
|
|
78
|
-
createHandler(): Promisable<void> {
|
|
91
|
+
createHandler(): Promisable<void> {
|
|
92
|
+
assertEx(this._status === 'creating', () => `createHandler can not be called [status = ${this.status}]`)
|
|
93
|
+
}
|
|
79
94
|
|
|
80
|
-
paramsValidator(params: Partial<TParams>): TParams {
|
|
81
|
-
return { ...params, name: params.name ?? this.constructor.name } as TParams
|
|
95
|
+
paramsValidator(params: Partial<TParams & RequiredCreatableParams>): TParams & RequiredCreatableParams {
|
|
96
|
+
return { ...params, name: params.name ?? this.constructor.name } as TParams & RequiredCreatableParams
|
|
82
97
|
}
|
|
83
98
|
|
|
84
99
|
async start(): Promise<boolean> {
|
|
85
100
|
this._noOverride('start')
|
|
86
|
-
|
|
87
|
-
this.statusReporter?.report(this.name, 'starting')
|
|
88
|
-
await this.startHandler()
|
|
89
|
-
this.statusReporter?.report(this.name, 'started')
|
|
101
|
+
if (this.status === 'started') {
|
|
90
102
|
return true
|
|
91
|
-
} catch (ex) {
|
|
92
|
-
this.statusReporter?.report(this.name, 'error', isError(ex) ? ex : new Error(`Error stopping: ${ex}`))
|
|
93
|
-
return false
|
|
94
103
|
}
|
|
104
|
+
return await this._statusMutex.runExclusive(async () => {
|
|
105
|
+
try {
|
|
106
|
+
// check again in case it changed
|
|
107
|
+
if (this.status === 'started') {
|
|
108
|
+
return true
|
|
109
|
+
}
|
|
110
|
+
assertEx(this.startable, () => `Creatable [${this.name}] is not startable in status [${this.status}]`)
|
|
111
|
+
this.setStatus('starting')
|
|
112
|
+
await this.startHandler()
|
|
113
|
+
this.setStatus('started')
|
|
114
|
+
return true
|
|
115
|
+
} catch (ex) {
|
|
116
|
+
this.setStatus('error', isError(ex) ? ex : new Error(`Error starting: ${ex}`))
|
|
117
|
+
return false
|
|
118
|
+
}
|
|
119
|
+
})
|
|
95
120
|
}
|
|
96
121
|
|
|
97
122
|
async stop(): Promise<boolean> {
|
|
98
123
|
this._noOverride('stop')
|
|
99
|
-
|
|
100
|
-
this.statusReporter?.report(this.name, 'stopping')
|
|
101
|
-
await this.stopHandler()
|
|
102
|
-
this.statusReporter?.report(this.name, 'stopped')
|
|
124
|
+
if (this.status === 'stopped') {
|
|
103
125
|
return true
|
|
104
|
-
} catch (ex) {
|
|
105
|
-
this.statusReporter?.report(this.name, 'error', isError(ex) ? ex : new Error(`Error stopping: ${ex}`))
|
|
106
|
-
return false
|
|
107
126
|
}
|
|
127
|
+
return await this._statusMutex.runExclusive(async () => {
|
|
128
|
+
try {
|
|
129
|
+
// check again in case it changed
|
|
130
|
+
if (this.status === 'stopped') {
|
|
131
|
+
return true
|
|
132
|
+
}
|
|
133
|
+
assertEx(this.status === 'started', () => `Creatable [${this.name}] is not stoppable in status [${this.status}]`)
|
|
134
|
+
this.setStatus('stopping')
|
|
135
|
+
await this.stopHandler()
|
|
136
|
+
this.setStatus('stopped')
|
|
137
|
+
return true
|
|
138
|
+
} catch (ex) {
|
|
139
|
+
this.setStatus('error', isError(ex) ? ex : new Error(`Error stopping: ${ex}`))
|
|
140
|
+
return false
|
|
141
|
+
}
|
|
142
|
+
})
|
|
108
143
|
}
|
|
109
144
|
|
|
110
145
|
protected _noOverride(functionName = getFunctionName(3)) {
|
|
@@ -115,6 +150,26 @@ export class AbstractCreatable<TParams extends CreatableParams = CreatableParams
|
|
|
115
150
|
assertEx(thisFunc === rootFunc, () => `Override not allowed for [${functionName}] - override ${functionName}Handler instead`)
|
|
116
151
|
}
|
|
117
152
|
|
|
153
|
+
protected setStatus(value: Exclude<CreatableStatus, 'error'>, progress?: number): void
|
|
154
|
+
protected setStatus(value: Extract<CreatableStatus, 'error'>, error?: Error): void
|
|
155
|
+
protected setStatus(value: CreatableStatus, progressOrError?: number | Error): void {
|
|
156
|
+
this._status = value
|
|
157
|
+
if (value !== null) {
|
|
158
|
+
if (value === 'error') {
|
|
159
|
+
if (isError(progressOrError)) {
|
|
160
|
+
this.statusReporter?.report(this.name, value, progressOrError)
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
if (isNumber(progressOrError)) {
|
|
165
|
+
this.statusReporter?.report(this.name, value, progressOrError)
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
this.statusReporter?.report(this.name, value)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
118
173
|
protected startHandler(): Promisable<void> {
|
|
119
174
|
// when overriding this, throw an error on failure
|
|
120
175
|
}
|
package/src/Creatable.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { Promisable } from '@xylabs/promise'
|
|
|
4
4
|
import type { AbstractCreatable } from './AbstractCreatable.ts'
|
|
5
5
|
import type {
|
|
6
6
|
CreatableInstance, CreatableParams, Labels,
|
|
7
|
+
RequiredCreatableParams,
|
|
7
8
|
} from './model/index.ts'
|
|
8
9
|
|
|
9
10
|
export interface CreatableFactory<T extends CreatableInstance = CreatableInstance>
|
|
@@ -30,7 +31,7 @@ export interface Creatable<T extends CreatableInstance = CreatableInstance> {
|
|
|
30
31
|
): Promisable<T>
|
|
31
32
|
|
|
32
33
|
paramsHandler<T extends CreatableInstance>(
|
|
33
|
-
this: Creatable<T>, params?: Partial<T['params']>): Promisable<T['params']>
|
|
34
|
+
this: Creatable<T>, params?: Partial<T['params']>): Promisable<T['params'] & RequiredCreatableParams>
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
export interface CreatableWithFactory<T extends CreatableInstance = CreatableInstance> extends Creatable<T> {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { BaseClassName } from '@xylabs/base'
|
|
2
2
|
import type { BaseEmitterParams } from '@xylabs/events'
|
|
3
3
|
|
|
4
|
-
import type { CreatableStatusReporter } from './CreatableStatusReporter.ts'
|
|
4
|
+
import type { CreatableStatus, CreatableStatusReporter } from './CreatableStatusReporter.ts'
|
|
5
5
|
|
|
6
6
|
export type CreatableName = Exclude<string, 'creatable-name-reserved-32546239486'> & BaseClassName
|
|
7
7
|
|
|
8
|
-
export interface
|
|
8
|
+
export interface RequiredCreatableParams<TAdditionalStatus extends CreatableStatus | void = void> extends BaseEmitterParams {
|
|
9
9
|
name?: CreatableName
|
|
10
|
-
statusReporter?: CreatableStatusReporter
|
|
10
|
+
statusReporter?: CreatableStatusReporter<TAdditionalStatus>
|
|
11
11
|
}
|
|
12
|
+
|
|
13
|
+
export interface CreatableParams extends RequiredCreatableParams, BaseEmitterParams {}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { BaseClassName } from '@xylabs/base'
|
|
2
2
|
|
|
3
|
-
export type
|
|
3
|
+
export type StandardCreatableStatus = 'creating' | 'created' | 'starting' | 'started' | 'stopping' | 'stopped' | 'error'
|
|
4
|
+
export type CreatableStatus<TAdditionalStatus extends void | string = void>
|
|
5
|
+
= StandardCreatableStatus | (TAdditionalStatus extends void ? StandardCreatableStatus : TAdditionalStatus)
|
|
4
6
|
|
|
5
|
-
export interface CreatableStatusReporter<
|
|
6
|
-
report(name: BaseClassName, status: Exclude<
|
|
7
|
-
report(name: BaseClassName, status: Extract<
|
|
7
|
+
export interface CreatableStatusReporter<TAdditionalStatus extends void | string = void> {
|
|
8
|
+
report(name: BaseClassName, status: Exclude<CreatableStatus<TAdditionalStatus>, 'error'>, progress: number): void
|
|
9
|
+
report(name: BaseClassName, status: Extract<CreatableStatus<TAdditionalStatus>, 'error'>, error: Error): void
|
|
10
|
+
report(name: BaseClassName, status: CreatableStatus<TAdditionalStatus>): void
|
|
8
11
|
}
|
|
@@ -6,7 +6,9 @@ import {
|
|
|
6
6
|
|
|
7
7
|
import { AbstractCreatable } from '../AbstractCreatable.ts'
|
|
8
8
|
import { Creatable, creatable } from '../Creatable.ts'
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
CreatableInstance, CreatableParams, RequiredCreatableParams,
|
|
11
|
+
} from '../model/index.ts'
|
|
10
12
|
|
|
11
13
|
export interface TestCreatableParams extends CreatableParams {
|
|
12
14
|
testParam: string
|
|
@@ -22,7 +24,7 @@ export class TestCreatable<TParams extends TestCreatableParams = TestCreatablePa
|
|
|
22
24
|
return instance
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
override paramsValidator(params: Partial<TParams> = {}): TParams {
|
|
27
|
+
override paramsValidator(params: Partial<TParams & RequiredCreatableParams> = {}): TParams {
|
|
26
28
|
const result: TestCreatableParams = {
|
|
27
29
|
...params, name: params.name ?? this.constructor.name, testParam: 'yo',
|
|
28
30
|
}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
Creatable, creatable, creatableFactory,
|
|
9
9
|
} from '../Creatable.ts'
|
|
10
|
-
import { CreatableInstance } from '../model/index.ts'
|
|
10
|
+
import { CreatableInstance, RequiredCreatableParams } from '../model/index.ts'
|
|
11
11
|
import { TestCreatable, TestCreatableParams } from './TestCreatable.spec.ts'
|
|
12
12
|
|
|
13
13
|
interface TestCreatableParams2 extends TestCreatableParams {
|
|
@@ -24,7 +24,7 @@ class TestCreatable2<TParams extends TestCreatableParams2 = TestCreatableParams2
|
|
|
24
24
|
return instance
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
override paramsValidator(params: Partial<TParams> = {}): TParams {
|
|
27
|
+
override paramsValidator(params: Partial<TParams & RequiredCreatableParams> = {}): TParams {
|
|
28
28
|
const result: TestCreatableParams = {
|
|
29
29
|
...params, name: params.name ?? this.constructor.name, testParam: 'yo',
|
|
30
30
|
}
|