@toa.io/extensions.realtime 1.0.0-alpha.18 → 1.0.0-alpha.182

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 (50) hide show
  1. package/components/streams/manifest.toa.yaml +0 -1
  2. package/components/streams/operations/create.d.ts +4 -2
  3. package/components/streams/operations/create.js +15 -9
  4. package/components/streams/operations/create.js.map +1 -1
  5. package/components/streams/operations/lib/{stream.d.ts → Stream.d.ts} +5 -1
  6. package/components/streams/operations/lib/Stream.js +54 -0
  7. package/components/streams/operations/lib/Stream.js.map +1 -0
  8. package/components/streams/operations/{types.d.ts → lib/types.d.ts} +4 -1
  9. package/components/streams/operations/lib/types.js.map +1 -0
  10. package/components/streams/operations/push.d.ts +1 -1
  11. package/components/streams/operations/tsconfig.tsbuildinfo +1 -1
  12. package/components/streams/source/create.ts +20 -9
  13. package/components/streams/source/lib/Stream.ts +69 -0
  14. package/components/streams/source/{types.ts → lib/types.ts} +4 -1
  15. package/components/streams/source/push.ts +1 -1
  16. package/features/static.feature +34 -0
  17. package/features/steps/Realtime.ts +1 -1
  18. package/features/steps/components/messages/manifest.toa.yaml +2 -0
  19. package/package.json +6 -2
  20. package/readme.md +32 -6
  21. package/source/Composition.ts +1 -7
  22. package/source/Realtime.ts +4 -2
  23. package/source/Receiver.ts +49 -0
  24. package/source/Routes.ts +6 -26
  25. package/source/extension.ts +69 -0
  26. package/source/index.ts +1 -0
  27. package/transpiled/Composition.d.ts +1 -1
  28. package/transpiled/Composition.js +2 -5
  29. package/transpiled/Composition.js.map +1 -1
  30. package/transpiled/Realtime.js +5 -3
  31. package/transpiled/Realtime.js.map +1 -1
  32. package/transpiled/Receiver.d.ts +11 -0
  33. package/transpiled/Receiver.js +41 -0
  34. package/transpiled/Receiver.js.map +1 -0
  35. package/transpiled/Routes.d.ts +0 -1
  36. package/transpiled/Routes.js +5 -17
  37. package/transpiled/Routes.js.map +1 -1
  38. package/transpiled/extension.d.ts +8 -0
  39. package/transpiled/extension.js +46 -0
  40. package/transpiled/extension.js.map +1 -0
  41. package/transpiled/index.d.ts +1 -0
  42. package/transpiled/index.js +15 -0
  43. package/transpiled/index.js.map +1 -1
  44. package/transpiled/tsconfig.tsbuildinfo +1 -1
  45. package/components/streams/operations/lib/stream.js +0 -31
  46. package/components/streams/operations/lib/stream.js.map +0 -1
  47. package/components/streams/operations/types.js.map +0 -1
  48. package/components/streams/source/lib/stream.ts +0 -37
  49. package/stage/streams.test.ts +0 -128
  50. /package/components/streams/operations/{types.js → lib/types.js} +0 -0
@@ -1,4 +1,3 @@
1
- prototype: null
2
1
  namespace: realtime
3
2
  name: streams
4
3
 
@@ -1,11 +1,13 @@
1
1
  /// <reference types="node" />
2
2
  import { type Readable } from 'node:stream';
3
3
  import { type Operation } from '@toa.io/types';
4
- import { type Context } from './types';
4
+ import { type Context } from './lib/types';
5
5
  export declare class Effect implements Operation {
6
6
  private readonly streams;
7
+ private logs;
7
8
  mount(context: Context): void;
8
- execute(input: Input, context: Context): Promise<Readable>;
9
+ unmount(): void;
10
+ execute(input: Input): Promise<Readable>;
9
11
  private createStream;
10
12
  }
11
13
  interface Input {
@@ -1,28 +1,34 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.Effect = void 0;
7
- const node_assert_1 = __importDefault(require("node:assert"));
8
- const stream_1 = require("./lib/stream");
4
+ const Stream_1 = require("./lib/Stream");
9
5
  class Effect {
10
6
  streams = new Map();
7
+ logs;
11
8
  mount(context) {
12
9
  context.state.streams = this.streams;
10
+ this.logs = context.logs;
13
11
  }
14
- async execute(input, context) {
12
+ unmount() {
13
+ this.logs.info('Destroying streams', { count: this.streams.size });
14
+ for (const stream of this.streams.values())
15
+ stream.destroy();
16
+ }
17
+ async execute(input) {
15
18
  const key = input.key;
16
19
  if (!this.streams.has(key))
17
20
  this.createStream(key);
18
21
  const stream = this.streams.get(key);
19
- node_assert_1.default.ok(stream !== undefined);
20
22
  return stream.fork();
21
23
  }
22
24
  createStream(key) {
23
- const stream = new stream_1.Stream();
25
+ const stream = new Stream_1.Stream(this.logs.fork({ key }));
24
26
  this.streams.set(key, stream);
25
- stream.once('close', () => this.streams.delete(key));
27
+ stream.once('close', () => {
28
+ this.logs.debug('Stream closed', { key });
29
+ this.streams.delete(key);
30
+ });
31
+ this.logs.debug('Stream created', { key });
26
32
  }
27
33
  }
28
34
  exports.Effect = Effect;
@@ -1 +1 @@
1
- {"version":3,"file":"create.js","sourceRoot":"","sources":["../source/create.ts"],"names":[],"mappings":";;;;;;AACA,8DAAgC;AAGhC,yCAAqC;AAErC,MAAa,MAAM;IACA,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAA;IAE7C,KAAK,CAAE,OAAgB;QAC5B,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;IACtC,CAAC;IAEM,KAAK,CAAC,OAAO,CAAE,KAAY,EAAE,OAAgB;QAClD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAA;QAErB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YACxB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;QAExB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAEpC,qBAAM,CAAC,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAA;QAE/B,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;IACtB,CAAC;IAEO,YAAY,CAAE,GAAW;QAC/B,MAAM,MAAM,GAAG,IAAI,eAAM,EAAE,CAAA;QAE3B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QAE7B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;IACtD,CAAC;CACF;AA3BD,wBA2BC"}
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../source/create.ts"],"names":[],"mappings":";;;AAGA,yCAAqC;AAErC,MAAa,MAAM;IACA,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAA;IAC5C,IAAI,CAAK;IAEV,KAAK,CAAE,OAAgB;QAC5B,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;QACpC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IAC1B,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;QAElE,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;YACxC,MAAM,CAAC,OAAO,EAAE,CAAA;IACpB,CAAC;IAEM,KAAK,CAAC,OAAO,CAAE,KAAY;QAChC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAA;QAErB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YACxB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;QAExB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAE,CAAA;QAErC,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;IACtB,CAAC;IAEO,YAAY,CAAE,GAAW;QAC/B,MAAM,MAAM,GAAG,IAAI,eAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;QAElD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QAE7B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YACxB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;YACzC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC1B,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;IAC5C,CAAC;CACF;AAvCD,wBAuCC"}
@@ -2,9 +2,13 @@
2
2
  import { PassThrough, Readable } from 'node:stream';
3
3
  export declare class Stream extends Readable {
4
4
  private forks;
5
- constructor();
5
+ private interval;
6
+ private readonly logs;
7
+ constructor(logs: any);
6
8
  fork(): PassThrough;
7
9
  _read(): void;
10
+ _destroy(error: Error | null, callback: (error?: (Error | null)) => void): void;
11
+ private heartbeat;
8
12
  private increment;
9
13
  private decrement;
10
14
  }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Stream = void 0;
4
+ const node_stream_1 = require("node:stream");
5
+ class Stream extends node_stream_1.Readable {
6
+ forks = 0;
7
+ interval = null;
8
+ logs;
9
+ constructor(logs) {
10
+ super(objectMode);
11
+ this.logs = logs;
12
+ }
13
+ fork() {
14
+ const through = new node_stream_1.PassThrough(objectMode);
15
+ through.once('close', this.decrement.bind(this));
16
+ this.increment();
17
+ this.heartbeat(through);
18
+ this.pipe(through);
19
+ return through;
20
+ }
21
+ // has to be here
22
+ _read() {
23
+ if (this.interval === null)
24
+ this.interval = setInterval(() => this.heartbeat(), HEARTBEAT_INTERVAL);
25
+ }
26
+ _destroy(error, callback) {
27
+ if (this.interval !== null)
28
+ clearInterval(this.interval);
29
+ this.logs.debug('Stream destroyed', { forks: this.forks });
30
+ super._destroy(error, callback);
31
+ }
32
+ heartbeat(stream = this) {
33
+ const resume = stream.push('heartbeat ' + Date.now());
34
+ if (!resume && this.interval !== null) {
35
+ clearInterval(this.interval);
36
+ this.interval = null;
37
+ }
38
+ return resume;
39
+ }
40
+ increment() {
41
+ this.forks++;
42
+ this.logs.debug('Stream forked', { forks: this.forks });
43
+ }
44
+ decrement() {
45
+ this.forks--;
46
+ this.logs.debug('Stream fork closed', { forks: this.forks });
47
+ if (this.forks === 0)
48
+ this.destroy();
49
+ }
50
+ }
51
+ exports.Stream = Stream;
52
+ const HEARTBEAT_INTERVAL = 16_000; // why?
53
+ const objectMode = { objectMode: true };
54
+ //# sourceMappingURL=Stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stream.js","sourceRoot":"","sources":["../../source/lib/Stream.ts"],"names":[],"mappings":";;;AAAA,6CAAmD;AAEnD,MAAa,MAAO,SAAQ,sBAAQ;IAC1B,KAAK,GAAW,CAAC,CAAA;IACjB,QAAQ,GAA0B,IAAI,CAAA;IAC7B,IAAI,CAAK;IAE1B,YAAoB,IAAS;QAC3B,KAAK,CAAC,UAAU,CAAC,CAAA;QAEjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAEM,IAAI;QACT,MAAM,OAAO,GAAG,IAAI,yBAAW,CAAC,UAAU,CAAC,CAAA;QAE3C,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAEhD,IAAI,CAAC,SAAS,EAAE,CAAA;QAChB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;QACvB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAElB,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,iBAAiB;IACD,KAAK;QACnB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI;YACxB,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,kBAAkB,CAAC,CAAA;IAC3E,CAAC;IAEe,QAAQ,CAAE,KAAmB,EAAE,QAA0C;QACvF,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI;YACxB,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAE9B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;QAE1D,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IACjC,CAAC;IAEO,SAAS,CAAE,SAAmB,IAAI;QACxC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAErD,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAC5B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;QACtB,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAEO,SAAS;QACf,IAAI,CAAC,KAAK,EAAE,CAAA;QAEZ,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;IACzD,CAAC;IAEO,SAAS;QACf,IAAI,CAAC,KAAK,EAAE,CAAA;QAEZ,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,oBAAoB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;QAE5D,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC;YAClB,IAAI,CAAC,OAAO,EAAE,CAAA;IAClB,CAAC;CACF;AA/DD,wBA+DC;AAED,MAAM,kBAAkB,GAAG,MAAM,CAAA,CAAC,OAAO;AACzC,MAAM,UAAU,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,CAAA"}
@@ -1,8 +1,11 @@
1
- import { type Stream } from './lib/stream';
1
+ import { type Stream } from './Stream';
2
2
  export interface Context {
3
3
  state: {
4
4
  streams: Map<string, Stream>;
5
5
  };
6
+ logs: {
7
+ info: (m: string, att?: object) => void;
8
+ };
6
9
  }
7
10
  export interface PushInput {
8
11
  key: string;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../source/lib/types.ts"],"names":[],"mappings":""}
@@ -1,2 +1,2 @@
1
- import { type Context, type PushInput } from './types';
1
+ import { type Context, type PushInput } from './lib/types';
2
2
  export declare function effect({ key, event, data }: PushInput, context: Context): Promise<void>;