@solidxai/core 0.1.11-beta.0 → 0.1.11-beta.2

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 (66) hide show
  1. package/CLAUDE.md +26 -0
  2. package/dist/controllers/service.controller.d.ts +1 -0
  3. package/dist/controllers/service.controller.d.ts.map +1 -1
  4. package/dist/controllers/service.controller.js +2 -2
  5. package/dist/controllers/service.controller.js.map +1 -1
  6. package/dist/helpers/field-crud-managers/IntFieldCrudManager.d.ts.map +1 -1
  7. package/dist/helpers/field-crud-managers/IntFieldCrudManager.js +4 -1
  8. package/dist/helpers/field-crud-managers/IntFieldCrudManager.js.map +1 -1
  9. package/dist/helpers/solid-registry.d.ts +2 -1
  10. package/dist/helpers/solid-registry.d.ts.map +1 -1
  11. package/dist/helpers/solid-registry.js.map +1 -1
  12. package/dist/repository/scheduled-job.repository.d.ts +3 -0
  13. package/dist/repository/scheduled-job.repository.d.ts.map +1 -1
  14. package/dist/repository/scheduled-job.repository.js +60 -0
  15. package/dist/repository/scheduled-job.repository.js.map +1 -1
  16. package/dist/seeders/module-metadata-seeder.service.d.ts +37 -2
  17. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  18. package/dist/seeders/module-metadata-seeder.service.js +1071 -232
  19. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  20. package/dist/seeders/seed-data/solid-core-metadata.json +7 -0
  21. package/dist/services/action-metadata.service.d.ts +7 -0
  22. package/dist/services/action-metadata.service.d.ts.map +1 -1
  23. package/dist/services/action-metadata.service.js +76 -3
  24. package/dist/services/action-metadata.service.js.map +1 -1
  25. package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.d.ts.map +1 -1
  26. package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js +6 -5
  27. package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js.map +1 -1
  28. package/dist/services/locale.service.d.ts +14 -0
  29. package/dist/services/locale.service.d.ts.map +1 -1
  30. package/dist/services/locale.service.js +83 -0
  31. package/dist/services/locale.service.js.map +1 -1
  32. package/dist/services/role-metadata.service.d.ts +5 -0
  33. package/dist/services/role-metadata.service.d.ts.map +1 -1
  34. package/dist/services/role-metadata.service.js +95 -33
  35. package/dist/services/role-metadata.service.js.map +1 -1
  36. package/dist/services/view-metadata.service.d.ts +6 -0
  37. package/dist/services/view-metadata.service.d.ts.map +1 -1
  38. package/dist/services/view-metadata.service.js +70 -8
  39. package/dist/services/view-metadata.service.js.map +1 -1
  40. package/dist/subscribers/audit.subscriber.d.ts +2 -0
  41. package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
  42. package/dist/subscribers/audit.subscriber.js +25 -6
  43. package/dist/subscribers/audit.subscriber.js.map +1 -1
  44. package/dist/subscribers/computed-entity-field.subscriber.d.ts.map +1 -1
  45. package/dist/subscribers/computed-entity-field.subscriber.js +1 -0
  46. package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
  47. package/dist/subscribers/created-by-updated-by.subscriber.d.ts.map +1 -1
  48. package/dist/subscribers/created-by-updated-by.subscriber.js.map +1 -1
  49. package/dist/subscribers/field-metadata.subscriber.d.ts.map +1 -1
  50. package/dist/subscribers/field-metadata.subscriber.js.map +1 -1
  51. package/package.json +1 -1
  52. package/src/controllers/service.controller.ts +3 -2
  53. package/src/helpers/field-crud-managers/IntFieldCrudManager.ts +4 -1
  54. package/src/helpers/solid-registry.ts +7 -1
  55. package/src/repository/scheduled-job.repository.ts +73 -0
  56. package/src/seeders/module-metadata-seeder.service.ts +1295 -264
  57. package/src/seeders/seed-data/solid-core-metadata.json +7 -0
  58. package/src/services/action-metadata.service.ts +87 -2
  59. package/src/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.ts +10 -5
  60. package/src/services/locale.service.ts +111 -3
  61. package/src/services/role-metadata.service.ts +112 -49
  62. package/src/services/view-metadata.service.ts +83 -9
  63. package/src/subscribers/audit.subscriber.ts +34 -14
  64. package/src/subscribers/computed-entity-field.subscriber.ts +1 -0
  65. package/src/subscribers/created-by-updated-by.subscriber.ts +3 -0
  66. package/src/subscribers/field-metadata.subscriber.ts +3 -0
@@ -84,24 +84,44 @@ export class AuditSubscriber implements EntitySubscriberInterface {
84
84
  const batch = this.perTxn.get(event.queryRunner) ?? [];
85
85
  this.perTxn.delete(event.queryRunner);
86
86
 
87
- // Now outside the DB transaction — safe to publish to the queue.
88
- // allSettled: publish in parallel; a single failure does not block the rest.
89
- const results = await Promise.allSettled(
90
- batch.map(payload => this.publisherFactory.publish({ payload }, 'ChatterQueuePublisher'))
91
- );
92
-
93
- results.forEach((result, i) => {
94
- if (result.status === 'rejected') {
95
- this.logger.error(
96
- `Failed to publish audit event for ${batch[i].modelName}#${batch[i].entityId}`,
97
- result.reason,
98
- );
99
- }
100
- });
87
+ if (batch.length === 0) return;
88
+
89
+ if (this.shouldDeferAuditPublish()) {
90
+ setImmediate(() => void this.publishAuditBatch(batch));
91
+ return;
92
+ }
93
+
94
+ await this.publishAuditBatch(batch);
101
95
  }
102
96
 
103
97
  afterTransactionRollback(event: { queryRunner: any }) {
104
98
  // Drop buffered payloads; the write never happened.
105
99
  this.perTxn.delete(event.queryRunner);
106
100
  }
101
+
102
+ private shouldDeferAuditPublish(): boolean {
103
+ const driver = (process.env.DEFAULT_DATABASE_DRIVER ?? '').toLowerCase();
104
+ const poolMax = Number(process.env.DEFAULT_DATABASE_POOL_MAX ?? 20);
105
+ return driver === 'pglite' && Number.isFinite(poolMax) && poolMax <= 1;
106
+ }
107
+
108
+ private async publishAuditBatch(batch: AuditQueuePayload[]) {
109
+ try {
110
+ // allSettled: publish in parallel; a single failure does not block the rest.
111
+ const results = await Promise.allSettled(
112
+ batch.map(payload => this.publisherFactory.publish({ payload }, 'ChatterQueuePublisher'))
113
+ );
114
+
115
+ results.forEach((result, i) => {
116
+ if (result.status === 'rejected') {
117
+ this.logger.error(
118
+ `Failed to publish audit event for ${batch[i].modelName}#${batch[i].entityId}`,
119
+ result.reason,
120
+ );
121
+ }
122
+ });
123
+ } catch (error) {
124
+ this.logger.error('Failed to publish audit batch', error);
125
+ }
126
+ }
107
127
  }
@@ -175,6 +175,7 @@ export class ComputedEntityFieldSubscriber implements EntitySubscriberInterface
175
175
  const base: TypeOrmEventContext = {
176
176
  metadataName: event.metadata?.name,
177
177
  eventType: eventType,
178
+ manager: event.manager,
178
179
  };
179
180
  if ("entityId" in event && event.entityId) {
180
181
  base.entityId = event.entityId;
@@ -38,6 +38,9 @@ export class CreatedByUpdatedBySubscriber implements EntitySubscriberInterface {
38
38
  return;
39
39
  }
40
40
 
41
+ // NOTE: If re-enabling loadUser below, query via `event.queryRunner.manager`, NOT
42
+ // `this.defaultDataSource.getRepository(...)`. A second connection opened mid-transaction
43
+ // deadlocks single-threaded engines (PGlite).
41
44
  // const loadedUser = await this.loadUser(activeUserOrUndefined as unknown as ActiveUserData);
42
45
  // if (isInsert) {
43
46
  // event.entity.createdBy = loadedUser?.id;
@@ -21,6 +21,9 @@ export class FieldMetadataSubscriber implements EntitySubscriberInterface<FieldM
21
21
  }
22
22
 
23
23
  async afterUpdate(event: UpdateEvent<FieldMetadata>): Promise<void> {
24
+ // NOTE: If re-enabling the block below, use `event.queryRunner.manager` (the active
25
+ // transaction's connection), NOT `this.dataSource.getRepository(...)`. A second
26
+ // connection opened here mid-transaction deadlocks single-threaded engines (PGlite).
24
27
  // If a field of type relation.many-to-one is marked for removal, and this field had an inverse relation created
25
28
  // It means there is a field of type relation.one-to-many in the co-model, which needs to be removed
26
29
  // if (event.entity && event.entity.isMarkedForRemoval && event.entity.type === 'relation' && event.entity.relationType === 'many-to-one' && event.entity.relationCreateInverse === true) {