@typed/fx 0.0.32 → 0.0.34

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 (55) hide show
  1. package/.eslintcache +1 -1
  2. package/cjs/Subject.js +2 -2
  3. package/cjs/Subject.js.map +1 -1
  4. package/cjs/_internal.d.ts +1 -1
  5. package/cjs/_internal.d.ts.map +1 -1
  6. package/esm/Subject.js +2 -2
  7. package/esm/Subject.js.map +1 -1
  8. package/esm/_internal.d.ts +1 -1
  9. package/esm/_internal.d.ts.map +1 -1
  10. package/package.json +27 -31
  11. package/perf/cases/filter-map-reduce.ts +30 -38
  12. package/perf/helpers.ts +54 -0
  13. package/src/Subject.test.ts +1 -1
  14. package/src/Subject.ts +2 -2
  15. package/src/combine.test.ts +1 -1
  16. package/src/continueWith.test.ts +1 -1
  17. package/src/debounce.test.ts +1 -1
  18. package/src/delay.test.ts +1 -1
  19. package/src/during.test.ts +1 -1
  20. package/src/exhaustMap.test.ts +1 -1
  21. package/src/exhaustMapLatest.test.ts +1 -1
  22. package/src/exhaustMapList.test.ts +1 -1
  23. package/src/filterLoop.test.ts +1 -1
  24. package/src/filterMap.test.ts +1 -1
  25. package/src/flatMap.test.ts +1 -1
  26. package/src/flatMapConcurrently.test.ts +1 -1
  27. package/src/hold.test.ts +1 -1
  28. package/src/mapCause.test.ts +1 -1
  29. package/src/mapEffect.test.ts +1 -1
  30. package/src/merge.test.ts +1 -1
  31. package/src/multicast.test.ts +1 -1
  32. package/src/orElse.test.ts +1 -1
  33. package/src/periodic.test.ts +1 -1
  34. package/src/provide.test.ts +1 -1
  35. package/src/since.test.ts +1 -1
  36. package/src/skipRepeats.test.ts +1 -1
  37. package/src/skipWhile.test.ts +1 -1
  38. package/src/slice.test.ts +1 -1
  39. package/src/snapshot.test.ts +1 -1
  40. package/src/switchMap.test.ts +1 -1
  41. package/src/takeWhile.test.ts +1 -1
  42. package/src/throttle.test.ts +1 -1
  43. package/src/until.test.ts +1 -1
  44. package/src/withEmitter.test.ts +1 -1
  45. package/src/zip.test.ts +1 -1
  46. package/src/zipIterable.test.ts +1 -1
  47. package/tools/benchmark.ts +179 -0
  48. package/perf/_internal.ts +0 -153
  49. package/perf/cases/flatMap.ts +0 -49
  50. package/perf/cases/switchMap.ts +0 -36
  51. package/perf/readme-base.md +0 -14
  52. package/perf/readme.md +0 -40
  53. package/perf/runFullSuite.ts +0 -37
  54. package/perf/runPerfTest.ts +0 -18
  55. package/perf/tsconfig.json +0 -7
package/perf/_internal.ts DELETED
@@ -1,153 +0,0 @@
1
- import process from 'node:process'
2
-
3
- import * as EffectStream from '@effect/core/Stream/Stream'
4
- import * as Effect from '@effect/core/io/Effect'
5
- import * as M from '@most/core'
6
- import * as MS from '@most/scheduler'
7
- import * as MT from '@most/types'
8
- import benchmark, { Suite } from 'benchmark'
9
- import * as RxJS from 'rxjs'
10
-
11
- import * as Fx from '@/index.js'
12
-
13
- export function parseIterations() {
14
- const i = parseInt(process.argv[2], 10)
15
-
16
- return Number.isNaN(i) ? 10000 : i
17
- }
18
-
19
- export const iterations = parseIterations()
20
- export const array = Array.from({ length: iterations }, (_, i) => i)
21
-
22
- export function runSuite(suite: Suite, cb: () => void) {
23
- suite
24
- .on('start', logStart)
25
- .on('cycle', logResults)
26
- .on('complete', () => {
27
- logComplete()
28
- cb()
29
- })
30
- .run({ defer: false })
31
- }
32
-
33
- const longestLibrary = 13
34
- const longestOps = 10
35
-
36
- function logResults(e: any) {
37
- const t = e.target
38
-
39
- if (t.failure) {
40
- console.log(`| ${t.name} | FAILED | ${e.target.failure} |`)
41
-
42
- console.error(padl(10, t.name) + 'FAILED: ' + e.target.failure)
43
- } else {
44
- console.log(
45
- `| ${padl(longestLibrary, t.name)} | ${padl(longestOps, t.hz.toFixed(2))} | ${padl(
46
- 6,
47
- t.stats.rme.toFixed(2) + '%',
48
- )} | ${padl(3, t.stats.sample.length)} |`,
49
- )
50
- }
51
- }
52
-
53
- function logStart(this: any) {
54
- console.log('### ' + this.name)
55
- console.log(`| Library | Ops/sec | ± | Samples |
56
- | --------------|------------|--------|---------|`)
57
- }
58
-
59
- function logComplete() {
60
- console.log('-------------------------------------------------------\n')
61
- }
62
-
63
- function padl(n: number, s: string) {
64
- while (s.length < n) {
65
- s += ' '
66
- }
67
- return s
68
- }
69
-
70
- // function padr(n: number, s: string) {
71
- // while (s.length < n) {
72
- // s = ' ' + s
73
- // }
74
- // return s
75
- // }
76
-
77
- export interface PerformanceTest {
78
- readonly name: string
79
- readonly cases: readonly PerformanceTestCase<any>[]
80
- }
81
-
82
- export interface PerformanceTestCase<A> {
83
- name: string
84
- init: () => A
85
- run: (a: A, deferred: benchmark.Deferred) => void
86
- }
87
-
88
- export function PerformanceTestCase<A>(
89
- name: string,
90
- init: () => A,
91
- run: (a: A, deferred: benchmark.Deferred) => void,
92
- ): PerformanceTestCase<A> {
93
- return { name, init, run }
94
- }
95
-
96
- export function runPerformanceTest(test: PerformanceTest, cb: () => void) {
97
- // eslint-disable-next-line import/no-named-as-default-member
98
- let suite = new benchmark.Suite(test.name)
99
-
100
- for (const testCase of test.cases) {
101
- const constructed = testCase.init()
102
-
103
- suite = suite.add(testCase.name, (deferred: benchmark.Deferred) =>
104
- testCase.run(constructed, deferred),
105
- )
106
- }
107
-
108
- runSuite(suite, cb)
109
- }
110
-
111
- export function fxTest<E, A>(init: () => Fx.Fx<never, E, A>) {
112
- return PerformanceTestCase(
113
- 'Fx',
114
- () => {
115
- const push = init()
116
-
117
- return Fx.runDrain(push)
118
- },
119
- (fx, deferred) => Effect.unsafeRunAsyncWith(fx, () => deferred.resolve()),
120
- )
121
- }
122
-
123
- export function fxEffectTest<E, A>(init: () => Effect.Effect<never, E, A>) {
124
- return PerformanceTestCase('Fx', init, (e, deferred) => {
125
- Effect.unsafeRunPromise(e).then(() => deferred.resolve())
126
- })
127
- }
128
-
129
- export function mostStreamTest<A>(init: () => MT.Stream<A>) {
130
- const mostScheduler = MS.newDefaultScheduler()
131
-
132
- return PerformanceTestCase('@most/core', init, (mostStream, deferred) =>
133
- M.runEffects(mostStream, mostScheduler).then(() => deferred.resolve()),
134
- )
135
- }
136
-
137
- export function rxjsObservableTest<A>(init: () => RxJS.Observable<A>) {
138
- return PerformanceTestCase('RxJS @7', init, (observable, deferred) => {
139
- observable.subscribe({
140
- complete: () => deferred.resolve(),
141
- })
142
- })
143
- }
144
-
145
- export function effectTsStreamTest<E, A>(init: () => EffectStream.Stream<never, E, A>) {
146
- return PerformanceTestCase(
147
- 'Effect/Stream',
148
- () => EffectStream.runDrain(init()),
149
- (e, deferred) => {
150
- Effect.unsafeRunPromise(e).then(() => deferred.resolve())
151
- },
152
- )
153
- }
@@ -1,49 +0,0 @@
1
- import * as EffectStream from '@effect/core/Stream/Stream'
2
- import { pipe } from '@fp-ts/data/Function'
3
- import * as M from '@most/core'
4
- import * as Chunk from '@tsplus/stdlib/collections/Chunk'
5
- import * as rxjs from 'rxjs'
6
-
7
- import {
8
- array,
9
- effectTsStreamTest,
10
- fxTest,
11
- iterations,
12
- mostStreamTest,
13
- rxjsObservableTest,
14
- } from '../_internal.js'
15
-
16
- import * as Stream from '@/index.js'
17
-
18
- const nestedArray = array.map((x) => Array.from({ length: x }, (_, i) => x * 1000 + i))
19
-
20
- const add = (x: number, y: number): number => x + y
21
-
22
- export const name = 'flatMap ' + iterations + ' x ' + iterations + ' integers'
23
- export const cases = [
24
- fxTest(() =>
25
- pipe(
26
- Stream.fromIterable(nestedArray),
27
- Stream.flatMap(Stream.fromIterable),
28
- Stream.scan(0, add),
29
- ),
30
- ),
31
- mostStreamTest(() =>
32
- pipe(
33
- M.periodic(0),
34
- M.withItems(nestedArray),
35
- M.chain((ns) => pipe(M.periodic(0), M.withItems(ns))),
36
- M.scan(add, 0),
37
- ),
38
- ),
39
- rxjsObservableTest(() =>
40
- pipe(rxjs.from(nestedArray), rxjs.flatMap(rxjs.from), rxjs.scan(add, 0)),
41
- ),
42
- effectTsStreamTest(() =>
43
- pipe(
44
- EffectStream.fromChunk(Chunk.from(nestedArray)),
45
- EffectStream.flatMap((ns) => EffectStream.fromChunk(Chunk.from(ns))),
46
- EffectStream.scan(0, add),
47
- ),
48
- ),
49
- ]
@@ -1,36 +0,0 @@
1
- import { pipe } from '@fp-ts/data/Function'
2
- import * as M from '@most/core'
3
- import * as rxjs from 'rxjs'
4
-
5
- import { array, fxTest, iterations, mostStreamTest, rxjsObservableTest } from '../_internal.js'
6
-
7
- import * as Stream from '@/index.js'
8
-
9
- const nestedArray = array.map((x) => Array.from({ length: x }, (_, i) => x * 1000 + i))
10
-
11
- const add = (x: number, y: number): number => x + y
12
-
13
- export const name = 'switchMap ' + iterations + ' x ' + iterations + ' integers'
14
-
15
- export const cases = [
16
- fxTest(() =>
17
- pipe(
18
- Stream.fromIterable(nestedArray),
19
- Stream.switchMap(Stream.fromIterable),
20
- Stream.scan(0, add),
21
- ),
22
- ),
23
- mostStreamTest(() =>
24
- pipe(
25
- M.periodic(0),
26
- M.withItems(nestedArray),
27
- M.map((ns) => pipe(M.periodic(0), M.withItems(ns))),
28
- M.switchLatest,
29
- M.scan(add, 0),
30
- ),
31
- ),
32
- rxjsObservableTest(() =>
33
- pipe(rxjs.from(nestedArray), rxjs.switchMap(rxjs.from), rxjs.scan(add, 0)),
34
- ),
35
- // Effect Stream is pull-based and does not offer switchMap
36
- ]
@@ -1,14 +0,0 @@
1
- # Performance Tests
2
-
3
- Here is the latest output of the perf test suite run on a 2020 13" macbook pro.
4
- It is worth noting that all the tests utilize entirely synchronous workflows, and thus
5
- have a great favoring towards Most.js/RxJS in terms of raw performance overhead.
6
-
7
- If you need strict performance over push-based streams, definitely use Most.js, but if you are
8
- interested in the superpowers of `Effect`, and are interested in using push-based streams as a means
9
- of orchestration `Fx` is still a great bet as it won't often be your bottleneck.
10
-
11
- If you need strict performance no matter what, none of these abstractions should be utilized at all.
12
-
13
- ## Test Results
14
-
package/perf/readme.md DELETED
@@ -1,40 +0,0 @@
1
- # Performance Tests
2
-
3
- Here is the latest output of the perf test suite run on a 2020 13" macbook pro.
4
- It is worth noting that all the tests utilize entirely synchronous workflows, and thus
5
- have a great favoring towards Most.js/RxJS in terms of raw performance overhead.
6
-
7
- If you need strict performance over push-based streams, definitely use Most.js, but if you are
8
- interested in the superpowers of `Effect`, and are interested in using push-based streams as a means
9
- of orchestration `Fx` is still a great bet as it won't often be your bottleneck.
10
-
11
- If you need strict performance no matter what, none of these abstractions should be utilized at all.
12
-
13
- ## Test Results
14
-
15
- ### filter -> map -> scan 10000 integers
16
- | Library | Ops/sec | ± | Samples |
17
- | --------------|------------|--------|---------|
18
- | Fx | 3801.43 | 5.81% | 82 |
19
- | @most/core | 384094.58 | 12.96% | 64 |
20
- | RxJS @7 | 2255.04 | 12.60% | 87 |
21
- | Effect/Stream | 91.50 | 29.12% | 41 |
22
- -------------------------------------------------------
23
-
24
- ### flatMap 10000 x 10000 integers
25
- | Library | Ops/sec | ± | Samples |
26
- | --------------|------------|--------|---------|
27
- | Fx | 6474.91 | 11.85% | 76 |
28
- | @most/core | 276654.02 | 19.33% | 46 |
29
- | RxJS @7 | 10322.11 | 52.99% | 77 |
30
- | Effect/Stream | 2.29 | 124.34% | 9 |
31
- -------------------------------------------------------
32
-
33
- ### switchMap 10000 x 10000 integers
34
- | Library | Ops/sec | ± | Samples |
35
- | --------------|------------|--------|---------|
36
- | Fx | 4759.84 | 13.52% | 63 |
37
- | @most/core | 300663.64 | 14.57% | 55 |
38
- | RxJS @7 | 16469.83 | 2.63% | 75 |
39
- -------------------------------------------------------
40
-
@@ -1,37 +0,0 @@
1
- import { spawnSync } from 'node:child_process'
2
- import * as fs from 'node:fs'
3
- import { basename, dirname, join } from 'node:path'
4
- import { fileURLToPath } from 'node:url'
5
-
6
- const currentDir = dirname(fileURLToPath(import.meta.url))
7
- const casesDir = join(currentDir, '/cases')
8
-
9
- export const runPerfTestPath = join(currentDir, 'runPerfTest.ts')
10
- export const readmeBasePath = join(currentDir, 'readme-base.md')
11
- export const readmePath = join(currentDir, 'readme.md')
12
- export const fileNames = fs.readdirSync(casesDir).map((x) => basename(x))
13
-
14
- let readmeContent = fs.readFileSync(readmeBasePath, 'utf-8').toString()
15
-
16
- for (const fileName of fileNames) {
17
- console.log('Running', 'cases/' + basename(fileName), '\n')
18
-
19
- const { stdout } = spawnSync(`node`, [
20
- `--loader`,
21
- `@esbuild-kit/esm-loader`,
22
- `${runPerfTestPath}`,
23
- `${fileName}`,
24
- ])
25
-
26
- const output = stdout.toString()
27
-
28
- console.log(output)
29
-
30
- readmeContent += output
31
- }
32
-
33
- if (fs.existsSync(readmePath)) {
34
- fs.unlinkSync(readmePath)
35
- }
36
-
37
- fs.writeFileSync(readmePath, readmeContent)
@@ -1,18 +0,0 @@
1
- import process from 'node:process'
2
-
3
- import { runPerformanceTest } from './_internal.js'
4
-
5
- const fileName = process.argv.slice(2).filter((x) => x.trim() !== '--')[0]
6
-
7
- async function main() {
8
- const { name, cases } = await import(
9
- `./cases/${fileName}${fileName.endsWith('.ts') ? '' : '.ts'}`
10
- )
11
-
12
- runPerformanceTest({ name, cases }, () => process.exit(0))
13
- }
14
-
15
- main().catch((error) => {
16
- console.error(error)
17
- process.exit(1)
18
- })
@@ -1,7 +0,0 @@
1
- {
2
- "$schema": "https://json.schemastore.org/tsconfig",
3
- "extends": "../tsconfig.base.json",
4
- "include": [
5
- "."
6
- ]
7
- }