@engjts/nexus 0.1.7 → 0.1.9
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/advanced/playground/generatePlaygroundHTML.d.ts.map +1 -1
- package/dist/advanced/playground/generatePlaygroundHTML.js +107 -0
- package/dist/advanced/playground/generatePlaygroundHTML.js.map +1 -1
- package/dist/advanced/playground/playground.d.ts +19 -0
- package/dist/advanced/playground/playground.d.ts.map +1 -1
- package/dist/advanced/playground/playground.js +70 -0
- package/dist/advanced/playground/playground.js.map +1 -1
- package/dist/advanced/playground/types.d.ts +20 -0
- package/dist/advanced/playground/types.d.ts.map +1 -1
- package/dist/core/application.d.ts +14 -0
- package/dist/core/application.d.ts.map +1 -1
- package/dist/core/application.js +173 -71
- package/dist/core/application.js.map +1 -1
- package/dist/core/context-pool.d.ts +2 -13
- package/dist/core/context-pool.d.ts.map +1 -1
- package/dist/core/context-pool.js +7 -45
- package/dist/core/context-pool.js.map +1 -1
- package/dist/core/context.d.ts +108 -5
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +449 -53
- package/dist/core/context.js.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +9 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/middleware.d.ts +6 -0
- package/dist/core/middleware.d.ts.map +1 -1
- package/dist/core/middleware.js +83 -84
- package/dist/core/middleware.js.map +1 -1
- package/dist/core/performance/fast-json.d.ts +149 -0
- package/dist/core/performance/fast-json.d.ts.map +1 -0
- package/dist/core/performance/fast-json.js +473 -0
- package/dist/core/performance/fast-json.js.map +1 -0
- package/dist/core/router/file-router.d.ts +20 -7
- package/dist/core/router/file-router.d.ts.map +1 -1
- package/dist/core/router/file-router.js +41 -13
- package/dist/core/router/file-router.js.map +1 -1
- package/dist/core/router/index.d.ts +6 -0
- package/dist/core/router/index.d.ts.map +1 -1
- package/dist/core/router/index.js +33 -6
- package/dist/core/router/index.js.map +1 -1
- package/dist/core/router/radix-tree.d.ts +4 -1
- package/dist/core/router/radix-tree.d.ts.map +1 -1
- package/dist/core/router/radix-tree.js +7 -3
- package/dist/core/router/radix-tree.js.map +1 -1
- package/dist/core/serializer.d.ts +251 -0
- package/dist/core/serializer.d.ts.map +1 -0
- package/dist/core/serializer.js +290 -0
- package/dist/core/serializer.js.map +1 -0
- package/dist/core/types.d.ts +39 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/documentation/01-getting-started.md +0 -240
- package/documentation/02-context.md +0 -335
- package/documentation/03-routing.md +0 -397
- package/documentation/04-middleware.md +0 -483
- package/documentation/05-validation.md +0 -514
- package/documentation/06-error-handling.md +0 -465
- package/documentation/07-performance.md +0 -364
- package/documentation/08-adapters.md +0 -470
- package/documentation/09-api-reference.md +0 -548
- package/documentation/10-examples.md +0 -582
- package/documentation/11-deployment.md +0 -477
- package/documentation/12-sentry.md +0 -620
- package/documentation/13-sentry-data-storage.md +0 -996
- package/documentation/14-sentry-data-reference.md +0 -457
- package/documentation/15-sentry-summary.md +0 -409
- package/documentation/16-alerts-system.md +0 -745
- package/documentation/17-alert-adapters.md +0 -696
- package/documentation/18-alerts-implementation-summary.md +0 -385
- package/documentation/19-class-based-routing.md +0 -840
- package/documentation/20-websocket-realtime.md +0 -813
- package/documentation/21-cache-system.md +0 -510
- package/documentation/22-job-queue.md +0 -772
- package/documentation/23-sentry-plugin.md +0 -551
- package/documentation/24-testing-utilities.md +0 -1287
- package/documentation/25-api-versioning.md +0 -533
- package/documentation/26-context-store.md +0 -607
- package/documentation/27-dependency-injection.md +0 -329
- package/documentation/28-lifecycle-hooks.md +0 -521
- package/documentation/29-package-structure.md +0 -196
- package/documentation/30-plugin-system.md +0 -414
- package/documentation/31-jwt-authentication.md +0 -597
- package/documentation/32-cli.md +0 -268
- package/documentation/ALERTS-COMPLETE-SUMMARY.md +0 -429
- package/documentation/ALERTS-INDEX.md +0 -330
- package/documentation/ALERTS-QUICK-REFERENCE.md +0 -286
- package/documentation/README.md +0 -178
- package/documentation/index.html +0 -34
- package/modern_framework_paper.md +0 -1870
- package/public/css/style.css +0 -87
- package/public/index.html +0 -34
- package/public/js/app.js +0 -27
- package/src/advanced/cache/InMemoryCacheStore.ts +0 -68
- package/src/advanced/cache/MultiTierCache.ts +0 -194
- package/src/advanced/cache/RedisCacheStore.ts +0 -341
- package/src/advanced/cache/index.ts +0 -5
- package/src/advanced/cache/types.ts +0 -40
- package/src/advanced/graphql/SimpleDataLoader.ts +0 -42
- package/src/advanced/graphql/index.ts +0 -22
- package/src/advanced/graphql/server.ts +0 -252
- package/src/advanced/graphql/types.ts +0 -42
- package/src/advanced/jobs/InMemoryQueueStore.ts +0 -68
- package/src/advanced/jobs/JobQueue.ts +0 -556
- package/src/advanced/jobs/RedisQueueStore.ts +0 -367
- package/src/advanced/jobs/index.ts +0 -5
- package/src/advanced/jobs/types.ts +0 -70
- package/src/advanced/observability/APMManager.ts +0 -163
- package/src/advanced/observability/AlertManager.ts +0 -109
- package/src/advanced/observability/MetricRegistry.ts +0 -151
- package/src/advanced/observability/ObservabilityCenter.ts +0 -304
- package/src/advanced/observability/StructuredLogger.ts +0 -154
- package/src/advanced/observability/TracingManager.ts +0 -117
- package/src/advanced/observability/adapters.ts +0 -304
- package/src/advanced/observability/createObservabilityMiddleware.ts +0 -63
- package/src/advanced/observability/index.ts +0 -11
- package/src/advanced/observability/types.ts +0 -174
- package/src/advanced/playground/extractPathParams.ts +0 -6
- package/src/advanced/playground/generateFieldExample.ts +0 -31
- package/src/advanced/playground/generatePlaygroundHTML.ts +0 -1849
- package/src/advanced/playground/generateSummary.ts +0 -19
- package/src/advanced/playground/getTagFromPath.ts +0 -9
- package/src/advanced/playground/index.ts +0 -8
- package/src/advanced/playground/playground.ts +0 -170
- package/src/advanced/playground/types.ts +0 -20
- package/src/advanced/playground/zodToExample.ts +0 -16
- package/src/advanced/playground/zodToParams.ts +0 -15
- package/src/advanced/postman/buildAuth.ts +0 -31
- package/src/advanced/postman/buildBody.ts +0 -15
- package/src/advanced/postman/buildQueryParams.ts +0 -27
- package/src/advanced/postman/buildRequestItem.ts +0 -36
- package/src/advanced/postman/buildResponses.ts +0 -11
- package/src/advanced/postman/buildUrl.ts +0 -33
- package/src/advanced/postman/capitalize.ts +0 -4
- package/src/advanced/postman/generateCollection.ts +0 -59
- package/src/advanced/postman/generateEnvironment.ts +0 -34
- package/src/advanced/postman/generateExampleFromZod.ts +0 -21
- package/src/advanced/postman/generateFieldExample.ts +0 -45
- package/src/advanced/postman/generateName.ts +0 -20
- package/src/advanced/postman/generateUUID.ts +0 -11
- package/src/advanced/postman/getTagFromPath.ts +0 -10
- package/src/advanced/postman/index.ts +0 -28
- package/src/advanced/postman/postman.ts +0 -156
- package/src/advanced/postman/slugify.ts +0 -7
- package/src/advanced/postman/types.ts +0 -140
- package/src/advanced/realtime/index.ts +0 -18
- package/src/advanced/realtime/websocket.ts +0 -231
- package/src/advanced/sentry/index.ts +0 -1236
- package/src/advanced/sentry/types.ts +0 -355
- package/src/advanced/static/generateDirectoryListing.ts +0 -47
- package/src/advanced/static/generateETag.ts +0 -7
- package/src/advanced/static/getMimeType.ts +0 -9
- package/src/advanced/static/index.ts +0 -32
- package/src/advanced/static/isSafePath.ts +0 -13
- package/src/advanced/static/publicDir.ts +0 -21
- package/src/advanced/static/serveStatic.ts +0 -225
- package/src/advanced/static/spa.ts +0 -24
- package/src/advanced/static/types.ts +0 -159
- package/src/advanced/swagger/SwaggerGenerator.ts +0 -66
- package/src/advanced/swagger/buildOperation.ts +0 -61
- package/src/advanced/swagger/buildParameters.ts +0 -61
- package/src/advanced/swagger/buildRequestBody.ts +0 -21
- package/src/advanced/swagger/buildResponses.ts +0 -54
- package/src/advanced/swagger/capitalize.ts +0 -5
- package/src/advanced/swagger/convertPath.ts +0 -9
- package/src/advanced/swagger/createSwagger.ts +0 -12
- package/src/advanced/swagger/generateOperationId.ts +0 -21
- package/src/advanced/swagger/generateSpec.ts +0 -105
- package/src/advanced/swagger/generateSummary.ts +0 -24
- package/src/advanced/swagger/generateSwaggerUI.ts +0 -70
- package/src/advanced/swagger/generateThemeCss.ts +0 -53
- package/src/advanced/swagger/index.ts +0 -25
- package/src/advanced/swagger/swagger.ts +0 -237
- package/src/advanced/swagger/types.ts +0 -206
- package/src/advanced/swagger/zodFieldToOpenAPI.ts +0 -94
- package/src/advanced/swagger/zodSchemaToOpenAPI.ts +0 -50
- package/src/advanced/swagger/zodToOpenAPI.ts +0 -22
- package/src/advanced/testing/factory.ts +0 -509
- package/src/advanced/testing/harness.ts +0 -612
- package/src/advanced/testing/index.ts +0 -430
- package/src/advanced/testing/load-test.ts +0 -618
- package/src/advanced/testing/mock-server.ts +0 -498
- package/src/advanced/testing/mock.ts +0 -670
- package/src/cli/bin.ts +0 -9
- package/src/cli/cli.ts +0 -158
- package/src/cli/commands/add.ts +0 -178
- package/src/cli/commands/build.ts +0 -73
- package/src/cli/commands/create.ts +0 -166
- package/src/cli/commands/dev.ts +0 -85
- package/src/cli/commands/generate.ts +0 -99
- package/src/cli/commands/help.ts +0 -95
- package/src/cli/commands/init.ts +0 -91
- package/src/cli/commands/version.ts +0 -38
- package/src/cli/index.ts +0 -6
- package/src/cli/templates/generators.ts +0 -359
- package/src/cli/templates/index.ts +0 -680
- package/src/cli/utils/exec.ts +0 -52
- package/src/cli/utils/file-system.ts +0 -78
- package/src/cli/utils/logger.ts +0 -111
- package/src/core/adapter.ts +0 -88
- package/src/core/application.ts +0 -1335
- package/src/core/context-pool.ts +0 -127
- package/src/core/context.ts +0 -412
- package/src/core/index.ts +0 -80
- package/src/core/middleware.ts +0 -262
- package/src/core/performance/buffer-pool.ts +0 -108
- package/src/core/performance/middleware-optimizer.ts +0 -162
- package/src/core/plugin/PluginManager.ts +0 -435
- package/src/core/plugin/builder.ts +0 -358
- package/src/core/plugin/index.ts +0 -50
- package/src/core/plugin/types.ts +0 -214
- package/src/core/router/file-router.ts +0 -594
- package/src/core/router/index.ts +0 -227
- package/src/core/router/radix-tree.ts +0 -226
- package/src/core/store/index.ts +0 -30
- package/src/core/store/registry.ts +0 -178
- package/src/core/store/request-store.ts +0 -240
- package/src/core/store/types.ts +0 -233
- package/src/core/types.ts +0 -574
- package/src/database/adapter.ts +0 -35
- package/src/database/adapters/index.ts +0 -1
- package/src/database/adapters/mysql.ts +0 -669
- package/src/database/database.ts +0 -70
- package/src/database/dialect.ts +0 -388
- package/src/database/index.ts +0 -12
- package/src/database/migrations.ts +0 -86
- package/src/database/optimizer.ts +0 -125
- package/src/database/query-builder.ts +0 -404
- package/src/database/realtime.ts +0 -53
- package/src/database/schema.ts +0 -71
- package/src/database/transactions.ts +0 -56
- package/src/database/types.ts +0 -87
- package/src/deployment/cluster.ts +0 -471
- package/src/deployment/config.ts +0 -454
- package/src/deployment/docker.ts +0 -599
- package/src/deployment/graceful-shutdown.ts +0 -373
- package/src/deployment/index.ts +0 -56
- package/src/index.ts +0 -264
- package/src/security/adapter.ts +0 -318
- package/src/security/auth/JWTPlugin.ts +0 -234
- package/src/security/auth/JWTProvider.ts +0 -316
- package/src/security/auth/adapter.ts +0 -12
- package/src/security/auth/jwt.ts +0 -234
- package/src/security/auth/middleware.ts +0 -188
- package/src/security/csrf.ts +0 -220
- package/src/security/headers.ts +0 -108
- package/src/security/index.ts +0 -60
- package/src/security/rate-limit/adapter.ts +0 -7
- package/src/security/rate-limit/memory.ts +0 -108
- package/src/security/rate-limit/middleware.ts +0 -181
- package/src/security/sanitization.ts +0 -75
- package/src/security/types.ts +0 -240
- package/src/security/utils.ts +0 -52
- package/tsconfig.json +0 -39
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RequestStore - Per-request state management
|
|
3
|
-
* State hanya bertahan selama satu request lifecycle
|
|
4
|
-
*
|
|
5
|
-
* Berbeda dengan ContextStore (global/singleton),
|
|
6
|
-
* RequestStore di-create fresh untuk setiap request
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { StoreListener, DisposeCallback, StoreOptions } from './types';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* RequestStore constructor type
|
|
13
|
-
*/
|
|
14
|
-
export type RequestStoreConstructor<T extends RequestStore<any>> = new (...args: any[]) => T;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Extract state type from RequestStore
|
|
18
|
-
*/
|
|
19
|
-
export type RequestStateOf<T> = T extends RequestStore<infer S> ? S : never;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* RequestStore - Per-request scoped state
|
|
23
|
-
*
|
|
24
|
-
* State hanya berlaku untuk satu request.
|
|
25
|
-
* Setiap request baru akan mendapat instance baru.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```typescript
|
|
29
|
-
* interface CheckoutState {
|
|
30
|
-
* items: CartItem[];
|
|
31
|
-
* total: number;
|
|
32
|
-
* discount: number;
|
|
33
|
-
* validated: boolean;
|
|
34
|
-
* }
|
|
35
|
-
*
|
|
36
|
-
* class CheckoutStore extends RequestStore<CheckoutState> {
|
|
37
|
-
* protected initial(): CheckoutState {
|
|
38
|
-
* return { items: [], total: 0, discount: 0, validated: false };
|
|
39
|
-
* }
|
|
40
|
-
*
|
|
41
|
-
* addItem(item: CartItem) {
|
|
42
|
-
* const items = [...this.state.items, item];
|
|
43
|
-
* const total = items.reduce((sum, i) => sum + i.price, 0);
|
|
44
|
-
* this.set({ ...this.state, items, total });
|
|
45
|
-
* }
|
|
46
|
-
*
|
|
47
|
-
* applyDiscount(percent: number) {
|
|
48
|
-
* const discount = this.state.total * (percent / 100);
|
|
49
|
-
* this.update({ discount });
|
|
50
|
-
* }
|
|
51
|
-
*
|
|
52
|
-
* validate() {
|
|
53
|
-
* this.update({ validated: true });
|
|
54
|
-
* }
|
|
55
|
-
* }
|
|
56
|
-
* ```
|
|
57
|
-
*/
|
|
58
|
-
export abstract class RequestStore<T = any> {
|
|
59
|
-
private _state: T;
|
|
60
|
-
private _listeners: Set<StoreListener<T>> = new Set();
|
|
61
|
-
private _options: StoreOptions;
|
|
62
|
-
private _requestId: string;
|
|
63
|
-
|
|
64
|
-
constructor(options: StoreOptions = {}) {
|
|
65
|
-
this._options = options;
|
|
66
|
-
this._state = this.initial();
|
|
67
|
-
this._requestId = this.generateRequestId();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Generate unique request ID
|
|
72
|
-
*/
|
|
73
|
-
private generateRequestId(): string {
|
|
74
|
-
return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Define initial state (wajib implement)
|
|
79
|
-
*/
|
|
80
|
-
protected abstract initial(): T;
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Get current state (readonly)
|
|
84
|
-
*/
|
|
85
|
-
get state(): Readonly<T> {
|
|
86
|
-
return this._state;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Get store name
|
|
91
|
-
*/
|
|
92
|
-
get name(): string {
|
|
93
|
-
return this._options.name || this.constructor.name;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Get request ID (unique per request)
|
|
98
|
-
*/
|
|
99
|
-
get requestId(): string {
|
|
100
|
-
return this._requestId;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Get listener count
|
|
105
|
-
*/
|
|
106
|
-
get listenerCount(): number {
|
|
107
|
-
return this._listeners.size;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Set state (replace entirely)
|
|
112
|
-
*/
|
|
113
|
-
protected set(newState: T): void {
|
|
114
|
-
const prevState = this._state;
|
|
115
|
-
this._state = newState;
|
|
116
|
-
|
|
117
|
-
if (this._options.debug) {
|
|
118
|
-
console.log(`[RequestStore:${this.name}:${this._requestId}] State updated:`, {
|
|
119
|
-
prev: prevState,
|
|
120
|
-
next: newState
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Notify listeners
|
|
125
|
-
this._listeners.forEach(listener => {
|
|
126
|
-
try {
|
|
127
|
-
listener(this._state, prevState);
|
|
128
|
-
} catch (error) {
|
|
129
|
-
console.error(`[RequestStore:${this.name}] Listener error:`, error);
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Update state partially (merge)
|
|
136
|
-
*/
|
|
137
|
-
protected update(partial: Partial<T>): void {
|
|
138
|
-
if (typeof this._state === 'object' && this._state !== null) {
|
|
139
|
-
this.set({ ...this._state, ...partial } as T);
|
|
140
|
-
} else {
|
|
141
|
-
throw new Error(`[RequestStore:${this.name}] update() only works with object state`);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Listen to state changes
|
|
147
|
-
*/
|
|
148
|
-
listen(listener: StoreListener<T>): DisposeCallback {
|
|
149
|
-
this._listeners.add(listener);
|
|
150
|
-
return () => this._listeners.delete(listener);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Reset to initial state
|
|
155
|
-
*/
|
|
156
|
-
reset(): void {
|
|
157
|
-
this.set(this.initial());
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Dispose store (cleanup)
|
|
162
|
-
*/
|
|
163
|
-
dispose(): void {
|
|
164
|
-
if (this._options.debug) {
|
|
165
|
-
console.log(`[RequestStore:${this.name}:${this._requestId}] Disposed`);
|
|
166
|
-
}
|
|
167
|
-
this._listeners.clear();
|
|
168
|
-
this.onDispose();
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Lifecycle: called on dispose
|
|
173
|
-
*/
|
|
174
|
-
protected onDispose(): void {
|
|
175
|
-
// Override if needed
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* RequestStoreRegistry - Manages stores for a single request
|
|
181
|
-
* Created fresh for each request, disposed after response
|
|
182
|
-
*/
|
|
183
|
-
export class RequestStoreRegistry {
|
|
184
|
-
private stores: Map<RequestStoreConstructor<any>, RequestStore<any>> = new Map();
|
|
185
|
-
private debug: boolean;
|
|
186
|
-
|
|
187
|
-
constructor(debug: boolean = false) {
|
|
188
|
-
this.debug = debug;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Get or create a RequestStore for this request
|
|
193
|
-
*/
|
|
194
|
-
get<T extends RequestStore<any>>(StoreClass: RequestStoreConstructor<T>): T {
|
|
195
|
-
if (!this.stores.has(StoreClass)) {
|
|
196
|
-
const instance = new StoreClass({ debug: this.debug });
|
|
197
|
-
this.stores.set(StoreClass, instance);
|
|
198
|
-
|
|
199
|
-
if (this.debug) {
|
|
200
|
-
console.log(`[RequestStoreRegistry] Created: ${StoreClass.name}`);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
return this.stores.get(StoreClass) as T;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Check if store exists
|
|
208
|
-
*/
|
|
209
|
-
has<T extends RequestStore<any>>(StoreClass: RequestStoreConstructor<T>): boolean {
|
|
210
|
-
return this.stores.has(StoreClass);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Get all stores
|
|
215
|
-
*/
|
|
216
|
-
getAll(): RequestStore<any>[] {
|
|
217
|
-
return Array.from(this.stores.values());
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Dispose all stores (call at end of request)
|
|
222
|
-
*/
|
|
223
|
-
dispose(): void {
|
|
224
|
-
this.stores.forEach((store) => {
|
|
225
|
-
try {
|
|
226
|
-
store.dispose();
|
|
227
|
-
} catch (error) {
|
|
228
|
-
console.error(`[RequestStoreRegistry] Dispose error:`, error);
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
this.stores.clear();
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Get store count
|
|
236
|
-
*/
|
|
237
|
-
get size(): number {
|
|
238
|
-
return this.stores.size;
|
|
239
|
-
}
|
|
240
|
-
}
|
package/src/core/store/types.ts
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ContextStore Types
|
|
3
|
-
* State management system inspired by Flutter's Provider pattern
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Listener callback type
|
|
8
|
-
*/
|
|
9
|
-
export type StoreListener<T> = (state: T, prevState: T) => void;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Dispose callback for cleanup
|
|
13
|
-
*/
|
|
14
|
-
export type DisposeCallback = () => void;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Store constructor type for type-safe store access
|
|
18
|
-
*/
|
|
19
|
-
export type StoreConstructor<T extends ContextStore<any>> = new (...args: any[]) => T;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Extract state type from store
|
|
23
|
-
*/
|
|
24
|
-
export type StateOf<T> = T extends ContextStore<infer S> ? S : never;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Store options
|
|
28
|
-
*/
|
|
29
|
-
export interface StoreOptions {
|
|
30
|
-
/** Enable debug logging */
|
|
31
|
-
debug?: boolean;
|
|
32
|
-
/** Store name for debugging */
|
|
33
|
-
name?: string;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Store registry options
|
|
38
|
-
*/
|
|
39
|
-
export interface StoreRegistryOptions {
|
|
40
|
-
/** Enable debug logging */
|
|
41
|
-
debug?: boolean;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Base abstract class for ContextStore
|
|
46
|
-
* Extend this class to create your own stores
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```typescript
|
|
50
|
-
* interface UserState {
|
|
51
|
-
* users: User[];
|
|
52
|
-
* loading: boolean;
|
|
53
|
-
* }
|
|
54
|
-
*
|
|
55
|
-
* class UserStore extends ContextStore<UserState> {
|
|
56
|
-
* protected initial(): UserState {
|
|
57
|
-
* return { users: [], loading: false };
|
|
58
|
-
* }
|
|
59
|
-
*
|
|
60
|
-
* async fetchUsers() {
|
|
61
|
-
* this.set({ ...this.state, loading: true });
|
|
62
|
-
* const users = await api.getUsers();
|
|
63
|
-
* this.set({ users, loading: false });
|
|
64
|
-
* }
|
|
65
|
-
* }
|
|
66
|
-
* ```
|
|
67
|
-
*/
|
|
68
|
-
export abstract class ContextStore<T = any> {
|
|
69
|
-
private _state: T;
|
|
70
|
-
private _listeners: Set<StoreListener<T>> = new Set();
|
|
71
|
-
private _disposeCallbacks: DisposeCallback[] = [];
|
|
72
|
-
private _options: StoreOptions;
|
|
73
|
-
private _initialized: boolean = false;
|
|
74
|
-
|
|
75
|
-
constructor(options: StoreOptions = {}) {
|
|
76
|
-
this._options = options;
|
|
77
|
-
this._state = this.initial();
|
|
78
|
-
this._initialized = true;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Define the initial state
|
|
83
|
-
* Must be implemented by subclasses
|
|
84
|
-
*/
|
|
85
|
-
protected abstract initial(): T;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Get current state (readonly)
|
|
89
|
-
*/
|
|
90
|
-
get state(): Readonly<T> {
|
|
91
|
-
return this._state;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Get store name for debugging
|
|
96
|
-
*/
|
|
97
|
-
get name(): string {
|
|
98
|
-
return this._options.name || this.constructor.name;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Update state and notify all listeners
|
|
103
|
-
*
|
|
104
|
-
* @param newState - New state or partial state update
|
|
105
|
-
*/
|
|
106
|
-
protected set(newState: T): void {
|
|
107
|
-
const prevState = this._state;
|
|
108
|
-
this._state = newState;
|
|
109
|
-
|
|
110
|
-
if (this._options.debug) {
|
|
111
|
-
console.log(`[ContextStore:${this.name}] State updated:`, {
|
|
112
|
-
prev: prevState,
|
|
113
|
-
next: newState
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Notify all listeners
|
|
118
|
-
this._listeners.forEach(listener => {
|
|
119
|
-
try {
|
|
120
|
-
listener(this._state, prevState);
|
|
121
|
-
} catch (error) {
|
|
122
|
-
console.error(`[ContextStore:${this.name}] Listener error:`, error);
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Update state partially (merge with current state)
|
|
129
|
-
* Only works if state is an object
|
|
130
|
-
*
|
|
131
|
-
* @param partial - Partial state to merge
|
|
132
|
-
*/
|
|
133
|
-
protected update(partial: Partial<T>): void {
|
|
134
|
-
if (typeof this._state === 'object' && this._state !== null) {
|
|
135
|
-
this.set({ ...this._state, ...partial } as T);
|
|
136
|
-
} else {
|
|
137
|
-
throw new Error(`[ContextStore:${this.name}] update() only works with object state`);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Listen to state changes
|
|
143
|
-
* Returns unsubscribe function
|
|
144
|
-
*
|
|
145
|
-
* @param listener - Callback function called on state change
|
|
146
|
-
* @returns Unsubscribe function
|
|
147
|
-
*
|
|
148
|
-
* @example
|
|
149
|
-
* ```typescript
|
|
150
|
-
* const unsubscribe = store.listen((state, prevState) => {
|
|
151
|
-
* console.log('State changed:', state);
|
|
152
|
-
* });
|
|
153
|
-
*
|
|
154
|
-
* // Later: cleanup
|
|
155
|
-
* unsubscribe();
|
|
156
|
-
* ```
|
|
157
|
-
*/
|
|
158
|
-
listen(listener: StoreListener<T>): DisposeCallback {
|
|
159
|
-
this._listeners.add(listener);
|
|
160
|
-
|
|
161
|
-
const unsubscribe = () => {
|
|
162
|
-
this._listeners.delete(listener);
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
// Track for auto-dispose
|
|
166
|
-
this._disposeCallbacks.push(unsubscribe);
|
|
167
|
-
|
|
168
|
-
return unsubscribe;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Get listener count (useful for debugging)
|
|
173
|
-
*/
|
|
174
|
-
get listenerCount(): number {
|
|
175
|
-
return this._listeners.size;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Check if store is initialized
|
|
180
|
-
*/
|
|
181
|
-
get isInitialized(): boolean {
|
|
182
|
-
return this._initialized;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Reset state to initial value
|
|
187
|
-
*/
|
|
188
|
-
reset(): void {
|
|
189
|
-
this.set(this.initial());
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Dispose store and cleanup all listeners
|
|
194
|
-
* Called automatically when store is removed from registry
|
|
195
|
-
*/
|
|
196
|
-
dispose(): void {
|
|
197
|
-
if (this._options.debug) {
|
|
198
|
-
console.log(`[ContextStore:${this.name}] Disposing...`);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Clear all listeners
|
|
202
|
-
this._listeners.clear();
|
|
203
|
-
|
|
204
|
-
// Call all dispose callbacks
|
|
205
|
-
this._disposeCallbacks.forEach(cb => {
|
|
206
|
-
try {
|
|
207
|
-
cb();
|
|
208
|
-
} catch (error) {
|
|
209
|
-
console.error(`[ContextStore:${this.name}] Dispose callback error:`, error);
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
this._disposeCallbacks = [];
|
|
213
|
-
|
|
214
|
-
// Call lifecycle hook
|
|
215
|
-
this.onDispose();
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Lifecycle hook: called when store is disposed
|
|
220
|
-
* Override to add custom cleanup logic
|
|
221
|
-
*/
|
|
222
|
-
protected onDispose(): void {
|
|
223
|
-
// Override in subclass if needed
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Lifecycle hook: called when store is first accessed
|
|
228
|
-
* Override to add initialization logic (e.g., fetch initial data)
|
|
229
|
-
*/
|
|
230
|
-
onInit(): void | Promise<void> {
|
|
231
|
-
// Override in subclass if needed
|
|
232
|
-
}
|
|
233
|
-
}
|