@t4h.framework/dev 0.0.0-experimental-20260911032608 → 0.0.0-experimental-20260911032651

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/CHANGELOG.md CHANGED
@@ -1,22 +1,19 @@
1
1
  # @t4h.framework/dev
2
2
 
3
- ## 0.0.0-experimental-20260911032608
3
+ ## 0.0.0-experimental-20260911032651
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - [#172](https://github.com/tech4humans-brasil/framework/pull/172) [`103c1a8`](https://github.com/tech4humans-brasil/framework/commit/103c1a8a3b7ba177c68a0e4e683aead1e4ba1b3f) Thanks [@gusteycamargo](https://github.com/gusteycamargo)! - Rejects a `Binary` the dev server cannot address instead of trying to serialize
8
- it.
7
+ - [#173](https://github.com/tech4humans-brasil/framework/pull/173) [`fb800a8`](https://github.com/tech4humans-brasil/framework/commit/fb800a85e7e1c094cf2944644f79d44117038435) Thanks [@gusteycamargo](https://github.com/gusteycamargo)! - Caps how many workflow runs the dev server advances at the same time.
9
8
 
10
- A `Binary` implemented in the App matched no codec kind and fell through to the
11
- generic object branch, which walks a `Buffer` one property per byte — around
12
- 100 MB of heap and 8 MB of JSON for a 760 KB file, on every serialization. It
13
- surfaced as an out-of-memory crash with nothing pointing at the cause, and only
14
- in development: a published project fails on the same value with a clear error.
9
+ Every child run was scheduled on its own, so a `split` over thousands of blocks
10
+ started every child at once and exhausted the heap before any of them finished
11
+ — a workflow that fans out over a large file could not be tried locally at all.
15
12
 
16
- It now fails the same way, with `Unsupported binary instance`, so the mistake
17
- shows up while you are writing the workflow. Always take a `Binary` from the
18
- framework — a response body, `sftp.get`, `read`, `write`, `join`, `asset` — and
19
- never implement the class yourself.
13
+ Runs now go through a FIFO queue bounded by
14
+ `WORKFLOW_RUN_NEXT_TICK_CONCURRENCY`. Children still run in parallel, just not
15
+ all at once, which also makes local behaviour closer to what a bounded worker
16
+ pool does when the project is published.
20
17
 
21
18
  ## 0.20.1
22
19
 
@@ -9,3 +9,4 @@ export declare const PROJECTS_ROUTES_PREFIX = "/projects";
9
9
  export declare const DEV_ROUTES_PREFIX = "/_dev";
10
10
  export declare const SERVER_URL_ARG = "--server-url=";
11
11
  export declare const WORKFLOW_RUN_EVENTS: readonly ["run:created", "run:updated"];
12
+ export declare const WORKFLOW_RUN_NEXT_TICK_CONCURRENCY = 10;
@@ -9,4 +9,5 @@ export const PROJECTS_ROUTES_PREFIX = '/projects';
9
9
  export const DEV_ROUTES_PREFIX = '/_dev';
10
10
  export const SERVER_URL_ARG = '--server-url=';
11
11
  export const WORKFLOW_RUN_EVENTS = ['run:created', 'run:updated'];
12
+ export const WORKFLOW_RUN_NEXT_TICK_CONCURRENCY = 10;
12
13
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/constants/server.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAA;AAEhC,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAA;AAEvC,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,GAAG,IAAI,CAAA;AAElD,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,GAAG,IAAI,CAAA;AAEvD,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAA;AAE7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAA;AAE3C,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAA;AAElD,MAAM,CAAC,MAAM,sBAAsB,GAAG,WAAW,CAAA;AAEjD,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAA;AAExC,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAA;AAE7C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,aAAa,EAAE,aAAa,CAAU,CAAA"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/constants/server.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAA;AAEhC,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAA;AAEvC,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,GAAG,IAAI,CAAA;AAElD,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,GAAG,IAAI,CAAA;AAEvD,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAA;AAE7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAA;AAE3C,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAA;AAElD,MAAM,CAAC,MAAM,sBAAsB,GAAG,WAAW,CAAA;AAEjD,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAA;AAExC,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAA;AAE7C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,aAAa,EAAE,aAAa,CAAU,CAAA;AAE1E,MAAM,CAAC,MAAM,kCAAkC,GAAG,EAAE,CAAA"}
@@ -3,14 +3,14 @@ import { getIntegrations } from '../integrations/index.js';
3
3
  import { DevFileBinary } from '../models/DevFileBinary.js';
4
4
  import { JSONCodec, JSONCodecKind } from '../models/JSONCodec.js';
5
5
  const jsonDateKind = new JSONCodecKind('date', value => value instanceof Date, (date) => date.toISOString(), (date) => new Date(date));
6
- const jsonBinaryKind = new JSONCodecKind('binary', value => value instanceof Binary, (binary) => {
6
+ const jsonFileBinaryKind = new JSONCodecKind('binary', value => value instanceof DevFileBinary, (binary) => {
7
7
  if (!(binary instanceof DevFileBinary))
8
8
  throw new TypeError('Unsupported binary instance');
9
9
  return binary.toJSON();
10
10
  }, json => DevFileBinary.from(json));
11
11
  const load = async () => {
12
12
  const integrations = await getIntegrations();
13
- return new JSONCodec(jsonDateKind, ...integrations.flatMap(({ kinds }) => kinds ?? []), jsonBinaryKind);
13
+ return new JSONCodec(jsonDateKind, jsonFileBinaryKind, ...integrations.flatMap(({ kinds }) => kinds ?? []));
14
14
  };
15
15
  let codec;
16
16
  export const getJsonCodec = () => (codec ??= load());
@@ -1 +1 @@
1
- {"version":3,"file":"json-codec.js","sourceRoot":"","sources":["../../src/tools/json-codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAIjE,MAAM,YAAY,GAAG,IAAI,aAAa,CACpC,MAAM,EACN,KAAK,CAAC,EAAE,CAAC,KAAK,YAAY,IAAI,EAC9B,CAAC,IAAU,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,EAClC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CACjC,CAAA;AAED,MAAM,cAAc,GAAG,IAAI,aAAa,CACtC,QAAQ,EACR,KAAK,CAAC,EAAE,CAAC,KAAK,YAAY,MAAM,EAChC,CAAC,MAAc,EAAE,EAAE;IACjB,IAAI,CAAC,CAAC,MAAM,YAAY,aAAa,CAAC;QACpC,MAAM,IAAI,SAAS,CAAC,6BAA6B,CAAC,CAAA;IAEpD,OAAO,MAAM,CAAC,MAAM,EAAE,CAAA;AACxB,CAAC,EACD,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CACjC,CAAA;AAED,MAAM,IAAI,GAAG,KAAK,IAA+B,EAAE;IACjD,MAAM,YAAY,GAAG,MAAM,eAAe,EAAE,CAAA;IAE5C,OAAO,IAAI,SAAS,CAClB,YAAY,EACZ,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,EACnD,cAAc,CACf,CAAA;AACH,CAAC,CAAA;AAED,IAAI,KAA4C,CAAA;AAEhD,MAAM,CAAC,MAAM,YAAY,GAAG,GAA8B,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,CAAA"}
1
+ {"version":3,"file":"json-codec.js","sourceRoot":"","sources":["../../src/tools/json-codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAIjE,MAAM,YAAY,GAAG,IAAI,aAAa,CACpC,MAAM,EACN,KAAK,CAAC,EAAE,CAAC,KAAK,YAAY,IAAI,EAC9B,CAAC,IAAU,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,EAClC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CACjC,CAAA;AAED,MAAM,kBAAkB,GAAG,IAAI,aAAa,CAC1C,QAAQ,EACR,KAAK,CAAC,EAAE,CAAC,KAAK,YAAY,aAAa,EACvC,CAAC,MAAc,EAAE,EAAE;IACjB,IAAI,CAAC,CAAC,MAAM,YAAY,aAAa,CAAC;QACpC,MAAM,IAAI,SAAS,CAAC,6BAA6B,CAAC,CAAA;IAEpD,OAAO,MAAM,CAAC,MAAM,EAAE,CAAA;AACxB,CAAC,EACD,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CACjC,CAAA;AAED,MAAM,IAAI,GAAG,KAAK,IAA+B,EAAE;IACjD,MAAM,YAAY,GAAG,MAAM,eAAe,EAAE,CAAA;IAE5C,OAAO,IAAI,SAAS,CAClB,YAAY,EACZ,kBAAkB,EAClB,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CACpD,CAAA;AACH,CAAC,CAAA;AAED,IAAI,KAA4C,CAAA;AAEhD,MAAM,CAAC,MAAM,YAAY,GAAG,GAA8B,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,CAAA"}
@@ -3,7 +3,11 @@ import { WorkflowRunLockService } from '../services/WorkflowRunLock.service.js';
3
3
  export declare class EnqueueWorkflowRunNextTick {
4
4
  private readonly workflowRun;
5
5
  private readonly lock;
6
+ private readonly pending;
7
+ private running;
6
8
  constructor(workflowRun: WorkflowRunFacade, lock: WorkflowRunLockService);
7
9
  enqueue(runId: string): void;
8
10
  enqueueMany(runIds: readonly string[]): void;
11
+ private drain;
12
+ private run;
9
13
  }
@@ -9,29 +9,48 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
9
9
  };
10
10
  import { styleText } from 'node:util';
11
11
  import { Inject, Injectable } from 'pleroma';
12
+ import { WORKFLOW_RUN_NEXT_TICK_CONCURRENCY } from '../constants/server.js';
12
13
  import { WorkflowRunFacade } from '../services/WorkflowRunFacade.service.js';
13
14
  import { WorkflowRunLockService } from '../services/WorkflowRunLock.service.js';
14
15
  let EnqueueWorkflowRunNextTick = class EnqueueWorkflowRunNextTick {
15
16
  workflowRun;
16
17
  lock;
18
+ pending = [];
19
+ running = 0;
17
20
  constructor(workflowRun, lock) {
18
21
  this.workflowRun = workflowRun;
19
22
  this.lock = lock;
20
23
  }
21
24
  enqueue(runId) {
22
- setImmediate(() => {
23
- this.lock
24
- .detach(() => this.workflowRun.nextTick(runId))
25
- .catch(error => {
26
- console.error(styleText('red', `[Runtime] next tick failed for run ${runId}:`, {
27
- stream: process.stderr,
28
- }), error);
29
- });
30
- });
25
+ this.pending.push(runId);
26
+ this.drain();
31
27
  }
32
28
  enqueueMany(runIds) {
33
29
  for (const runId of runIds)
34
- this.enqueue(runId);
30
+ this.pending.push(runId);
31
+ this.drain();
32
+ }
33
+ drain() {
34
+ while (this.running < WORKFLOW_RUN_NEXT_TICK_CONCURRENCY &&
35
+ this.pending.length > 0) {
36
+ const runId = this.pending.shift();
37
+ this.running += 1;
38
+ setImmediate(() => void this.run(runId));
39
+ }
40
+ }
41
+ async run(runId) {
42
+ try {
43
+ await this.lock.detach(() => this.workflowRun.nextTick(runId));
44
+ }
45
+ catch (error) {
46
+ console.error(styleText('red', `[Runtime] next tick failed for run ${runId}:`, {
47
+ stream: process.stderr,
48
+ }), error);
49
+ }
50
+ finally {
51
+ this.running -= 1;
52
+ this.drain();
53
+ }
35
54
  }
36
55
  };
37
56
  EnqueueWorkflowRunNextTick = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"EnqueueWorkflowRunNextTick.usecase.js","sourceRoot":"","sources":["../../src/use-cases/EnqueueWorkflowRunNextTick.usecase.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAErC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAE5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAA;AAGxE,IAAM,0BAA0B,GAAhC,MAAM,0BAA0B;IAGlB;IAGA;IALnB,YAEmB,WAA8B,EAG9B,IAA4B;QAH5B,gBAAW,GAAX,WAAW,CAAmB;QAG9B,SAAI,GAAJ,IAAI,CAAwB;IAC5C,CAAC;IAEG,OAAO,CAAC,KAAa;QAC1B,YAAY,CAAC,GAAG,EAAE;YAChB,IAAI,CAAC,IAAI;iBACN,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;iBAC9C,KAAK,CAAC,KAAK,CAAC,EAAE;gBACb,OAAO,CAAC,KAAK,CACX,SAAS,CAAC,KAAK,EAAE,sCAAsC,KAAK,GAAG,EAAE;oBAC/D,MAAM,EAAE,OAAO,CAAC,MAAM;iBACvB,CAAC,EACF,KAAK,CACN,CAAA;YACH,CAAC,CAAC,CAAA;QACN,CAAC,CAAC,CAAA;IACJ,CAAC;IAEM,WAAW,CAAC,MAAyB;QAC1C,KAAK,MAAM,KAAK,IAAI,MAAM;YAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IACjD,CAAC;CACF,CAAA;AA3BY,0BAA0B;IADtC,UAAU,EAAE;IAGR,WAAA,MAAM,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,CAAA;IAG/B,WAAA,MAAM,CAAC,GAAG,EAAE,CAAC,sBAAsB,CAAC,CAAA;GAL5B,0BAA0B,CA2BtC"}
1
+ {"version":3,"file":"EnqueueWorkflowRunNextTick.usecase.js","sourceRoot":"","sources":["../../src/use-cases/EnqueueWorkflowRunNextTick.usecase.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAErC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAE5C,OAAO,EAAE,kCAAkC,EAAE,MAAM,wBAAwB,CAAA;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAA;AAGxE,IAAM,0BAA0B,GAAhC,MAAM,0BAA0B;IAOlB;IAGA;IATF,OAAO,GAAa,EAAE,CAAA;IAE/B,OAAO,GAAG,CAAC,CAAA;IAEnB,YAEmB,WAA8B,EAG9B,IAA4B;QAH5B,gBAAW,GAAX,WAAW,CAAmB;QAG9B,SAAI,GAAJ,IAAI,CAAwB;IAC5C,CAAC;IAEG,OAAO,CAAC,KAAa;QAC1B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAExB,IAAI,CAAC,KAAK,EAAE,CAAA;IACd,CAAC;IAEM,WAAW,CAAC,MAAyB;QAC1C,KAAK,MAAM,KAAK,IAAI,MAAM;YAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAEpD,IAAI,CAAC,KAAK,EAAE,CAAA;IACd,CAAC;IAEO,KAAK;QACX,OACE,IAAI,CAAC,OAAO,GAAG,kCAAkC;YACjD,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EACvB,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAG,CAAA;YAEnC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;YAEjB,YAAY,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,GAAG,CAAC,KAAa;QAC7B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;QAChE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,SAAS,CAAC,KAAK,EAAE,sCAAsC,KAAK,GAAG,EAAE;gBAC/D,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,CAAC,EACF,KAAK,CACN,CAAA;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,OAAO,IAAI,CAAC,CAAA;YAEjB,IAAI,CAAC,KAAK,EAAE,CAAA;QACd,CAAC;IACH,CAAC;CACF,CAAA;AAtDY,0BAA0B;IADtC,UAAU,EAAE;IAOR,WAAA,MAAM,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,CAAA;IAG/B,WAAA,MAAM,CAAC,GAAG,EAAE,CAAC,sBAAsB,CAAC,CAAA;GAT5B,0BAA0B,CAsDtC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t4h.framework/dev",
3
- "version": "0.0.0-experimental-20260911032608",
3
+ "version": "0.0.0-experimental-20260911032651",
4
4
  "description": "Dev server for the T4H Framework",
5
5
  "homepage": "https://github.com/tech4humans-brasil/framework/tree/main/packages/dev",
6
6
  "bugs": "https://github.com/tech4humans-brasil/framework/issues",