@adaas/a-server 0.0.29 → 0.0.30

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 (84) hide show
  1. package/dist/browser/index.d.mts +123 -69
  2. package/dist/browser/index.mjs +211 -69
  3. package/dist/browser/index.mjs.map +1 -1
  4. package/dist/node/controllers/A-EntityController/A-EntityController.component.d.mts +2 -5
  5. package/dist/node/controllers/A-EntityController/A-EntityController.component.d.ts +2 -5
  6. package/dist/node/controllers/A-EntityController/A-EntityController.component.js +66 -88
  7. package/dist/node/controllers/A-EntityController/A-EntityController.component.js.map +1 -1
  8. package/dist/node/controllers/A-EntityController/A-EntityController.component.mjs +67 -89
  9. package/dist/node/controllers/A-EntityController/A-EntityController.component.mjs.map +1 -1
  10. package/dist/node/controllers/A-ListingController/A-ListingController.component.js +20 -18
  11. package/dist/node/controllers/A-ListingController/A-ListingController.component.js.map +1 -1
  12. package/dist/node/controllers/A-ListingController/A-ListingController.component.mjs +20 -18
  13. package/dist/node/controllers/A-ListingController/A-ListingController.component.mjs.map +1 -1
  14. package/dist/node/controllers/A-ServerHealthMonitor/A-ServerHealthMonitor.component.d.mts +0 -2
  15. package/dist/node/controllers/A-ServerHealthMonitor/A-ServerHealthMonitor.component.d.ts +0 -2
  16. package/dist/node/controllers/A-ServerHealthMonitor/A-ServerHealthMonitor.component.js +10 -1
  17. package/dist/node/controllers/A-ServerHealthMonitor/A-ServerHealthMonitor.component.js.map +1 -1
  18. package/dist/node/controllers/A-ServerHealthMonitor/A-ServerHealthMonitor.component.mjs +10 -1
  19. package/dist/node/controllers/A-ServerHealthMonitor/A-ServerHealthMonitor.component.mjs.map +1 -1
  20. package/dist/node/index.d.mts +3 -1
  21. package/dist/node/index.d.ts +3 -1
  22. package/dist/node/index.js +14 -0
  23. package/dist/node/index.mjs +2 -0
  24. package/dist/node/lib/A-Server/A-HttpServer.container.d.mts +4 -6
  25. package/dist/node/lib/A-Server/A-HttpServer.container.d.ts +4 -6
  26. package/dist/node/lib/A-ServerController/A-ServerController.component.js +17 -4
  27. package/dist/node/lib/A-ServerController/A-ServerController.component.js.map +1 -1
  28. package/dist/node/lib/A-ServerController/A-ServerController.component.mjs +17 -4
  29. package/dist/node/lib/A-ServerController/A-ServerController.component.mjs.map +1 -1
  30. package/dist/node/lib/A-ServerEntityList/A-EntityList.entity.d.mts +52 -28
  31. package/dist/node/lib/A-ServerEntityList/A-EntityList.entity.d.ts +52 -28
  32. package/dist/node/lib/A-ServerEntityList/A-EntityList.entity.js +117 -44
  33. package/dist/node/lib/A-ServerEntityList/A-EntityList.entity.js.map +1 -1
  34. package/dist/node/lib/A-ServerEntityList/A-EntityList.entity.mjs +118 -45
  35. package/dist/node/lib/A-ServerEntityList/A-EntityList.entity.mjs.map +1 -1
  36. package/dist/node/lib/A-ServerEntityList/A-EntityList.types.d.mts +14 -6
  37. package/dist/node/lib/A-ServerEntityList/A-EntityList.types.d.ts +14 -6
  38. package/dist/node/lib/A-ServerEntityList/A-EntityList.types.js.map +1 -1
  39. package/dist/node/lib/A-ServerEntityList/A-EntityList.types.mjs.map +1 -1
  40. package/dist/node/lib/A-ServerEntityList/A-EntityListCacheState.context.d.mts +12 -0
  41. package/dist/node/lib/A-ServerEntityList/A-EntityListCacheState.context.d.ts +12 -0
  42. package/dist/node/lib/A-ServerEntityList/A-EntityListCacheState.context.js +25 -0
  43. package/dist/node/lib/A-ServerEntityList/A-EntityListCacheState.context.js.map +1 -0
  44. package/dist/node/lib/A-ServerEntityList/A-EntityListCacheState.context.mjs +24 -0
  45. package/dist/node/lib/A-ServerEntityList/A-EntityListCacheState.context.mjs.map +1 -0
  46. package/dist/node/lib/A-ServerEntityList/A-EntityListPagination.context.d.mts +18 -0
  47. package/dist/node/lib/A-ServerEntityList/A-EntityListPagination.context.d.ts +18 -0
  48. package/dist/node/lib/A-ServerEntityList/A-EntityListPagination.context.js +48 -0
  49. package/dist/node/lib/A-ServerEntityList/A-EntityListPagination.context.js.map +1 -0
  50. package/dist/node/lib/A-ServerEntityList/A-EntityListPagination.context.mjs +47 -0
  51. package/dist/node/lib/A-ServerEntityList/A-EntityListPagination.context.mjs.map +1 -0
  52. package/dist/node/lib/A-ServerLogger/A-ServerLogger.component.d.mts +6 -8
  53. package/dist/node/lib/A-ServerLogger/A-ServerLogger.component.d.ts +6 -8
  54. package/dist/node/lib/A-ServerLogger/A-ServerLogger.component.js +3 -4
  55. package/dist/node/lib/A-ServerLogger/A-ServerLogger.component.js.map +1 -1
  56. package/dist/node/lib/A-ServerLogger/A-ServerLogger.component.mjs +4 -5
  57. package/dist/node/lib/A-ServerLogger/A-ServerLogger.component.mjs.map +1 -1
  58. package/dist/node/lib/A-ServerRouter/A-ServerRouter.component.d.mts +0 -2
  59. package/dist/node/lib/A-ServerRouter/A-ServerRouter.component.d.ts +0 -2
  60. package/dist/node/middlewares/A-ServerCORS/A_ServerCORS.component.js +1 -1
  61. package/dist/node/middlewares/A-ServerCORS/A_ServerCORS.component.js.map +1 -1
  62. package/dist/node/middlewares/A-ServerCORS/A_ServerCORS.component.mjs +1 -1
  63. package/dist/node/middlewares/A-ServerCORS/A_ServerCORS.component.mjs.map +1 -1
  64. package/dist/node/repositories/A-EntityRepository/A-EntityRepository.component.d.mts +1 -0
  65. package/dist/node/repositories/A-EntityRepository/A-EntityRepository.component.d.ts +1 -0
  66. package/examples/simple-server/components/Users.repository.ts +2 -2
  67. package/jest.config.ts +1 -0
  68. package/package.json +1 -1
  69. package/src/controllers/A-EntityController/A-EntityController.component.ts +69 -109
  70. package/src/controllers/A-ListingController/A-ListingController.component.ts +22 -20
  71. package/src/controllers/A-ServerHealthMonitor/A-ServerHealthMonitor.component.ts +11 -1
  72. package/src/index.ts +2 -0
  73. package/src/lib/A-ServerController/A-ServerController.component.ts +17 -8
  74. package/src/lib/A-ServerEntityList/A-EntityList.entity.ts +159 -55
  75. package/src/lib/A-ServerEntityList/A-EntityList.types.ts +17 -7
  76. package/src/lib/A-ServerEntityList/A-EntityListCacheState.context.ts +27 -0
  77. package/src/lib/A-ServerEntityList/A-EntityListPagination.context.ts +48 -0
  78. package/src/lib/A-ServerLogger/A-ServerLogger.component.ts +3 -4
  79. package/src/middlewares/A-ServerCORS/A_ServerCORS.component.ts +1 -1
  80. package/tests/A-Server-CORS.test.ts +542 -0
  81. package/tests/A-Server-Entity.test.ts +205 -0
  82. package/tests/A-Server-Health.test.ts +89 -0
  83. package/tests/A-Server-Routes.test.ts +113 -0
  84. package/tests/A-ServerEntityList.test.ts +416 -0
@@ -2,7 +2,7 @@ import { A_ExecutionContext } from '@adaas/a-utils/a-execution';
2
2
  import { IncomingMessage, ServerResponse, IncomingHttpHeaders, Server } from 'http';
3
3
  import { A_OperationContext, A_Operation_Storage } from '@adaas/a-utils/a-operation';
4
4
  import * as _adaas_a_concept from '@adaas/a-concept';
5
- import { A_TYPES__Error_Init, A_TYPES__Error_Serialized, A_TYPES__Entity_Serialized, A_Error, A_Entity, A_Fragment, A_TYPES__Required, A_Component, A_Scope, A_TYPES__Entity_Constructor, A_TYPES__ConceptENVVariables, A_Feature, A_TYPES__ComponentMeta, A_ComponentMeta, A_TYPES__MetaLinkedComponentConstructors } from '@adaas/a-concept';
5
+ import { A_TYPES__Error_Init, A_TYPES__Error_Serialized, A_TYPES__Entity_Serialized, A_Error, A_Entity, A_Scope, A_Fragment, A_TYPES__Required, A_Component, A_TYPES__Entity_Constructor, A_TYPES__Fragment_Serialized, A_TYPES__ConceptENVVariables, A_Feature, A_TYPES__ComponentMeta, A_ComponentMeta, A_TYPES__MetaLinkedComponentConstructors } from '@adaas/a-concept';
6
6
  import { A_Config } from '@adaas/a-utils/a-config';
7
7
  import { A_Route } from '@adaas/a-utils/a-route';
8
8
  import { Readable } from 'stream';
@@ -1200,44 +1200,11 @@ declare const A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES: {
1200
1200
  type A_TYPES__ServerENVVariables = (typeof A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES)[keyof typeof A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES][];
1201
1201
  declare const A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY: readonly ["A_SERVER_PORT"];
1202
1202
 
1203
- type A_SERVER_TYPES__ServerConstructor = {
1204
- name: string;
1205
- version: string;
1206
- routes: A_ServerRoute[];
1207
- port: number;
1208
- };
1209
- type A_SERVER_TYPES__ServerError_Init = {
1210
- /**
1211
- * HTTP Status Code of the error
1212
- */
1213
- status?: number;
1214
- } & A_TYPES__Error_Init;
1215
- type A_SERVER_TYPES__ServerError_Serialized = {
1216
- /**
1217
- * HTTP Status Code of the error
1218
- */
1219
- status: number;
1220
- } & A_TYPES__Error_Serialized;
1221
-
1222
- declare class A_Server extends A_Fragment {
1223
- port: number;
1224
- version: string;
1225
- protected _routes: A_ServerRoute[];
1226
- constructor(params: A_TYPES__Required<Partial<A_SERVER_TYPES__ServerConstructor>, [
1227
- 'port',
1228
- 'name'
1229
- ]>);
1230
- /**
1231
- * A list of routes that the server will listen to
1232
- */
1233
- get routes(): A_ServerRoute[];
1234
- }
1235
-
1236
1203
  declare class A_ServerLogger extends A_Logger {
1237
1204
  protected config: A_Config<any>;
1238
1205
  logRequestFinish(request: A_Request, response: A_Response, context: A_HttpServerRequestContext): void;
1239
1206
  logResponseError(request: A_Request, response: A_Response, context: A_HttpServerRequestContext, error: A_Error): void;
1240
- logStop(server: A_Server): void;
1207
+ logStop(scope: A_Scope): void;
1241
1208
  serverReady(params: {
1242
1209
  port: number;
1243
1210
  app: {
@@ -1277,6 +1244,39 @@ declare class A_HttpServer extends A_Service {
1277
1244
  handleRequest(request: IncomingMessage, response: ServerResponse): Promise<void>;
1278
1245
  }
1279
1246
 
1247
+ type A_SERVER_TYPES__ServerConstructor = {
1248
+ name: string;
1249
+ version: string;
1250
+ routes: A_ServerRoute[];
1251
+ port: number;
1252
+ };
1253
+ type A_SERVER_TYPES__ServerError_Init = {
1254
+ /**
1255
+ * HTTP Status Code of the error
1256
+ */
1257
+ status?: number;
1258
+ } & A_TYPES__Error_Init;
1259
+ type A_SERVER_TYPES__ServerError_Serialized = {
1260
+ /**
1261
+ * HTTP Status Code of the error
1262
+ */
1263
+ status: number;
1264
+ } & A_TYPES__Error_Serialized;
1265
+
1266
+ declare class A_Server extends A_Fragment {
1267
+ port: number;
1268
+ version: string;
1269
+ protected _routes: A_ServerRoute[];
1270
+ constructor(params: A_TYPES__Required<Partial<A_SERVER_TYPES__ServerConstructor>, [
1271
+ 'port',
1272
+ 'name'
1273
+ ]>);
1274
+ /**
1275
+ * A list of routes that the server will listen to
1276
+ */
1277
+ get routes(): A_ServerRoute[];
1278
+ }
1279
+
1280
1280
  declare class A_ServerError extends A_Error<A_SERVER_TYPES__ServerError_Init, A_SERVER_TYPES__ServerError_Serialized> {
1281
1281
  status: number;
1282
1282
  protected fromConstructor(params: A_SERVER_TYPES__ServerError_Init): void;
@@ -1290,10 +1290,14 @@ declare class A_ServerController extends A_Component {
1290
1290
  }>, response: A_Response, scope: A_Scope): Promise<void>;
1291
1291
  }
1292
1292
 
1293
- type A_SERVER_TYPES__A_EntityListConstructor = {
1294
- name: string;
1295
- scope: string;
1296
- constructor: A_TYPES__Entity_Constructor;
1293
+ type A_SERVER_TYPES__A_EntityListConstructor<T extends A_Entity = A_Entity> = {
1294
+ /** User-facing: the entity class (e.g. `User`). Name and scope are derived from its statics. */
1295
+ entity: A_TYPES__Entity_Constructor<T>;
1296
+ /** Initial pagination request parameters. Defaults to page 1, pageSize 10. */
1297
+ pagination?: {
1298
+ page?: number;
1299
+ pageSize?: number;
1300
+ };
1297
1301
  };
1298
1302
  declare enum A_SERVER_TYPES__A_EntityListEvent {
1299
1303
  Load = "load"
@@ -1308,52 +1312,102 @@ type A_SERVER_TYPES__A_EntityListPagination = {
1308
1312
  page: number;
1309
1313
  pageSize: number;
1310
1314
  };
1315
+ type A_SERVER_TYPES__A_EntityListCacheEntry = {
1316
+ timestamp: number;
1317
+ ttl: number;
1318
+ };
1319
+
1320
+ type A_SERVER_TYPES__A_EntityListPaginationSerialized = A_SERVER_TYPES__A_EntityListPagination & A_TYPES__Fragment_Serialized;
1321
+ declare class A_ServerEntityListPagination extends A_Fragment<A_SERVER_TYPES__A_EntityListPaginationSerialized> {
1322
+ protected _total: number;
1323
+ protected _page: number;
1324
+ protected _pageSize: number;
1325
+ constructor(init?: Partial<A_SERVER_TYPES__A_EntityListPagination>);
1326
+ get total(): number;
1327
+ get page(): number;
1328
+ get pageSize(): number;
1329
+ update(data: Partial<A_SERVER_TYPES__A_EntityListPagination>): void;
1330
+ fromJSON(serialized: A_SERVER_TYPES__A_EntityListPaginationSerialized): void;
1331
+ toJSON(): A_SERVER_TYPES__A_EntityListPaginationSerialized;
1332
+ }
1311
1333
 
1312
1334
  /**
1313
1335
  * A-EntityList
1314
1336
  *
1315
- * Entity that represents a list of entities with pagination of particular type
1337
+ * Typed, paginated list of A-Concept entities.
1338
+ *
1339
+ * Construction (user-facing):
1340
+ * new A_ServerEntityList<User>({ entity: User, pagination: { page: 1, pageSize: 20 } })
1341
+ *
1342
+ * Construction (controller-internal, backward-compat):
1343
+ * new A_ServerEntityList({ name: 'user', scope: 'my-scope', constructor: User })
1316
1344
  */
1317
- declare class A_ServerEntityList<EntityType extends A_Entity = A_Entity> extends A_Entity<A_SERVER_TYPES__A_EntityListConstructor, A_SERVER_TYPES__A_EntityListSerialized> {
1345
+ declare class A_ServerEntityList<EntityType extends A_Entity = A_Entity> extends A_Entity<A_SERVER_TYPES__A_EntityListConstructor<EntityType>, A_SERVER_TYPES__A_EntityListSerialized<EntityType>> {
1318
1346
  static get scope(): string;
1319
- protected _entityConstructor: new (...args: ConstructorParameters<typeof A_Entity>) => EntityType;
1320
- protected _items: Array<EntityType>;
1321
- protected _pagination: A_SERVER_TYPES__A_EntityListPagination;
1347
+ protected _entityConstructor: A_TYPES__Entity_Constructor<EntityType>;
1322
1348
  /**
1323
- * Returns the entity constructor used for the list
1349
+ * Ordered item references for O(1) positional access.
1350
+ * The list's own scope is the authoritative store (enables @A_Inject and
1351
+ * feature chains on items); this array mirrors the same items in order.
1324
1352
  */
1325
- get entityConstructor(): new (...args: ConstructorParameters<typeof A_Entity>) => EntityType;
1353
+ protected _items: Array<EntityType>;
1354
+ /** Lazily allocated private scope — pagination and cache state live here. */
1355
+ private _ownScope?;
1326
1356
  /**
1327
- * Returns the list of items contained in the entity list
1357
+ * The list's own scope, created on first access and bound to this entity
1358
+ * via A_Context.allocate. Items, pagination and cache state are registered
1359
+ * here so they participate in feature chains and @A_Inject resolution.
1328
1360
  */
1361
+ get ownScope(): A_Scope;
1362
+ get entityConstructor(): A_TYPES__Entity_Constructor<EntityType>;
1329
1363
  get items(): Array<EntityType>;
1364
+ /** Pagination state — lives as a Fragment in the list's own scope. */
1365
+ get pagination(): A_ServerEntityListPagination;
1366
+ private get cacheState();
1367
+ /** Total number of items currently held in memory. */
1368
+ get length(): number;
1369
+ fromNew(newEntity: A_SERVER_TYPES__A_EntityListConstructor<EntityType>): void;
1330
1370
  /**
1331
- * Returns pagination information about the entity list
1332
- */
1333
- get pagination(): A_SERVER_TYPES__A_EntityListPagination;
1334
- /**
1335
- * Creates a new instance of A_EntityList
1336
- *
1337
- * @param newEntity
1338
- */
1339
- fromNew(newEntity: A_SERVER_TYPES__A_EntityListConstructor): void;
1340
- /**
1341
- * Allows to convert Repository Response data to EntityList instance
1342
- *
1343
- * [!] This method does not load the data from the repository, it only converts the data to the EntityList instance
1344
- *
1345
- * @param items
1346
- * @param pagination
1371
+ * Populate the list from raw repository data.
1372
+ * Items are registered in the list's own scope so they participate in
1373
+ * feature chains and @A_Inject resolution.
1347
1374
  */
1348
1375
  fromList(items: Array<EntityType> | Array<ReturnType<EntityType['toJSON']>>, pagination?: A_SERVER_TYPES__A_EntityListPagination): void;
1349
- /**
1350
- * Serializes the EntityList to a JSON object
1351
- *
1352
- * @returns
1353
- */
1376
+ /** Return the item at `index`, or `undefined` if out of range. */
1377
+ at(index: number): EntityType | undefined;
1378
+ /** Replace the item at `index` in place. Accepts a live entity or a plain serialised object. */
1379
+ replace(index: number, item: EntityType | ReturnType<EntityType['toJSON']>): this;
1380
+ /** Append an item to the end of the list. */
1381
+ push(item: EntityType | ReturnType<EntityType['toJSON']>): this;
1382
+ /** Prepend an item to the beginning of the list. */
1383
+ unshift(item: EntityType | ReturnType<EntityType['toJSON']>): this;
1384
+ /** Remove the item at `index` from the list. */
1385
+ remove(index: number): this;
1386
+ /** Return the first item that satisfies `predicate`, or `undefined`. */
1387
+ find(predicate: (item: EntityType, index: number) => boolean): EntityType | undefined;
1388
+ /** Return all items that satisfy `predicate` without mutating the list. */
1389
+ filter(predicate: (item: EntityType, index: number) => boolean): EntityType[];
1390
+ /**
1391
+ * Mark this list as cached for `ttlMs` milliseconds from now.
1392
+ * Callers can check `isCached()` to decide whether to skip `load()`.
1393
+ */
1394
+ setCache(ttlMs: number): this;
1395
+ /** Returns `true` if the cache is still valid. */
1396
+ isCached(): boolean;
1397
+ /** Invalidate the cache so the next `load()` call fetches fresh data. */
1398
+ invalidateCache(): this;
1354
1399
  toJSON(): A_SERVER_TYPES__A_EntityListSerialized<EntityType>;
1355
1400
  }
1356
1401
 
1402
+ declare class A_ServerEntityListCacheState extends A_Fragment<A_TYPES__Fragment_Serialized> {
1403
+ protected _timestamp?: number;
1404
+ protected _ttl?: number;
1405
+ set(ttlMs: number): void;
1406
+ invalidate(): void;
1407
+ isValid(): boolean;
1408
+ toJSON(): A_TYPES__Fragment_Serialized;
1409
+ }
1410
+
1357
1411
  declare class A_ServerListQueryFilter<FilterFields extends string[]> extends A_Fragment {
1358
1412
  protected _query: string | Partial<Record<FilterFields[number], string>>;
1359
1413
  protected defaults: Partial<Record<FilterFields[number], string>>;
@@ -1696,4 +1750,4 @@ type A_SERVER_TYPES__StaticLoader_Init = {
1696
1750
  staticFilesPath: string;
1697
1751
  };
1698
1752
 
1699
- export { A_HttpRequestData, A_HttpServer, A_HttpServerError, type A_HttpServerError_Init, type A_HttpServerError_Serialized, type A_HttpServerFeatureNames, A_HttpServerFeatures, A_HttpServerRequestContext, type A_HttpServerRequestMethod, A_ProxyConfig, A_Request, A_RequestEnvVariables, A_RequestEnvVariablesArray, type A_RequestEnvVariablesType, A_RequestError, type A_RequestFeatureNames, A_RequestFeatures, A_RequestHelper, type A_Request_BodyType, A_Request_Event, type A_Request_EventCallback, type A_Request_FileUpload, type A_Request_Init, type A_Request_Listener, type A_Request_Methods, type A_Request_Options, type A_Request_ParsedBody, type A_Request_Serialized, type A_Request_SessionData, type A_Request_ValidationResult, A_Response, A_ResponseError, type A_ResponseFeatureNames, A_ResponseFeatures, type A_Response_CacheOptions, type A_Response_CompressionOptions, type A_Response_Constructor, type A_Response_CookieOptions, type A_Response_DownloadOptions, type A_Response_Listener, type A_Response_Options, type A_Response_SendResponseObject, type A_Response_Serialized, type A_Response_StreamOptions, A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES, A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY, type A_SERVER_TYPES__A_EntityListConstructor, A_SERVER_TYPES__A_EntityListEvent, type A_SERVER_TYPES__A_EntityListPagination, type A_SERVER_TYPES__A_EntityListSerialized, type A_SERVER_TYPES__ProxyConfigConstructor, type A_SERVER_TYPES__ProxyConfigConstructorConfig, type A_SERVER_TYPES__RoutesConfig, type A_SERVER_TYPES__ServerConstructor, type A_SERVER_TYPES__ServerError_Init, type A_SERVER_TYPES__ServerError_Serialized, type A_SERVER_TYPES__ServerLoggerEnvVariables, type A_SERVER_TYPES__ServerLoggerRouteParams, type A_SERVER_TYPES__StaticLoader_Init, A_SERVER__A_SERVER_LOGGER_ENV_VARIABLES, A_Server, A_ServerController, A_ServerEntityList, A_ServerError, A_ServerListQueryFilter, A_ServerLogger, A_ServerMiddleware, A_ServerProxy, A_ServerRoute, type A_ServerRouteHttpMethodNames, A_ServerRouteHttpMethods, A_ServerRouteProtocols, A_ServerRouter, A_ServerRouterDefineDecorator, A_ServerRouterMeta, type A_ServerRouterMetaKeyNames, A_ServerRouterMetaKeys, type A_ServerRouterMetaStructure, type A_ServerRouterRouteConfig, type A_ServerRouterRouteDefinition, type A_StaticAlias, A_StaticConfig, type A_StaticDirectoryConfig, A_StaticLoader, type A_TYPES__ServerENVVariables, type A_serverRouteProtocolNames, PROXY_CONFIG_DEFAULTS };
1753
+ export { A_HttpRequestData, A_HttpServer, A_HttpServerError, type A_HttpServerError_Init, type A_HttpServerError_Serialized, type A_HttpServerFeatureNames, A_HttpServerFeatures, A_HttpServerRequestContext, type A_HttpServerRequestMethod, A_ProxyConfig, A_Request, A_RequestEnvVariables, A_RequestEnvVariablesArray, type A_RequestEnvVariablesType, A_RequestError, type A_RequestFeatureNames, A_RequestFeatures, A_RequestHelper, type A_Request_BodyType, A_Request_Event, type A_Request_EventCallback, type A_Request_FileUpload, type A_Request_Init, type A_Request_Listener, type A_Request_Methods, type A_Request_Options, type A_Request_ParsedBody, type A_Request_Serialized, type A_Request_SessionData, type A_Request_ValidationResult, A_Response, A_ResponseError, type A_ResponseFeatureNames, A_ResponseFeatures, type A_Response_CacheOptions, type A_Response_CompressionOptions, type A_Response_Constructor, type A_Response_CookieOptions, type A_Response_DownloadOptions, type A_Response_Listener, type A_Response_Options, type A_Response_SendResponseObject, type A_Response_Serialized, type A_Response_StreamOptions, A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES, A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY, type A_SERVER_TYPES__A_EntityListCacheEntry, type A_SERVER_TYPES__A_EntityListConstructor, A_SERVER_TYPES__A_EntityListEvent, type A_SERVER_TYPES__A_EntityListPagination, type A_SERVER_TYPES__A_EntityListPaginationSerialized, type A_SERVER_TYPES__A_EntityListSerialized, type A_SERVER_TYPES__ProxyConfigConstructor, type A_SERVER_TYPES__ProxyConfigConstructorConfig, type A_SERVER_TYPES__RoutesConfig, type A_SERVER_TYPES__ServerConstructor, type A_SERVER_TYPES__ServerError_Init, type A_SERVER_TYPES__ServerError_Serialized, type A_SERVER_TYPES__ServerLoggerEnvVariables, type A_SERVER_TYPES__ServerLoggerRouteParams, type A_SERVER_TYPES__StaticLoader_Init, A_SERVER__A_SERVER_LOGGER_ENV_VARIABLES, A_Server, A_ServerController, A_ServerEntityList, A_ServerEntityListCacheState, A_ServerEntityListPagination, A_ServerError, A_ServerListQueryFilter, A_ServerLogger, A_ServerMiddleware, A_ServerProxy, A_ServerRoute, type A_ServerRouteHttpMethodNames, A_ServerRouteHttpMethods, A_ServerRouteProtocols, A_ServerRouter, A_ServerRouterDefineDecorator, A_ServerRouterMeta, type A_ServerRouterMetaKeyNames, A_ServerRouterMetaKeys, type A_ServerRouterMetaStructure, type A_ServerRouterRouteConfig, type A_ServerRouterRouteDefinition, type A_StaticAlias, A_StaticConfig, type A_StaticDirectoryConfig, A_StaticLoader, type A_TYPES__ServerENVVariables, type A_serverRouteProtocolNames, PROXY_CONFIG_DEFAULTS };
@@ -1,5 +1,5 @@
1
1
  import { A_ExecutionContext } from '@adaas/a-utils/a-execution';
2
- import { A_Feature, A_Inject, A_Error, A_IdentityHelper, A_Scope, A_Dependency, A_Concept, A_Meta, A_Entity, ASEID, A_Context, A_Fragment, A_ComponentMeta, A_Component, A_TypeGuards, A_Feature_Define, A_Feature_Extend, A_Container } from '@adaas/a-concept';
2
+ import { A_Feature, A_Inject, A_Error, A_Scope, A_IdentityHelper, A_Dependency, A_Concept, A_Meta, A_Entity, ASEID, A_Context, A_ComponentMeta, A_Component, A_TypeGuards, A_Fragment, A_Feature_Define, A_Feature_Extend, A_Container } from '@adaas/a-concept';
3
3
  import { A_OperationContext } from '@adaas/a-utils/a-operation';
4
4
  import { A_ScheduleObject } from '@adaas/a-utils/a-schedule';
5
5
  import { A_Config } from '@adaas/a-utils/a-config';
@@ -1696,22 +1696,6 @@ var A_ServerRoute = class extends A_Route {
1696
1696
  return new RegExp(`^${extensionScope.length ? `(${extensionScope.join("|")})` : ".*"}\\.${this.method}::${this.path.replace(/\/:([^\/]+)/g, "/([^/]+)")}$`);
1697
1697
  }
1698
1698
  };
1699
- var A_Server = class extends A_Fragment {
1700
- constructor(params) {
1701
- super(params);
1702
- this._routes = [];
1703
- this.port = params.port;
1704
- this._name = params.name;
1705
- this.version = params.version || "v1";
1706
- this._routes = params.routes || this._routes;
1707
- }
1708
- /**
1709
- * A list of routes that the server will listen to
1710
- */
1711
- get routes() {
1712
- return this._routes;
1713
- }
1714
- };
1715
1699
  var A_ServerLogger = class extends A_Logger {
1716
1700
  logRequestFinish(request, response, context) {
1717
1701
  this.info("green", `Request ${request.method} ${request.url} finished with status ${response.statusCode} in ${context.processingTime ?? "N/A"}ms`);
@@ -1720,8 +1704,8 @@ var A_ServerLogger = class extends A_Logger {
1720
1704
  this.info("red", `Request ${request.method} ${request.url} errored with status ${response.statusCode} in ${context.processingTime ?? "N/A"}ms`);
1721
1705
  this.error(error);
1722
1706
  }
1723
- logStop(server) {
1724
- this.log("red", `Server ${server.name} stopped`);
1707
+ logStop(scope) {
1708
+ this.info("red", `Server ${scope.name} stopped`);
1725
1709
  }
1726
1710
  serverReady(params) {
1727
1711
  const processId = process.pid;
@@ -1772,7 +1756,7 @@ __decorateClass([
1772
1756
  name: A_ServiceFeatures.onAfterStop,
1773
1757
  scope: [A_Service]
1774
1758
  }),
1775
- __decorateParam(0, A_Inject(A_Server))
1759
+ __decorateParam(0, A_Inject(A_Scope))
1776
1760
  ], A_ServerLogger.prototype, "logStop", 1);
1777
1761
  var _a3, _b3, _c3, _d2, _e2;
1778
1762
  var _A_HttpServer = class _A_HttpServer extends A_Service {
@@ -1961,6 +1945,22 @@ __decorateClass([
1961
1945
  A_Feature.Extend()
1962
1946
  ], _A_HttpServer.prototype, _a3, 1);
1963
1947
  var A_HttpServer = _A_HttpServer;
1948
+ var A_Server = class extends A_Fragment {
1949
+ constructor(params) {
1950
+ super(params);
1951
+ this._routes = [];
1952
+ this.port = params.port;
1953
+ this._name = params.name;
1954
+ this.version = params.version || "v1";
1955
+ this._routes = params.routes || this._routes;
1956
+ }
1957
+ /**
1958
+ * A list of routes that the server will listen to
1959
+ */
1960
+ get routes() {
1961
+ return this._routes;
1962
+ }
1963
+ };
1964
1964
  var A_ServerError = class extends A_Error {
1965
1965
  constructor() {
1966
1966
  super(...arguments);
@@ -2227,17 +2227,29 @@ A_ServerRouter = __decorateClass([
2227
2227
  var A_ServerController = class extends A_Component {
2228
2228
  async callEntityMethod(request, response, scope) {
2229
2229
  if (!scope.has(request.params.component))
2230
- return;
2230
+ throw new A_HttpServerError({
2231
+ status: 404,
2232
+ description: `Component "${request.params.component}" not found`
2233
+ });
2231
2234
  if (!request.params.operation || typeof request.params.operation !== "string")
2232
- return;
2235
+ throw new A_HttpServerError({
2236
+ status: 400,
2237
+ description: 'Missing or invalid "operation" parameter'
2238
+ });
2233
2239
  const possibleComponent = scope.resolve(request.params.component);
2234
2240
  if (!possibleComponent || ![A_Component, A_Container].some((c) => possibleComponent instanceof c))
2235
- return;
2241
+ throw new A_HttpServerError({
2242
+ status: 404,
2243
+ description: `"${request.params.component}" is not a valid component`
2244
+ });
2236
2245
  const component = possibleComponent;
2237
2246
  const meta = A_Context.meta(component);
2238
2247
  const targetFeature = meta.features().find((f) => f.name === `${component.constructor.name}.${request.params.operation}`);
2239
2248
  if (!targetFeature)
2240
- return;
2249
+ throw new A_HttpServerError({
2250
+ status: 404,
2251
+ description: `Operation "${request.params.operation}" not found on component "${request.params.component}"`
2252
+ });
2241
2253
  await component.call(request.params.operation, scope);
2242
2254
  }
2243
2255
  };
@@ -2251,86 +2263,216 @@ __decorateClass([
2251
2263
  __decorateParam(1, A_Inject(A_Response)),
2252
2264
  __decorateParam(2, A_Inject(A_Scope))
2253
2265
  ], A_ServerController.prototype, "callEntityMethod", 1);
2266
+ var A_ServerEntityListPagination = class extends A_Fragment {
2267
+ constructor(init) {
2268
+ super();
2269
+ this._total = 0;
2270
+ this._page = 1;
2271
+ this._pageSize = 10;
2272
+ if (init) {
2273
+ if (init.total !== void 0) this._total = init.total;
2274
+ if (init.page !== void 0) this._page = init.page;
2275
+ if (init.pageSize !== void 0) this._pageSize = init.pageSize;
2276
+ }
2277
+ }
2278
+ get total() {
2279
+ return this._total;
2280
+ }
2281
+ get page() {
2282
+ return this._page;
2283
+ }
2284
+ get pageSize() {
2285
+ return this._pageSize;
2286
+ }
2287
+ update(data) {
2288
+ if (data.total !== void 0) this._total = data.total;
2289
+ if (data.page !== void 0) this._page = data.page;
2290
+ if (data.pageSize !== void 0) this._pageSize = data.pageSize;
2291
+ }
2292
+ fromJSON(serialized) {
2293
+ this._total = serialized.total;
2294
+ this._page = serialized.page;
2295
+ this._pageSize = serialized.pageSize;
2296
+ }
2297
+ toJSON() {
2298
+ return {
2299
+ name: this.name,
2300
+ total: this._total,
2301
+ page: this._page,
2302
+ pageSize: this._pageSize
2303
+ };
2304
+ }
2305
+ };
2306
+ var A_ServerEntityListCacheState = class extends A_Fragment {
2307
+ set(ttlMs) {
2308
+ this._timestamp = Date.now();
2309
+ this._ttl = ttlMs;
2310
+ }
2311
+ invalidate() {
2312
+ this._timestamp = void 0;
2313
+ this._ttl = void 0;
2314
+ }
2315
+ isValid() {
2316
+ if (this._timestamp === void 0 || this._ttl === void 0) return false;
2317
+ return Date.now() - this._timestamp < this._ttl;
2318
+ }
2319
+ toJSON() {
2320
+ return { name: this.name };
2321
+ }
2322
+ };
2323
+
2324
+ // src/lib/A-ServerEntityList/A-EntityList.entity.ts
2254
2325
  var A_ServerEntityList = class extends A_Entity {
2255
2326
  constructor() {
2256
2327
  super(...arguments);
2328
+ /**
2329
+ * Ordered item references for O(1) positional access.
2330
+ * The list's own scope is the authoritative store (enables @A_Inject and
2331
+ * feature chains on items); this array mirrors the same items in order.
2332
+ */
2257
2333
  this._items = [];
2258
- this._pagination = {
2259
- total: 0,
2260
- page: 1,
2261
- pageSize: 10
2262
- };
2263
2334
  }
2264
2335
  static get scope() {
2265
2336
  return "a-server";
2266
2337
  }
2338
+ // ── Getters ──────────────────────────────────────────────────────────────
2267
2339
  /**
2268
- * Returns the entity constructor used for the list
2340
+ * The list's own scope, created on first access and bound to this entity
2341
+ * via A_Context.allocate. Items, pagination and cache state are registered
2342
+ * here so they participate in feature chains and @A_Inject resolution.
2269
2343
  */
2344
+ get ownScope() {
2345
+ if (!this._ownScope) {
2346
+ this._ownScope = A_Context.allocate(
2347
+ this,
2348
+ new A_Scope({ name: `${this.aseid.id}-scope` })
2349
+ );
2350
+ }
2351
+ return this._ownScope;
2352
+ }
2270
2353
  get entityConstructor() {
2271
2354
  return this._entityConstructor;
2272
2355
  }
2273
- /**
2274
- * Returns the list of items contained in the entity list
2275
- */
2276
2356
  get items() {
2277
2357
  return this._items;
2278
2358
  }
2279
- /**
2280
- * Returns pagination information about the entity list
2281
- */
2359
+ /** Pagination state — lives as a Fragment in the list's own scope. */
2282
2360
  get pagination() {
2283
- return this._pagination;
2361
+ return this.ownScope.resolveFlatOnce(A_ServerEntityListPagination);
2284
2362
  }
2285
- /**
2286
- * Creates a new instance of A_EntityList
2287
- *
2288
- * @param newEntity
2289
- */
2363
+ get cacheState() {
2364
+ return this.ownScope.resolveFlatOnce(A_ServerEntityListCacheState);
2365
+ }
2366
+ /** Total number of items currently held in memory. */
2367
+ get length() {
2368
+ return this._items.length;
2369
+ }
2370
+ // ── Initialisation ───────────────────────────────────────────────────────
2290
2371
  fromNew(newEntity) {
2291
- this.aseid = new ASEID({
2372
+ this.aseid = this.generateASEID({
2292
2373
  concept: A_Context.root.name,
2293
- scope: "default",
2294
- entity: "a-list" + (newEntity.name ? `.${newEntity.name}` : ""),
2295
- id: (/* @__PURE__ */ new Date()).getTime().toString()
2374
+ entity: "a-list." + newEntity.entity.name
2296
2375
  });
2297
- this._entityConstructor = newEntity.constructor;
2376
+ this._entityConstructor = newEntity.entity;
2377
+ this.ownScope.register(new A_ServerEntityListPagination(newEntity.pagination));
2378
+ this.ownScope.register(new A_ServerEntityListCacheState());
2298
2379
  }
2299
2380
  /**
2300
- * Allows to convert Repository Response data to EntityList instance
2301
- *
2302
- * [!] This method does not load the data from the repository, it only converts the data to the EntityList instance
2303
- *
2304
- * @param items
2305
- * @param pagination
2381
+ * Populate the list from raw repository data.
2382
+ * Items are registered in the list's own scope so they participate in
2383
+ * feature chains and @A_Inject resolution.
2306
2384
  */
2307
2385
  fromList(items, pagination) {
2308
- this._items = items.map((item) => {
2309
- if (item instanceof A_Entity) {
2310
- return item;
2311
- } else {
2312
- const entity = new this._entityConstructor(item);
2313
- return entity;
2386
+ this._items.forEach((item) => {
2387
+ try {
2388
+ this.ownScope.deregister(item);
2389
+ } catch {
2314
2390
  }
2315
2391
  });
2392
+ this._items = items.map((item) => {
2393
+ const entity = item instanceof A_Entity ? item : new this._entityConstructor(item);
2394
+ this.ownScope.register(entity);
2395
+ return entity;
2396
+ });
2316
2397
  if (pagination) {
2317
- this._pagination = {
2318
- total: pagination.total,
2319
- page: pagination.page,
2320
- pageSize: pagination.pageSize
2321
- };
2398
+ this.pagination.update(pagination);
2322
2399
  }
2323
2400
  }
2401
+ // ── Collection access ────────────────────────────────────────────────────
2402
+ /** Return the item at `index`, or `undefined` if out of range. */
2403
+ at(index) {
2404
+ return this._items[index];
2405
+ }
2406
+ /** Replace the item at `index` in place. Accepts a live entity or a plain serialised object. */
2407
+ replace(index, item) {
2408
+ const next = item instanceof A_Entity ? item : new this._entityConstructor(item);
2409
+ try {
2410
+ this.ownScope.deregister(this._items[index]);
2411
+ } catch {
2412
+ }
2413
+ this.ownScope.register(next);
2414
+ this._items[index] = next;
2415
+ return this;
2416
+ }
2417
+ /** Append an item to the end of the list. */
2418
+ push(item) {
2419
+ const next = item instanceof A_Entity ? item : new this._entityConstructor(item);
2420
+ this.ownScope.register(next);
2421
+ this._items.push(next);
2422
+ return this;
2423
+ }
2424
+ /** Prepend an item to the beginning of the list. */
2425
+ unshift(item) {
2426
+ const next = item instanceof A_Entity ? item : new this._entityConstructor(item);
2427
+ this.ownScope.register(next);
2428
+ this._items.unshift(next);
2429
+ return this;
2430
+ }
2431
+ /** Remove the item at `index` from the list. */
2432
+ remove(index) {
2433
+ const [removed] = this._items.splice(index, 1);
2434
+ if (removed) {
2435
+ try {
2436
+ this.ownScope.deregister(removed);
2437
+ } catch {
2438
+ }
2439
+ }
2440
+ return this;
2441
+ }
2442
+ /** Return the first item that satisfies `predicate`, or `undefined`. */
2443
+ find(predicate) {
2444
+ return this._items.find(predicate);
2445
+ }
2446
+ /** Return all items that satisfy `predicate` without mutating the list. */
2447
+ filter(predicate) {
2448
+ return this._items.filter(predicate);
2449
+ }
2450
+ // ── Caching ──────────────────────────────────────────────────────────────
2324
2451
  /**
2325
- * Serializes the EntityList to a JSON object
2326
- *
2327
- * @returns
2452
+ * Mark this list as cached for `ttlMs` milliseconds from now.
2453
+ * Callers can check `isCached()` to decide whether to skip `load()`.
2328
2454
  */
2455
+ setCache(ttlMs) {
2456
+ this.cacheState.set(ttlMs);
2457
+ return this;
2458
+ }
2459
+ /** Returns `true` if the cache is still valid. */
2460
+ isCached() {
2461
+ return this.cacheState.isValid();
2462
+ }
2463
+ /** Invalidate the cache so the next `load()` call fetches fresh data. */
2464
+ invalidateCache() {
2465
+ this.cacheState.invalidate();
2466
+ return this;
2467
+ }
2468
+ // ── Serialisation ────────────────────────────────────────────────────────
2329
2469
  toJSON() {
2470
+ const { total, page, pageSize } = this.pagination;
2330
2471
  return {
2331
2472
  ...super.toJSON(),
2332
2473
  items: this._items.map((i) => i.toJSON()),
2333
- pagination: this._pagination
2474
+ type: this._entityConstructor.entity ?? "unknown",
2475
+ pagination: { total, page, pageSize }
2334
2476
  };
2335
2477
  }
2336
2478
  };
@@ -2953,6 +3095,6 @@ var A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY = [
2953
3095
  A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES.A_SERVER_PORT
2954
3096
  ];
2955
3097
 
2956
- export { A_HttpRequestData, A_HttpServer, A_HttpServerError, A_HttpServerFeatures, A_HttpServerRequestContext, A_ProxyConfig, A_Request, A_RequestEnvVariables, A_RequestEnvVariablesArray, A_RequestError, A_RequestFeatures, A_RequestHelper, A_Request_Event, A_Response, A_ResponseError, A_ResponseFeatures, A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES, A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY, A_SERVER_TYPES__A_EntityListEvent, A_SERVER__A_SERVER_LOGGER_ENV_VARIABLES, A_Server, A_ServerController, A_ServerEntityList, A_ServerError, A_ServerListQueryFilter, A_ServerLogger, A_ServerMiddleware, A_ServerProxy, A_ServerRoute, A_ServerRouteHttpMethods, A_ServerRouteProtocols, A_ServerRouter, A_ServerRouterDefineDecorator, A_ServerRouterMeta, A_ServerRouterMetaKeys, A_StaticConfig, A_StaticLoader, PROXY_CONFIG_DEFAULTS };
3098
+ export { A_HttpRequestData, A_HttpServer, A_HttpServerError, A_HttpServerFeatures, A_HttpServerRequestContext, A_ProxyConfig, A_Request, A_RequestEnvVariables, A_RequestEnvVariablesArray, A_RequestError, A_RequestFeatures, A_RequestHelper, A_Request_Event, A_Response, A_ResponseError, A_ResponseFeatures, A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES, A_SERVER_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY, A_SERVER_TYPES__A_EntityListEvent, A_SERVER__A_SERVER_LOGGER_ENV_VARIABLES, A_Server, A_ServerController, A_ServerEntityList, A_ServerEntityListCacheState, A_ServerEntityListPagination, A_ServerError, A_ServerListQueryFilter, A_ServerLogger, A_ServerMiddleware, A_ServerProxy, A_ServerRoute, A_ServerRouteHttpMethods, A_ServerRouteProtocols, A_ServerRouter, A_ServerRouterDefineDecorator, A_ServerRouterMeta, A_ServerRouterMetaKeys, A_StaticConfig, A_StaticLoader, PROXY_CONFIG_DEFAULTS };
2957
3099
  //# sourceMappingURL=index.mjs.map
2958
3100
  //# sourceMappingURL=index.mjs.map