@igniter-js/jobs 0.1.14 → 0.1.15

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/index.mjs CHANGED
@@ -144,6 +144,11 @@ var _IgniterJobsPrefix = class _IgniterJobsPrefix {
144
144
  if (!params.scope) return base;
145
145
  return `${base}:scope:${params.scope.type}:${params.scope.id}`;
146
146
  }
147
+ static buildJobStreamChannel(params) {
148
+ const base = `${_IgniterJobsPrefix.BASE_PREFIX}:stream:${params.environment}:${params.service}:${params.queue}:${params.jobId}`;
149
+ if (!params.scope) return base;
150
+ return `${base}:scope:${params.scope.type}:${params.scope.id}`;
151
+ }
147
152
  };
148
153
  _IgniterJobsPrefix.BASE_PREFIX = "igniter:jobs";
149
154
  var IgniterJobsPrefix = _IgniterJobsPrefix;
@@ -545,7 +550,8 @@ var IgniterJobsManager = class _IgniterJobsManager {
545
550
  },
546
551
  state: () => self.adapter.getJobState(id, queueName),
547
552
  progress: () => self.adapter.getJobProgress(id, queueName),
548
- logs: () => self.adapter.getJobLogs(id, queueName)
553
+ logs: () => self.adapter.getJobLogs(id, queueName),
554
+ stream: () => self.createJobStreamAccessor(queueName, jobName, id)
549
555
  };
550
556
  },
551
557
  many(ids) {
@@ -878,10 +884,18 @@ var IgniterJobsManager = class _IgniterJobsManager {
878
884
  async buildExecutionContext(ctx, queueName, jobName) {
879
885
  const realContext = await this.config.contextFactory();
880
886
  const scope = ctx.scope ?? IgniterJobsScopeUtils.extractScopeFromMetadata(ctx.job.metadata);
887
+ const definition = this.getJobDefinition(queueName, jobName);
888
+ const stream = this.createExecutionStreamEmitter(
889
+ queueName,
890
+ jobName,
891
+ ctx.job.id,
892
+ scope,
893
+ definition
894
+ );
881
895
  return {
882
896
  ...ctx,
883
897
  context: realContext,
884
- job: { ...ctx.job, name: jobName, queue: queueName },
898
+ job: { ...ctx.job, name: jobName, queue: queueName, stream },
885
899
  scope
886
900
  };
887
901
  }
@@ -919,6 +933,115 @@ var IgniterJobsManager = class _IgniterJobsManager {
919
933
  name: jobName
920
934
  };
921
935
  }
936
+ createExecutionStreamEmitter(queueName, jobName, jobId, scope, definition) {
937
+ return {
938
+ emit: async (type, data) => {
939
+ const payload = await this.normalizeStreamEmitPayload(
940
+ queueName,
941
+ jobName,
942
+ type,
943
+ data,
944
+ definition
945
+ );
946
+ return this.adapter.writeJobStreamEvent({
947
+ queue: queueName,
948
+ jobName,
949
+ jobId,
950
+ scope,
951
+ persistence: definition?.stream?.persistence,
952
+ event: {
953
+ type,
954
+ data: payload,
955
+ timestamp: /* @__PURE__ */ new Date(),
956
+ jobId,
957
+ jobName,
958
+ queue: queueName,
959
+ scope
960
+ }
961
+ });
962
+ }
963
+ };
964
+ }
965
+ createJobStreamAccessor(queueName, jobName, jobId) {
966
+ const definition = this.getJobDefinition(queueName, jobName);
967
+ return {
968
+ subscribe: async (handler) => {
969
+ return this.adapter.subscribeJobStream({
970
+ queue: queueName,
971
+ jobId,
972
+ handler: async (event) => {
973
+ const normalized = await this.normalizeStreamReadEvent(
974
+ queueName,
975
+ jobName,
976
+ event,
977
+ definition
978
+ );
979
+ await handler(normalized);
980
+ }
981
+ });
982
+ },
983
+ read: async ({
984
+ after,
985
+ limit
986
+ } = {}) => {
987
+ if (!definition?.stream?.persistence?.enabled) {
988
+ return {
989
+ items: [],
990
+ nextCursor: void 0,
991
+ hasMore: false
992
+ };
993
+ }
994
+ const result = await this.adapter.readJobStream({
995
+ queue: queueName,
996
+ jobId,
997
+ after,
998
+ limit
999
+ });
1000
+ return {
1001
+ ...result,
1002
+ items: await Promise.all(
1003
+ result.items.map(
1004
+ (event) => this.normalizeStreamReadEvent(
1005
+ queueName,
1006
+ jobName,
1007
+ event,
1008
+ definition
1009
+ )
1010
+ )
1011
+ )
1012
+ };
1013
+ }
1014
+ };
1015
+ }
1016
+ async normalizeStreamEmitPayload(queueName, jobName, type, data, definition) {
1017
+ const schema = this.getJobStreamSchema(definition, type);
1018
+ if (!schema) return data;
1019
+ return IgniterJobsValidationUtils.validateInput(schema, data);
1020
+ }
1021
+ async normalizeStreamReadEvent(queueName, jobName, event, definition) {
1022
+ const schema = this.getJobStreamSchema(definition, event.type);
1023
+ if (!schema) return event;
1024
+ const normalized = await IgniterJobsValidationUtils.validateInput(
1025
+ schema,
1026
+ event.data
1027
+ );
1028
+ return {
1029
+ ...event,
1030
+ data: normalized
1031
+ };
1032
+ }
1033
+ getJobStreamSchema(definition, type) {
1034
+ const events = definition?.stream?.events;
1035
+ if (!events) return void 0;
1036
+ const schema = events[type];
1037
+ if (!schema) {
1038
+ throw new IgniterJobsError({
1039
+ code: "JOBS_VALIDATION_FAILED",
1040
+ message: `Stream event "${type}" is not registered for this job definition.`
1041
+ });
1042
+ }
1043
+ return schema;
1044
+ }
922
1045
  /**
923
1046
  * Resolves the effective scope for a job operation.
924
1047
  * @internal