@xylabs/creatable 5.0.76 → 5.0.78

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.
Files changed (48) hide show
  1. package/dist/neutral/AbstractCreatable.d.ts +1 -3
  2. package/dist/neutral/AbstractCreatable.d.ts.map +1 -1
  3. package/dist/neutral/Creatable.d.ts +0 -5
  4. package/dist/neutral/Creatable.d.ts.map +1 -1
  5. package/dist/neutral/index.d.ts +0 -3
  6. package/dist/neutral/index.d.ts.map +1 -1
  7. package/dist/neutral/index.mjs +0 -294
  8. package/dist/neutral/index.mjs.map +1 -1
  9. package/dist/neutral/model/CreatableInstance.d.ts +1 -2
  10. package/dist/neutral/model/CreatableInstance.d.ts.map +1 -1
  11. package/dist/neutral/model/CreatableParams.d.ts +2 -1
  12. package/dist/neutral/model/CreatableParams.d.ts.map +1 -1
  13. package/dist/neutral/model/CreatableStatusReporter.d.ts +4 -7
  14. package/dist/neutral/model/CreatableStatusReporter.d.ts.map +1 -1
  15. package/dist/neutral/model/index.d.ts +0 -5
  16. package/dist/neutral/model/index.d.ts.map +1 -1
  17. package/package.json +9 -15
  18. package/src/AbstractCreatable.ts +1 -3
  19. package/src/Creatable.ts +0 -5
  20. package/src/index.ts +0 -3
  21. package/src/model/CreatableInstance.ts +1 -2
  22. package/src/model/CreatableParams.ts +3 -1
  23. package/src/model/CreatableStatusReporter.ts +4 -8
  24. package/src/model/index.ts +0 -5
  25. package/dist/neutral/AbstractCreatableV2.d.ts +0 -62
  26. package/dist/neutral/AbstractCreatableV2.d.ts.map +0 -1
  27. package/dist/neutral/CreatableV2.d.ts +0 -31
  28. package/dist/neutral/CreatableV2.d.ts.map +0 -1
  29. package/dist/neutral/FactoryV2.d.ts +0 -11
  30. package/dist/neutral/FactoryV2.d.ts.map +0 -1
  31. package/dist/neutral/model/CreatableInstanceV2.d.ts +0 -13
  32. package/dist/neutral/model/CreatableInstanceV2.d.ts.map +0 -1
  33. package/dist/neutral/model/CreatableName.d.ts +0 -5
  34. package/dist/neutral/model/CreatableName.d.ts.map +0 -1
  35. package/dist/neutral/model/CreatableParamsV2.d.ts +0 -64
  36. package/dist/neutral/model/CreatableParamsV2.d.ts.map +0 -1
  37. package/dist/neutral/model/CreatableStatusReporter.zod.d.ts +0 -44
  38. package/dist/neutral/model/CreatableStatusReporter.zod.d.ts.map +0 -1
  39. package/dist/neutral/model/CreatableStatusReporterV2.d.ts +0 -7
  40. package/dist/neutral/model/CreatableStatusReporterV2.d.ts.map +0 -1
  41. package/src/AbstractCreatableV2.ts +0 -270
  42. package/src/CreatableV2.ts +0 -67
  43. package/src/FactoryV2.ts +0 -38
  44. package/src/model/CreatableInstanceV2.ts +0 -15
  45. package/src/model/CreatableName.ts +0 -3
  46. package/src/model/CreatableParamsV2.ts +0 -11
  47. package/src/model/CreatableStatusReporter.zod.ts +0 -31
  48. package/src/model/CreatableStatusReporterV2.ts +0 -11
@@ -1,270 +0,0 @@
1
- import { assertEx } from '@xylabs/assert'
2
- import type { EventData } from '@xylabs/events'
3
- import { BaseEmitterV2 } from '@xylabs/events'
4
- import { type Logger } from '@xylabs/logger'
5
- import type { Promisable } from '@xylabs/promise'
6
- import type { SpanConfig } from '@xylabs/telemetry'
7
- import { spanRoot, spanRootAsync } from '@xylabs/telemetry'
8
- import {
9
- isError, isNumber, isString,
10
- isUndefined,
11
- } from '@xylabs/typeof'
12
- import { Mutex } from 'async-mutex'
13
-
14
- import type { CreatableFactoryV2, CreatableV2 } from './CreatableV2.ts'
15
- import { FactoryV2 } from './FactoryV2.ts'
16
- import { getFunctionName, getRootFunction } from './lib/index.ts'
17
- import type {
18
- CreatableInstanceV2,
19
- CreatableName, CreatableParamsV2,
20
- CreatableStatusV2,
21
- Labels,
22
- } from './model/index.ts'
23
-
24
- const AbstractCreatableConstructorKey = Symbol.for('AbstractCreatableConstructor')
25
- const CREATABLE_NOT_STARTED = 'Creatable not Started' as const
26
-
27
- export abstract class AbstractCreatableV2<TParams extends CreatableParamsV2 = CreatableParamsV2,
28
- TEventData extends EventData = EventData> extends BaseEmitterV2<TParams, TEventData> implements CreatableInstanceV2<TParams, TEventData> {
29
- defaultLogger?: Logger
30
-
31
- protected _startPromise: Promisable<boolean> | undefined
32
- private _status: CreatableStatusV2 | null = null
33
- private _statusMutex = new Mutex()
34
- private _validatedParams?: TParams
35
-
36
- constructor(key: unknown, params: TParams) {
37
- assertEx(key === AbstractCreatableConstructorKey, () => 'AbstractCreatable should not be instantiated directly, use the static create method instead')
38
- super(params)
39
- this.setStatus('creating')
40
- }
41
-
42
- override get context(): TParams['context'] {
43
- return this.params.context
44
- }
45
-
46
- get name(): CreatableName {
47
- return this.params.name as CreatableName
48
- }
49
-
50
- override get params(): TParams {
51
- this._validatedParams = this._validatedParams ?? this.paramsValidator(super.params)
52
- return assertEx(this._validatedParams)
53
- }
54
-
55
- get startable() {
56
- return this.status === 'created' || this.status === 'stopped'
57
- }
58
-
59
- get status(): CreatableStatusV2 | null {
60
- return this._status
61
- }
62
-
63
- get statusReporter() {
64
- return this.context.statusReporter
65
- }
66
-
67
- abstract override get className(): CreatableName
68
-
69
- static async create<T extends CreatableInstanceV2>(
70
- this: CreatableV2<T>,
71
- inParams: T['params'],
72
- ): Promise<T> {
73
- const params = await this.paramsHandler(inParams)
74
- const name = (params.name ?? this.name) as CreatableName
75
- try {
76
- const instance = new this(AbstractCreatableConstructorKey, params)
77
- const initializedInstance = await this.createHandler(instance)
78
- await instance.createHandler()
79
- return initializedInstance
80
- } catch (ex) {
81
- params.context.statusReporter?.report(name, 'error', isError(ex) ? ex : new Error(`Error creating: ${name}`))
82
- params.context.logger?.error(`Error creating creatable [${name}]: ${(isError(ex) ? `${ex.message} ${ex.stack}` : ex)}`)
83
- throw isError(ex) ? ex : new Error(`Error creating: ${name}`)
84
- }
85
- }
86
-
87
- static createHandler<T extends CreatableInstanceV2>(
88
- this: CreatableV2<T>,
89
- instance: T,
90
- ): Promisable<T> {
91
- return instance
92
- }
93
-
94
- static paramsHandler<T extends CreatableInstanceV2>(
95
- this: CreatableV2<T>,
96
- params: Partial<T['params']> = {},
97
- ): Promisable<T['params']> {
98
- return { ...params } as T['params']
99
- }
100
-
101
- createHandler(): Promisable<void> {
102
- assertEx(this._status === 'creating', () => `createHandler can not be called [status = ${this.status}]`)
103
- this.setStatus('created')
104
- }
105
-
106
- paramsValidator(params: Partial<TParams>): TParams {
107
- return { ...params, name: params.name } as TParams
108
- }
109
-
110
- span<T>(name: string, fn: () => T): T {
111
- return spanRoot(name, fn, this.tracer)
112
- }
113
-
114
- async spanAsync<T>(name: string, fn: () => Promise<T>, config: SpanConfig = {}): Promise<T> {
115
- return await spanRootAsync(name, fn, {
116
- ...config, tracer: config.tracer ?? this.tracer, logger: config.logger ?? this.defaultLogger,
117
- })
118
- }
119
-
120
- async start(): Promise<boolean> {
121
- this._noOverride('start')
122
- if (this.status === 'started') {
123
- return true
124
- }
125
- return await this._statusMutex.runExclusive(async () => {
126
- try {
127
- // check again in case it changed
128
- if (this.status === 'started') {
129
- return true
130
- }
131
- assertEx(this.startable, () => `Creatable [${this.name}] is not startable in status [${this.status}]`)
132
- this.setStatus('starting')
133
- await this.startHandler()
134
- this.setStatus('started')
135
- return true
136
- } catch (ex) {
137
- this.setStatus('error', isError(ex) ? ex : new Error(`Error starting: ${ex}`))
138
- this.logger?.error(`Error starting creatable [${this.name}]: ${(isError(ex) ? `${ex.message} ${ex.stack}` : ex)}`)
139
- return false
140
- }
141
- })
142
- }
143
-
144
- started(notStartedAction: 'error' | 'throw' | 'warn' | 'log' | 'none' = 'log'): boolean {
145
- if (isString(this.status) && this.status === 'started') {
146
- return true
147
- } else {
148
- const message = () => `${CREATABLE_NOT_STARTED} [${this.name}] current state: ${this.status}`
149
- switch (notStartedAction) {
150
- case 'error': {
151
- throw new Error(message())
152
- }
153
- case 'throw': {
154
- throw new Error(message())
155
- }
156
- case 'warn': {
157
- this.logger?.warn(message())
158
- break
159
- }
160
- case 'log': {
161
- this.logger?.log(message())
162
- break
163
- }
164
- case 'none': {
165
- break
166
- }
167
- default: {
168
- throw new Error(`Unknown notStartedAction: ${notStartedAction}`)
169
- }
170
- }
171
- return false
172
- }
173
- }
174
-
175
- async startedAsync(notStartedAction: 'error' | 'throw' | 'warn' | 'log' | 'none' = 'log', tryStart = true): Promise<boolean> {
176
- if (isString(this.status) && this.status === 'started') {
177
- return true
178
- } else if (this.status === 'created' || this.status === 'stopped' || this.status === 'starting') {
179
- // using promise as mutex
180
- this._startPromise = this._startPromise ?? (async () => {
181
- if (tryStart) {
182
- try {
183
- return await this.start()
184
- } finally {
185
- this._startPromise = undefined
186
- }
187
- }
188
- return this.started(notStartedAction)
189
- })()
190
- } else {
191
- const message = `${CREATABLE_NOT_STARTED} [${this.name}] current state: ${this.status}`
192
- throw new Error(message)
193
- }
194
-
195
- if (isUndefined(this._startPromise)) {
196
- throw new Error(`Failed to create start promise: ${this.status}`)
197
- }
198
- return await this._startPromise
199
- }
200
-
201
- async stop(): Promise<boolean> {
202
- this._noOverride('stop')
203
- if (this.status === 'stopped') {
204
- return true
205
- }
206
- return await this._statusMutex.runExclusive(async () => {
207
- try {
208
- // check again in case it changed
209
- if (this.status === 'stopped') {
210
- return true
211
- }
212
- assertEx(this.status === 'started', () => `Creatable [${this.name}] is not stoppable in status [${this.status}]`)
213
- this.setStatus('stopping')
214
- await this.stopHandler()
215
- this.setStatus('stopped')
216
- return true
217
- } catch (ex) {
218
- this.setStatus('error', isError(ex) ? ex : new Error(`Error stopping: ${ex}`))
219
- return false
220
- }
221
- })
222
- }
223
-
224
- protected _noOverride(functionName = getFunctionName(3)) {
225
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
226
- const thisFunc = (this as any)[functionName]
227
-
228
- const rootFunc = getRootFunction(this, functionName)
229
- assertEx(thisFunc === rootFunc, () => `Override not allowed for [${functionName}] - override ${functionName}Handler instead`)
230
- }
231
-
232
- protected setStatus(value: Exclude<CreatableStatusV2, 'error'>, progress?: number): void
233
- protected setStatus(value: Extract<CreatableStatusV2, 'error'>, error?: Error): void
234
- protected setStatus(value: CreatableStatusV2, progressOrError?: number | Error): void {
235
- this._status = value
236
- if (value !== null) {
237
- if (value === 'error') {
238
- if (isError(progressOrError)) {
239
- this.statusReporter?.report(this.name, value, progressOrError)
240
- return
241
- }
242
- } else {
243
- if (isNumber(progressOrError)) {
244
- this.statusReporter?.report(this.name, value, progressOrError)
245
- return
246
- }
247
- }
248
- this.statusReporter?.report(this.name, value)
249
- }
250
- }
251
-
252
- protected startHandler(): Promisable<void> {
253
- // when overriding this, throw an error on failure
254
- }
255
-
256
- protected stopHandler(): Promisable<void> {
257
- // when overriding this, throw an error on failure
258
- }
259
- }
260
-
261
- export abstract class AbstractCreatableWithFactoryV2<TParams extends CreatableParamsV2 = CreatableParamsV2,
262
- TEventData extends EventData = EventData> extends AbstractCreatableV2<TParams, TEventData> {
263
- static factory<T extends CreatableInstanceV2>(
264
- this: CreatableV2<T>,
265
- params: T['params'],
266
- labels?: Labels,
267
- ): CreatableFactoryV2<T> {
268
- return FactoryV2.withParams<T>(this, params, labels)
269
- }
270
- }
@@ -1,67 +0,0 @@
1
- import type { Logger } from '@xylabs/logger'
2
- import type { Promisable } from '@xylabs/promise'
3
-
4
- import type {
5
- CreatableInstanceV2, CreatableParamsV2, Labels,
6
- } from './model/index.ts'
7
-
8
- export interface CreatableFactoryV2<T extends CreatableInstanceV2 = CreatableInstanceV2>
9
- extends Omit<CreatableV2<T>, 'create' | 'createHandler' | 'paramsHandler' | 'defaultLogger' | 'factory'> {
10
-
11
- create(
12
- this: CreatableFactoryV2<T>,
13
- params: T['params']): Promise<T>
14
- }
15
-
16
- export interface CreatableV2<T extends CreatableInstanceV2 = CreatableInstanceV2> {
17
-
18
- defaultLogger?: Logger
19
-
20
- new(key: unknown, params: CreatableParamsV2): T
21
-
22
- create<T extends CreatableInstanceV2>(
23
- this: CreatableV2<T>,
24
- params: T['params']): Promise<T>
25
-
26
- createHandler<T extends CreatableInstanceV2>(
27
- this: CreatableV2<T>,
28
- instance: T
29
- ): Promisable<T>
30
-
31
- paramsHandler<T extends CreatableInstanceV2>(
32
- this: CreatableV2<T>, params: Partial<T['params']>): Promisable<T['params']>
33
- }
34
-
35
- export interface CreatableWithFactoryV2<T extends CreatableInstanceV2 = CreatableInstanceV2> extends CreatableV2<T> {
36
- factory<T extends CreatableInstanceV2>(
37
- this: CreatableV2<T>,
38
- params: T['params'],
39
- labels?: Labels): CreatableFactoryV2<T>
40
- }
41
-
42
- /**
43
- * Class annotation to be used to decorate Modules which support
44
- * an asynchronous creation pattern
45
- * @returns The decorated Module requiring it implement the members
46
- * of the CreatableModule as statics properties/methods
47
- */
48
- export function creatableV2<T extends CreatableInstanceV2>() {
49
- return <U extends CreatableV2<T>>(constructor: U) => {
50
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
51
- constructor
52
- }
53
- }
54
-
55
- /**
56
- * Class annotation to be used to decorate Modules which support
57
- * an asynchronous creation factory pattern
58
- * @returns The decorated Module requiring it implement the members
59
- * of the CreatableModule as statics properties/methods
60
- */
61
-
62
- export function creatableFactoryV2() {
63
- return <U extends CreatableFactoryV2>(constructor: U) => {
64
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
65
- constructor
66
- }
67
- }
package/src/FactoryV2.ts DELETED
@@ -1,38 +0,0 @@
1
- import type { CreatableFactoryV2, CreatableV2 } from './CreatableV2.ts'
2
- import type {
3
- CreatableInstanceV2, Labels, WithOptionalLabels,
4
- } from './model/index.ts'
5
-
6
- export class FactoryV2<T extends CreatableInstanceV2 = CreatableInstanceV2> implements CreatableFactoryV2<T> {
7
- creatable: CreatableV2<T>
8
-
9
- defaultParams?: Partial<T['params']>
10
-
11
- labels?: Labels
12
-
13
- constructor(
14
- creatable: CreatableV2<T>,
15
- params: T['params'],
16
- labels: Labels = {},
17
- ) {
18
- this.creatable = creatable
19
- this.defaultParams = params
20
- this.labels = Object.assign({}, (creatable as WithOptionalLabels).labels ?? {}, labels ?? {})
21
- }
22
-
23
- static withParams<T extends CreatableInstanceV2>(
24
- creatableModule: CreatableV2<T>,
25
- params: T['params'],
26
- labels: Labels = {},
27
- ) {
28
- return new FactoryV2<T>(creatableModule, params, labels)
29
- }
30
-
31
- create(params: Partial<T['params']>): Promise<T> {
32
- const mergedParams: T['params'] = {
33
- ...this.defaultParams,
34
- ...params,
35
- } as T['params']
36
- return this.creatable.create<T>(mergedParams)
37
- }
38
- }
@@ -1,15 +0,0 @@
1
- import type { EventData, EventEmitter } from '@xylabs/events'
2
- import type { Promisable } from '@xylabs/promise'
3
-
4
- import type { CreatableName } from './CreatableName.ts'
5
- import type { CreatableParamsV2 } from './CreatableParamsV2.ts'
6
-
7
- export interface CreatableInstanceV2<TParams extends CreatableParamsV2 = CreatableParamsV2,
8
- TEventData extends EventData = EventData> extends EventEmitter<TEventData> {
9
- createHandler: () => Promisable<void>
10
- eventData: TEventData
11
- name: CreatableName
12
- params: TParams
13
- start: () => Promise<boolean>
14
- stop: () => Promise<boolean>
15
- }
@@ -1,3 +0,0 @@
1
- import type { BaseClassName } from '@xylabs/base'
2
-
3
- export type CreatableName = BaseClassName & { __creatableName: true }
@@ -1,11 +0,0 @@
1
- import { CachingContextZod } from '@xylabs/base'
2
- import { BaseEmitterParamsV2Zod } from '@xylabs/events'
3
- import z from 'zod'
4
-
5
- import { CreatableStatusReporterV2Zod } from './CreatableStatusReporter.zod.ts'
6
-
7
- export const CreatableContextZod = CachingContextZod.extend({ statusReporter: CreatableStatusReporterV2Zod.optional() })
8
-
9
- export const CreatableParamsV2Zod = BaseEmitterParamsV2Zod.extend({ context: CreatableContextZod, name: z.string() })
10
-
11
- export type CreatableParamsV2 = z.infer<typeof CreatableParamsV2Zod>
@@ -1,31 +0,0 @@
1
- import { z } from 'zod'
2
-
3
- export const CreatableStatusSuccessZod = z.enum(['creating', 'created', 'starting', 'started', 'stopping', 'stopped'])
4
-
5
- export const CreatableStatusErrorZod = z.enum(['error'])
6
-
7
- export const CreatableStatusZod = z.union([CreatableStatusSuccessZod, CreatableStatusErrorZod])
8
-
9
- export const CreatableStatusReporterV2Zod = z.object({
10
- report: z.union([
11
- z.function({
12
- input: z.union([
13
- z.tuple([
14
- z.string(),
15
- CreatableStatusSuccessZod,
16
- z.number().optional(),
17
- ]),
18
- z.tuple([
19
- z.string(),
20
- CreatableStatusErrorZod,
21
- z.instanceof(Error),
22
- ]),
23
- z.tuple([
24
- z.string(),
25
- CreatableStatusZod,
26
- ]),
27
- ]),
28
- output: z.void(),
29
- }),
30
- ]),
31
- })
@@ -1,11 +0,0 @@
1
- import type z from 'zod'
2
-
3
- import type {
4
- CreatableStatusReporterV2Zod, CreatableStatusSuccessZod, CreatableStatusZod,
5
- } from './CreatableStatusReporter.zod.ts'
6
-
7
- export type CreatableStatusSuccessV2 = z.infer<typeof CreatableStatusSuccessZod>
8
- export type CreatableStatusErrorV2 = Extract<CreatableStatusV2, 'error'>
9
- export type CreatableStatusV2 = z.infer<typeof CreatableStatusZod>
10
-
11
- export type CreatableStatusReporterV2 = z.infer<typeof CreatableStatusReporterV2Zod>